项目地址:https://github.com/CaoMeiYouRen/shirakami-haruka-button
演示页面:https://haruka.fun
在本次的项目开发中,本人也是尽可能抛弃 Vue2 的配置式写法,全面转向 Vue3 的函数式写法。
两者从功能上来讲是完全一致的,所以改造的过程还是比较顺利的,并没有遇到特别困难的情况。
而我认为真正麻烦的地方在于需要区分响应式对象和普通对象。
这里需要专门提一下 ref
和 reactive
的区别。
使用 ref
可以对所有类型的数据返回一个响应式代理,但是需要通过 xxx.value
来访问;而 reactive
只能转换对象,但是可以直接访问值。
由于经过 reactive
转换的值的类型和原来是一致的,所以在这种情况下更难判断当前调用的是响应式对象还是普通对象,因此我建议将响应式对象均使用 ref
来转换,这样能够借助类型系统区分响应式对象和普通对象。虽然在书写上会有点麻烦,但是对于带来的逻辑清晰,这点代价还是值得的。
由于官方也推荐把组合式 api 的命名采用类似 react hook 的风格,所以 vue composition api 写的函数也是使用 useXXX 格式命名的,例如
/**
* 返回 window 的大小
*
* @author CaoMeiYouRen
* @date 2020-10-10
* @export
* @returns
*/
export function useOnWindowResize() {
function getSize() {
const height = window.innerHeight || document.documentElement.clientHeight
const width = window.innerWidth || document.documentElement.clientWidth
return {
height,
width,
}
}
const height = ref(0)
const width = ref(0)
function handler() {
const size = getSize()
height.value = size.height
width.value = size.width
}
window.addEventListener('resize', handler)
onMounted(() => {
handler()
})
onUnmounted(() => {
window.removeEventListener('resize', handler)
})
function remove() {
window.removeEventListener('resize', handler)
}
return {
height,
width,
remove,
}
}
//调用时
const { width } = useOnWindowResize()
这样可以有利于区分组合式 api 函数和普通函数。
然后说一个点,没有使用到生命周期钩子的组合式 api ,也可以在全局调用,并不只能在 setup() 函数中执行。
同时,也因为这个原因,生命周期钩子必须同步调用,不能异步调用。这个问题实际上很好理解,如果异步执行的话,在 setup 期间,Vue 就不知道你调用了哪些生命周期钩子。
由于 vue 的组合式 api 可以在条件语句中执行,因此完全可以传入一个参数来标记当前是全局调用还是在 Vue 中调用。
在之后的研究中发现,可以使用
getCurrentInstance()
函数来判断当前是全局调用还是在 Vue 中调用,如果为 Vue 中,则会返回一个 Vue 实例,否则返回 null ,因此可以借此来判断。
基于此,可以开发一个超简单的 vuex ,而 vuex 的 next 版本也是基于此进行了很多优化。如果只是想全局调用少量数据的话,确实可以直接使用响应式对象来完成操作。
最后,就像在 react hook 中需要时刻注意 hook 会多次执行一样, vue 组合式函数也要牢记只会执行一次。尤其是要注意计算属性的使用。很多时候会写成给响应式对象赋值,而实际上是想写计算属性。
const arr = ref([])
//错误
const length = ref(arr.value.length)
//正确
const length = computed(() => arr.value.length)
vue 的响应式 api 一定还有着更多有趣的功能等待着大家开发,期待进一步的深入了解
- 本文链接: https://wp.cmyr.ltd/archives/remembering-an-experience-of-developing-web-pages-using
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
欢迎关注我的其它发布渠道
发表回复
要发表评论,您必须先登录。