0%

2020-10-16 记一次使用 vue-composition-api 开发网页的经历

2020-10-16 记一次使用 vue-composition-api 开发网页的经历

项目地址:https://github.com/CaoMeiYouRen/shirakami-haruka-button

演示页面:https://haruka.fun

在本次的项目开发中,本人也是尽可能抛弃 Vue2 的配置式写法,全面转向 Vue3 的函数式写法。

两者从功能上来讲是完全一致的,所以改造的过程还是比较顺利的,并没有遇到特别困难的情况。

而我认为真正麻烦的地方在于需要区分响应式对象和普通对象。

这里需要专门提一下 refreactive 的区别。

使用 ref 可以对所有类型的数据返回一个响应式代理,但是需要通过 xxx.value 来访问;而 reactive 只能转换对象,但是可以直接访问值。

由于经过 reactive 转换的值的类型和原来是一致的,所以在这种情况下更难判断当前调用的是响应式对象还是普通对象,因此我建议将响应式对象均使用 ref 来转换,这样能够借助类型系统区分响应式对象和普通对象。虽然在书写上会有点麻烦,但是对于带来的逻辑清晰,这点代价还是值得的。

由于官方也推荐把组合式 api 的命名采用类似 react hook 的风格,所以 vue composition api 写的函数也是使用 useXXX 格式命名的,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**
* 返回 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 组合式函数也要牢记只会执行一次。尤其是要注意计算属性的使用。很多时候会写成给响应式对象赋值,而实际上是想写计算属性。

1
2
3
4
5
6
const arr = ref([])
//错误
const length = ref(arr.value.length)

//正确
const length = computed(() => arr.value.length)

vue 的响应式 api 一定还有着更多有趣的功能等待着大家开发,期待进一步的深入了解

本文作者:草梅友仁
本文地址: https://blog.cmyr.ltd/archives/5164f68c.html
版权声明:转载请注明出处!

坚持原创技术分享,您的支持将鼓励我继续创作!