ttk-cli / uni-vue3-vite-ts-pinia

A template for uniapp with vue3.
MIT License
331 stars 100 forks source link

chore: update useInit hook 管理生命周期最佳实践 #46

Closed Minf97 closed 9 months ago

Minf97 commented 9 months ago

这是我第一次提pr,如果有做的不规范/描述不准确的地方,欢迎指正

解决issue #44

完善 useInit hook

缺陷:

useInit.ts中存在报错,原因是 pageQuery 初始化 {},与其约束的类型不符。

const pageQuery = ref<T | {}>({}); 可解决报错,但外部引用时将丢失 pageQuery 的类型检查,导致语法提示失效!

Allen-1998 commented 9 months ago

通常情况下,pageQuery的作用是用于页面初始化调用接口,如果按照这种写法的话,会不会可能导致部分不了解的人在调用useInit后直接在setup下使用,此时获取到的pageQuery将会都是undefined, 又会带来其他的疑问呢

Minf97 commented 9 months ago

当页面没有接收传参时,pageQuery的确是undefined,但我不认为会带来疑问。

Q1:当我们试图使用一个变量时,大概率是清楚我们拿变量要做什么?这个问题。所以反过来,不了解该变量的含义和用途的人,大概率也不会使用该变量

Q2:我们可以在test页面写注释补充,或直接console.log即可,就像你之前在onLoad中写的一样

Allen-1998 commented 9 months ago

有另外一种思路和你分享一下,如果让 useInit 同步执行,且等待 onLoad 后再返回结果,就可以做到使用时不需要在 onLoad 中调用,且直接就可以正常获取到值了。

一种实现方案大致是 useInit return 一个 promise,这个 promise 在 onLoad 获取到 pageInfo 后 resolve, 但是这样做会有一个问题,是使用时需要 const pageInfo = await useInit() , 而 uniapp 目前是不支持顶层 await 的,这就导致这种方式也无法直接使用。

那么如何解决呢,既然你了解小程序,举个例子,小程序中有 wx.setStorage 和 wx.setStorageSync ,其中 wx.setStorageSync 的效果就是让 wx.setStorage 同步执行了,且不需要添加 await , 它的实现原理应该是基于 yield 的, 我想这里我们也可以用类似的方式来处理。

Allen-1998 commented 9 months ago

具体的实现我这边白天还要工作暂时没有时间,晚一点可能会尝试一下,或者你感兴趣的话也可以了解一下试试看

Minf97 commented 9 months ago

我突然意识到我的理解出现了些偏差,现在我完全明白你的意思了。

就当下而言,我们可以使用watch来监听到pageQuery的变化,并触发依赖更新。

但这仍不是最佳实践。

晚些时间我会继续尝试解决这个问题

Allen-1998 commented 9 months ago

了解了一下,猜测 wx.setStorageSync 可能是类似于 fs.writefilesync, 调用了c++ 底层同步执行的模块,而非 yield 参见。所以想要脱离promise实现同步执行异步函数目前看来还是不太可能的,感觉最好的方式还是等待uniapp支持顶层await,不过相关issue已经一年了看起来还没有进展😇 https://github.com/dcloudio/uni-app/issues/3678

Minf97 commented 9 months ago

感谢您的详细解惑,针对这个问题我去提问了一位大佬,他的回复是:“你都用setup了就别在意生命周期了”

我觉得很有道理,也分享给您[笑哭]

尽管这是一次失败的pr,但我仍学习到很多 感谢!