uni-app 小程序中将 pinia store 通过 props 传入插槽组件,组件内调用 actions 方法抛异常后,微信小程序真机会死循环导致页面卡死
uni-app 小程序中将 pinia store 通过 props 传入插槽组件,组件内调用 actions 方法抛异常后,微信小程序真机会死循环导致页面卡死
示例代码:
报错示例代码见附件
附件项目如何使用:
- 下载zip压缩包,解压
- 在项目目录,使用yarn安装依赖
- 使用yarn dev:mp-weixin命令编译成微信小程序
- 打开微信开发者工具进行调试
- 微信开发者工具生成开发码,手机扫码,即可一键死机
操作步骤:
复现步骤(可参照附件项目,附件里的项目有完整复现方法):
- 创建一个Pinia的Store,里面定义一个Action方法,方法内抛出异常
- 创建父组件,在父组件内useStore,并存入对象,当做props传入子组件
- 创建子组件A,声明一个插槽
- 创建子组件B,子组件某个方法调用(通过props传入的)Store里的异常Action
- 在父组件使用子组件A,将子组件B传入子组件A的插槽内
- 使用真机调试微信小程序,触发报错Action,100%出现死循环卡顿,手机会发烫死机
预期结果:
预期结果:正常报错,但不会造成死循环并死机
实际结果:
触发报错Action,100%出现死循环卡顿,手机会发烫死机
bug描述:
Vue3+ts版复现该BUG
(项目由CLI创建,命令:npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project)
复现步骤(可参照附件项目,附件里的项目有完整复现方法):
- 创建一个Pinia的Store,里面定义一个Action方法,方法内抛出异常
- 创建父组件,在父组件内useStore,并存入对象,当做props传入子组件
- 创建子组件A,声明一个插槽
- 创建子组件B,子组件某个方法调用(通过props传入的)Store里的异常Action
- 在父组件使用子组件A,将子组件B传入子组件A的插槽内
- 使用真机调试微信小程序,触发报错Action,100%出现死循环卡顿,手机会发烫死机
附件项目如何使用:
- 下载zip压缩包,解压
- 在项目目录,使用yarn安装依赖
- 使用yarn dev:mp-weixin命令编译成微信小程序
- 打开微信开发者工具进行调试
- 微信开发者工具生成开发码,手机扫码,即可一键死机
感谢反馈,这边排查下
已复现问题,与pinia无关,后续会修复。你可以先把错误捕获下
好的 谢谢!
您好,有具体修复发版时间吗
回复 f***@163.com: 我之前的回答有误,这个问题是pinia导致的,为什么要传递一个store呢?你直接在子组件引入试试
回复 YUANRJ: 因为业务需要,同样的interface可能传入的实现不同,所以需要传入,不太方便直接use去使用pinia store
回复 YUANRJ: 使用原生Vue没有复现这样的问题,只有uniapp微信的运行时环境上出现了这样的问题。麻烦修复这个死循环问题,支持下这样的用法。谢谢
在 uni-app 小程序中使用 Pinia 时,如果将 Pinia store 通过 props
传入插槽组件,并在组件内调用 store 的 actions
方法时抛出了异常,可能会导致微信小程序真机出现死循环,进而导致页面卡死。这个问题通常与异常处理不当或状态更新触发重新渲染有关。
以下是可能的原因和解决方案:
1. 异常未被捕获
如果 actions
方法抛出异常且未被捕获,可能会导致组件不断尝试重新执行该方法,从而进入死循环。
解决方案:
确保在调用 actions
方法时使用 try-catch
捕获异常,避免异常传播。
try {
await store.someAction();
} catch (error) {
console.error('Action failed:', error);
}
2. 状态更新触发重新渲染
如果 actions
方法中修改了 store 的状态,而状态更新又触发了组件的重新渲染,可能会导致组件不断调用 actions
方法,从而进入死循环。
解决方案:
检查 actions
方法中是否有不必要的状态更新,或者确保状态更新不会触发组件的重新渲染。
3. 插槽组件的重新渲染
如果 Pinia store 通过 props
传入插槽组件,而父组件的状态更新导致插槽组件不断重新渲染,可能会触发 actions
方法的重复调用。
解决方案:
- 避免将 store 直接通过
props
传入插槽组件,而是直接在插槽组件内使用 Pinia 的useStore
获取 store。 - 使用
computed
或watch
控制状态更新,避免不必要的重新渲染。
import { useStore } from '@/store';
export default {
setup() {
const store = useStore();
return { store };
},
};
4. 微信小程序的异常处理机制
微信小程序的异常处理机制可能与 Pinia 的行为不完全兼容,导致异常未被正确处理,从而引发死循环。
解决方案:
- 确保 Pinia 和微信小程序的版本是最新的。
- 在
actions
方法中避免抛出同步异常,改为返回错误信息。
5. 调试与日志
启用详细的日志记录,帮助定位问题的根源。
解决方案:
在 actions
方法和组件生命周期中添加日志,观察调用顺序和状态变化。
actions: {
someAction() {
console.log('Action called');
try {
// 业务逻辑
} catch (error) {
console.error('Action error:', error);
}
},
},