VUE3+VITE 常见问题解决
reactive解构最深的一层,失去响应性问题
pinia创建的store,使用结构失去响应性
reactive包裹后的对象 重新赋值失去响应性
无法动态引入图片
在computed中传参数
vue3放弃了filter
reactive解构最深的一层,失去响应性问题
<script setup lang="ts"> let target = { a: { b: 1 } }; let target1 = { c: 1 }; const obj = reactive(target) const obj1 = reactive(target1) watch(obj, () => { console.log('obj', obj); // 有打印 }) watch(obj1, () => { console.log('obj1', obj); // 无打印 }) let { a } = obj let { c } = obj1 a.b = 3 c = 3 </script>
看看解构后的数据
console.log(a); // Proxy(...)
console.log(c); // 3
由上可以看出,最深一层结构后是数值,所以没有响应性。
使用toRef改写
let { c } = obj1
let c = toRef(obj1, 'c') c.value = 3
或是toRefs
let { c } = toRefs(obj1) c.value = 3
:::补充
reactive原理简易实现
function reactive(params) { return new Proxy(params, { get(target, p, receiver) { if (typeof target[p] === 'object') { reactive(target[p]) } // track(target,p) return Reflect.get(target, p, receiver) }, set(target, p, newValue, receiver) { // trigger(target,key) return Reflect.set(target, p, newValue, receiver) } }) }
reactive对对像属性做了深层代理。
解构原理大致是创建一个变量,从对象中匹配出 与创建变量名相同的 对象属性名,将这个属性的值(或是地址,对象的引用)复制给新的变量。
从reactive和解构原理可以看出,当reactive解构到最后一层,收集依赖的方法是
track(target,p)
,返回值是一个基本数据,此时都是正常的,问题是接下来,
基本数据的值 复制给了一个新的变量,此时,响应被断开。
!!!!!!!!!!!!!!若有不对,请大佬指导!!!!!!!!!!!!!
pinia创建的store,使用结构失去响应性
storeToRefs。
reactive包裹后的对象 重新赋值失去响应性
Vue2中,实例会在初始化时对 挂载到$data上的对象 重写并赋值 到 $data相同属性名上,当你直接给$data的属性重新赋值,监听器会认为是对 $data属性值 的更改;
而Vue3 setup中,使用reactive工具函数对 对象进行包裹(代理)实现监听并返回一个新对象,如果对这个新对象进行对象赋值,会直接替换掉上一步 reactive的包裹后的对象,所以失去了响应性,解决方法就是,reactive包裹的对象修改时,避免对象直接赋值的写法。
img标签无法动态引入图片
vite提供了静态资源处理方法:
function getImageUrl(name) { return new URL(`./dir/${name}.png`, import.meta.url).href }
文档:
https://vitejs.cn/vite3-cn/guide/assets.html#importing-asset-as-url
在computed中传参数,动态依赖
利用 computed的依赖改变重新计算的特点,可以将一些复杂逻辑抽出来。在循环或是插槽中使用的时候,需要传入参数当作依赖,当这个参数(params)改变时会重新计算获取新的返回值。
let someAttr = computed(() => (params: any) => { return params //在这里添加逻辑
})
vue3放弃了filter
使用方法或是computed代替;
PPPPS:API中有个app.config.globalProperties可以全局挂载。