# 常见问题

# 目录

# 一、如何解决微信小程序关于选择器的警告提示?(谨慎使用)

微信小程序组件警告提示

Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors...

# 解决方案:

暂时无需解决,不影响使用

# 二、文档右侧的演示demo有些功能不能操作?

因为演示demo是iframe嵌入的H5,所以组件中的@touchstart等事件会失效。

# 解决方案:

直接访问https://h5.uvui.cn (opens new window)的手机模式进行体验

# 三、使用的ref与组件名重名,在vue3的setup语法糖中会报错

<!-- 错误示例 -->
<template>
  <view style="padding-top: 100px;">
    <uv-demo ref="uvDemo"></uv-demo>
  </view>
</template>
<script setup>
  import { ref } from 'vue'
  const uvDemo = ref(null);
</script>

报错

上述代码会报错导致不能正常显示
Invalid vnode type when creating vnode: null.
Component is missing template or render function.

# 解决方案:将ref改成其他名字即可,如下:

<template>
  <view style="padding-top: 100px;">
    <uv-demo ref="uvDemo1"></uv-demo>
  </view>
</template>
<script setup>
  import { ref } from 'vue'
  const uvDemo1 = ref(null);
</script>

# 四、qinui-popup等组件怎么禁止滚动穿透?

使用qinui-popup等弹出层组件时,会发现遮罩下方的内容可以滚动,这就是穿透滚动。

由于平台的自身原因,除H5之外,其他平台都不能在组件内禁止滚动穿透,所以在微信小程序、App 平台,页面内需要用户特殊处理一下。

# 解决方案:

# 微信小程序/App

qinui-popup 为例,需要在 data 中定义一个变量,用来表示 qinui-popup 的开启关闭状态,并通过这个变量修改 page-metaoverflow 属性。
qinui-popup 的 打开和关闭 事件中可以接受到 qinui-popup 的开启关闭状态 ,并赋值给上面的变量。

<template>
  <page-meta :page-style="'overflow:'+(show?'hidden':'visible')"></page-meta>
  <view class="container">
    <!-- 普通弹窗 -->
    <qinui-popup ref="popup" @open="change(true)" @close="change(false)">
    <!-- ... -->
    </qinui-popup>
  </view>
</template>
<script>
  export default {
    data() {
      return {
        show:false
      }
    },
    methods: {
      change(show) {
        this.show = show
      }
    }
  }
</script>

# Tips

  • h5 滚动穿透不需要处理,组件内部有处理。或者自己根据状态设置 body 上面的 overflow 属性为 hiddenvisible,也可以达到这种效果。
  • 其他平台无法阻止滚动穿透,建议使用 scroll-view 滚动 ,手动设置 overflow:hidden或设置 scroll-y属性来禁止滚动。

# 五、怎么隐藏组件的滚动条?

组件使用了 scroll-view 标签,在 H5 等平台会出现滚动条,需要全局设置滚动条样式,局部设置不生效。

# 解决方案:

/* APP.vue */
<style lang="scss">
  ::-webkit-scrollbar {
    display: none;  
    width: 0 !important;  
    height: 0 !important;  
    -webkit-appearance: none;  
    background: transparent;  
  }
</style>

# 六、避免部分扩展组件之间套娃,否则会造成错乱

  • 套娃的简单案例:qinui-popup 中嵌套 uv-calendars。造成的后果可以复制下面的代码体验下。
<template>
  <view>
    <qinui-popup ref="popup" mode="top">
      <view>
        <uv-button :text="`选择时间${time}`" @click="openTime"></uv-button>
        <!-- 套在了qinui-popup中...过分...,uv-calendars属于弹窗性质的组件,这样做的后果就是底层组件都不知道自己是啥娃子了 -->
        <uv-calendars ref="calendars" @confirm="confirm" />
      </view>
    </qinui-popup>
    <button @click="open">打开</button>
  </view>
</template>
<script>
  export default {
    data() {
      return {
        time: ''
      }
    },
    methods: {
      open() {
        this.$refs.popup.open('top');
      },
      openTime() {
        this.$refs.calendars.open();
      },
      confirm(e) {
        this.time = e.fulldate;
      }
    }
  }
</script>
  • 正确的做法:弹窗类等组件避免套在其他扩展组件里面,要放在根节点下面使用,且根节点不能设置宽高等属性。
<template>
  <view>
    <qinui-popup ref="popup" mode="top">
      <view>
        <uv-button :text="`选择时间${time}`" @click="openTime"></uv-button>
      </view>
    </qinui-popup>
    <button @click="open">打开</button>
    <uv-calendars ref="calendars" @confirm="confirm" />
  </view>
</template>
<script>
  export default {
    data() {
      return {
        time: ''
      }
    },
    methods: {
      open() {
        this.$refs.popup.open('top');
      },
      openTime() {
        this.$refs.calendars.open();
      },
      confirm(e) {
        this.time = e.fulldate;
      }
    }
  }
</script>
  • 总结:一些套娃的行为是不利于前端开发的!大家要谨记,特别是扩展组件,与原生组件有本质上的区别。为啥不能这样做,比如弹窗组件底层使用了动画组件,动画的开始执行位置是-100%,你把它执行的范围给缩小到你指定的范围,那弹出来的效果肯定是不对的。

# 七、为什么qinui-popup等弹窗组件显示不使用show属性进行控制,而是使用ref控制

  1. 弹窗等组件中都会用到调用 open 方法去执行后续程序,使用监听 show 属性也可以做到,但是实际上使用 watch 监听 show 属性的变化,会比直接调方法执行的慢些,监听到去执行是需要时间的,所以 QinUi 推荐直接调用方法,这可能也是 QinUi 组件使用 ref 的原因,跟着官方对齐没毛病吧。

  2. 在 Vuejs 中, ref 方法和监听 show 变化都可以用来访问和操作 DOM 元素。但是,它们的执行顺序是不确定的,因为它们是由 Vuejs 内部处理的。通常情况下, ref 方法会先于监听 show 变化执行,因为它可以更早地访问和操作 DOM 元素。然而,在某些情况下,监听show 变化可能会先于 ref 方法执行。例如,当 show 属性在组件实例化之前发生变化时,监听 show 变化可能会先执行。

  3. 可以用一个简单示例来解释:可以看出下面的示例 show 的变化在前, open 方法执行在后,但是最后打印的结果是 open 中的程序在前,监听 show 变化程序在后。

  4. 总结:从性能和代码洁癖上来考虑,还是建议使用 ref 进行控制,这也正是 QinUi 深思熟虑的结果。

index.vue

<template>
  <view class="content">
    <demo ref="demoRef" :show="show"></demo>
    <button @click="handle">执行</button>
  </view>
</template>
<script>
  export default {
    data() {
      return {
        show: false
      }
    },
    methods: {
      handle() {
        this.show = true;
        this.$refs.demoRef.open();
      }
    }
  }
</script>

demo组件:

<template></template>
<script>
  export default {
    props: {
      show: {
        type: Boolean,
        default: false
      }
    },
    watch: {
      show(n) {
        console.log('监听show变化', n);
      }
    },
    methods: {
      open() {
        console.log('监听open方法执行');
      }
    }
  }
</script>