最近因为跳槽换了公司,公司项目是v3.4的,发现hooks封装极其重,让我脑海中仅存的v2的语法感觉很别扭,即便是从react转过来的,但是还是有很多地方第一眼没明白,主要是钩子和宏太多了,当初只是大概过了一下v3最初版本的语法,没去延申扩展性。以下是实操v3几天的笔记,生命周期钩子我就不提了。主要是记录自己的一些觉得有趣的地方。
1. 和 和 和$宏的区别
const data = $computed(() => data?.data);
return {
status: $$(data?.status),
data: $$(data),
refetch,
};
第一眼看到这
c
o
m
p
u
t
e
d
是啥啊,
computed是啥啊,
computed是啥啊,$(data)又是啥啊,啥玩意这是。导致我一脸懵逼,于是查阅了vue3官方文档,再这儿有明确的解释,我是看了2遍才彻底理解:
在vue中传参默认情况如下:
function trackChange(x: Ref<number>) {
watch(x, (x) => {
console.log('x 改变了!')
})
}
let count = $ref(0)
trackChange(count) // 无效!
调用函数的时候 使用 func(a)是能保证响应式的,a传过去是一个ref对象的响应式对象
但是在后续版本中 为了减少ref声明的变量 使用中使用 .value 的复杂写法 升级了一个宏
每一个会返回 ref 的响应式 API 都有一个相对应的、以 $ 为前缀的宏函数。包括以下这些 API:
- ref -> $ref
- computed -> $computed
- shallowRef -> $shallowRef
- customRef -> $customRef
- toRef -> $toRef
假设有一个期望接收一个 ref 对象为参数的函数:
function trackChange(x: Ref<number>) {
watch(x, (x) => {
console.log('x 改变了!')
})
}
let count = $ref(0)
trackChange(count) // 无效!
上面的例子不会正常工作,因为代码被编译成了这样:因为$ 这个宏在编译的时候 自动携带了.value所以导致我们最后编译成了一个原始值
let count = ref(0)
trackChange(count.value)
这里的 count.value 是以一个 number 类型值的形式传入,然而 trackChange 期望接收的是一个真正的 ref。要解决这个问题,可以在将 count 作为参数传入之前,用 ( ) 包装: () 包装: () 包装:就是再吧$简写的对象找到他的对应的ref对象 进行传参 属于 负负得正的写法
let count = $ref(0)
- trackChange(count)
+ trackChange($$(count))
上面的代码将被编译成:
import { ref } from 'vue'
let count = ref(0)
trackChange(count)
以上是官网的例子,我个人的理解是: 宏语法是为了让我们更加简便使用,从而再使用过程中少写 . v a l u e ,这种再当前模板作为变量使用确实是没问题的,但是涉及到传参等问题,因为最后编译,识别到宏后会自动追加 . v a l u e ,所以倒是传参过去的实参失去了 r e f ,这种就需要 宏语法是为了让我们更加简便使用,从而再使用过程中少写.value,这种再当前模板作为变量使用确实是没问题的,但是涉及到传参等问题,因为最后编译,识别到宏后会自动追加.value,所以倒是传参过去的实参失去了ref,这种就需要 宏语法是为了让我们更加简便使用,从而再使用过程中少写.value,这种再当前模板作为变量使用确实是没问题的,但是涉及到传参等问题,因为最后编译,识别到宏后会自动追加.value,所以倒是传参过去的实参失去了ref,这种就需要$来找回引用的原ref响应对象。属于 负负得正的写法。
2.项目中使用了vueusejs而非pina实现数据共享
项目中几乎使用的是createSharedComposable 实现数据共享,本意只创造一个hooks观察器,多初使用 只需要调用当前hooks即可,不会重新生成一个观察器,逻辑代码也基本写再这里面了。
export const useGlobalState = createSharedComposable(
() => {
const count = ref(0)
return { count }
}
)
使用:
const { count } = $(useGlobalState())
这样的语法 使其返回的count的ref对象也识别成响应式不用再去写.value即可