"vue": "^3.2.35" 版本新增macros.d.ts的声明文件
这个声明文件是可以直接进行使用,也就说是宏编译的
解决的问题是:
// 新增之前需要.value
let a = ref<number>(0);
a.value++
// 新增之后
let b = $ref<number>(0);
const values = $computed(() => b * 2);
// 配置方式
找到env.d.ts添加这个 我这个是ts 添加下面这个东西
/// <reference types="vue/macros-global" />
本质上来说这是一个语法糖
ref -> $ref
computed -> $computed
shallowRef -> $shallowRef
customRef -> $customRef
toRef -> $toRef
以前所导入到响应式函数,可以添加$这样,你就可以省略.value
注意点:如果当前$不在setup区域内部,比如在一个函数中,你直接返回是不好用的
例子:
const useMouse = () => {
let x = $ref(0);
let y= $ref(0);
const update = (event:MouseEvent) => {
x = event.pageX;
y = event.pageY;
}
onMounted(()=> window.addEventListener('mousemove',update))
// 这样返回页面不是出现响应式的
return {x,y}
}
改修:
return $$({x,y})
//注意点:$作为函数参数的时候的问题
//例子:
let data = $ref(0);
//这里证明了,你发过来的参数不是一个响应式的
//所以即使你使用watch来观察也是无用的,也无法对页面进行逻辑操作
const watchData = (data: Ref<number>) => {
console.log(isRef(data)) //false
console.log(isReactive(data)) //false
}
onMounted(() => {
watchData(data);
})
改修:
onMounted(() => {
watchData($$(data));
})
$:的本质
let data = $ref(0)
当代理基本数据类型的时候,你使用
console.log(isReactive(data),isRef(data),isProxy(data));
来检查数据的时候,都是false,因为vue帮你做了解包,将内部的.value拿出来了,他是这个值,不是响应式对象
那为什么我更改的时候,页面也有反应?
因为:当我操作.value的时候由于对象的特性,我操作.value就相当于操作源码中ref类中.value,而这个ref类是一个响应式对象
其实ref也是reactive,因为proxy不能代理基本数据类型,所以才会出现ref来代理基本数据类型,我们将整个ref类看作成对象,通过get
set 来控制响应式
如果代理的是
let data = $ref({
name:'zs'
})
console.log(isReactive(data),isRef(data),isProxy(data));
// 返回 true true false
也就说,最终这个东西还是个reactive
当我们使用$$的时候。就会把data ===》 这个代理数据代理方式改回ref
console.log(isReactive($$(data)),isProxy($$(data)),isRef($$(data)))
false false true
// 这里在解释 isReactive isProxy 为啥打印的结果一样呢?
我们在源码可以看到 isProxy 和 isReactive 其实检查的是一个东西 都是查看当前代理的对象中是否包含 __v_isReactive
所以打印的东西都是一样的