uniapp+vue3开发微信小程序踩坑集

世上本没有路,走的人多了,也便成了路。

本文主要记录使用uniapp+vue3开发微信小程序遇见的各种常见问题及注意点。(持续更新)

问题:

如何解决使用各种dialog组件导致的滚动穿透问题

本质上是禁用touchmove默认的滚动行为,uniapp用.stop修饰符可阻止默认行为

小程序写法

html 复制代码
  <view catchtouchmove="true">
    <dialog .../>
  </view>

uniapp写法

html 复制代码
  <uni-popup @touchmove.stop />

禁用touchmove会同时禁掉dialog组件内部的滚动,所以如果内部也需要滚动,则需要借助 page-meta 标签(page-meta须为根标签)

html 复制代码
<page-meta :page-style="`overflow:${pageScrollFlag?'visible':'hidden'}`">
  ...
</page-meta>

unplugin-vue-components 不生效,仍需手动导入

vite.config.ts文件中

需要把unplugin-vue-components插件提前到uni之前!!!

需要把unplugin-vue-components插件提前到uni之前!!!

需要把unplugin-vue-components插件提前到uni之前!!!

正确写法:

js 复制代码
  Components({
    dirs: ['src/components'],
    dts: 'typings/components.d.ts',
  }),
  uni(),

错误写法:

js 复制代码
  uni(),
  Components({
    dirs: ['src/components'],
    dts: 'typings/components.d.ts',
  }),

官方好大的坑:官方issue

子组件使用onShow、onPullDownRefresh、onReachBottom 导致接口重复触发

在页面子组件中使用onShow等是挺高频的需求,但是在 v-if 的子组件中使用了onShow等,在子组件状态来回切换时,会出现闭包导致子组件的onShow等无法被销毁,从而在onShow时回调函数中的逻辑重复执行,严重时甚至可能会造成内存溢出假死。为了解决这个问题,我封装了几个方法,本质上都是在 onunmounted 中将回调函数要执行的逻辑重置为空函数,这样虽然闭包还在但是不会再重复触发回调的逻辑:

封装 onShow:

js 复制代码
export const initOnshow = async (cb: () => Promise<void>) => {
  let isFirstOnShow = true
  onMounted(() => {
    cb().finally(() => {
      isFirstOnShow = false
    })
  })
  onUnmounted(() => {
    // 卸载闭包,防止内存泄漏
    onShowFn = () => {}
  })
  let onShowFn = () => {
    if (isFirstOnShow) {
      isFirstOnShow = false
      return
    }
    cb()
  }
  onShow(() => onShowFn())
}

封装 onPullDownRefresh:

js 复制代码
export const initRefresh = async (cb: () => Promise<void>) => {
  onUnmounted(() => {
    // 卸载闭包,防止内存泄漏
    pullDownRefresh = async () => {}
  })
  let pullDownRefresh = async () => {
    await cb()
    uni.stopPullDownRefresh()
    uni.showToast({ title: '刷新成功', icon: 'success' }).then()
  }
  onPullDownRefresh(() => pullDownRefresh())
}

封装 onReachBottom

js 复制代码
export const initReachBottom = async (cb: () => Promise<void>) => {
  onUnmounted(() => {
    // 卸载闭包,防止内存泄漏
    onReachFn = () => {}
  })
  let onReachFn = () => {
    cb()
  }
  onReachBottom(() => onReachFn())
}

input数据改变后页面没有实时更新

js 复制代码
const price = ref(0)
const handleInput = () => {
  nextTick(() => {
    if (price.value > 100) {
      price.value = 100
    }
  })
}

showLoadingshowToast 不能同时存在

真机上如果使用 hideLoading 会立马把 toast 取消掉,所以同时出现时使用setTimeout延迟toast的时机。

怎么做状态管理和持久化

vue3 推荐使用 pinia 做全局状态管理,使用体验比 vuex 好不知道多少倍。pinia 本身相当于sessionStorage,如果要做持久化缓存需要使用 uni.setStorageSync()。而如果有大量持久化需求则需要引入另一个插件 pinia-plugin-unistorage

关于使用 unocss

原子化CSS是一种将css用class书写出来的方式,很好的解决了关注点分离带来的痛处。在vue的单文件开发模式中,经常烦恼的一件事就是template和style中切来切去,写起来时有不畅。而原子化css则解决了这个麻烦,可以在开发时少写大量代码,较大程度提升开发体验并节省开发时间。(推荐同时使用vscode插件UnoCSS,可以显示class实际属性)

同为原子化工具,UnoCSS 相较于 Tailwind CSS 较大的优势是class都是按需生成,且规则编写更加灵活(只需要会一点点正则)。最重要的是unocss完全兼容Tailwind CSS。

注意点:

不支持vue的render、inline-template、X-Templates、keep-alive、transition

redirectTo: 关闭当前页面(销毁了当前页面在路由栈中的历史记录),跳转到应用内的某个页面。

reLaunch: 关闭所有页面,打开到应用内的某个页面。(清空了路由栈,此时调用getCurrentPages()得到空数组)

navigateTo 跳转到某个页面,保留当前页面的历史记录,在下个页面可使用navigateBack()返回到当前页面。

  • 建议跳转登录页等使用redirectTo,登录后再使用redirectTo跳回原页面。

  • 建议跳转到首页、我的等等一级页面使用reLaunch,这样可以避免路由栈缓存的页面过多导致栈溢出。(小程序最多打开20个页面)

  • 建议跳转有返回按钮的页面使用navigateTo,保留栈历史。

事件修饰符

以下为uniapp官方文档,小程序只支持.stop .native两个修饰符

  • .stop: 各平台均支持,使用时会阻止事件冒泡,在非 H5 端同时也会阻止事件的默认行为
  • .native: 监听原生事件,各平台均支持
  • .prevent: 仅在 H5 平台支持
  • .capture: 仅在 H5 平台支持
  • .self: 仅在 H5 平台支持
  • .once: 仅在 H5 平台支持
  • .passive: 仅在 H5 平台支持

生命周期

uniapp小程序除了小程序自己的页面生命周期,还有vue的组件生命周期。

  • onLoad 当页面加载时触发,回调接收来自上个页面传递的参数
  • onShow 当 uni-app 启动,或从后台进入前台显示
  • onHide 当 uni-app 从前台进入后台
  • onPullDownRefresh 当下拉刷新时触发
  • onReachBottom 当页面滚动到底部时触发

注意onLoad生命周期只会在页面加载时触发,所以如果用在组件中,当组件v-if重新加载时,不会重新触发。如果要重新触发,需要使用onMounted等vue组件生命周期。

好文推荐

相关推荐
王哈哈^_^1 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie2 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic2 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿3 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具3 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
customer083 小时前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
qq_390161774 小时前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test4 小时前
js下载excel示例demo
前端·javascript·excel
Yaml44 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事4 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro