vue2失去响应式
原理
Object.defineProperty无法监控到数组下标和长度的变化,因为添加或删除的对象的属性没 有 在 初 始 化 进 行 响 应 式 处 理 ,Object.defineProperty检测不到
<template>
<div>
<h2>{{ obj }}</h2>
<h2>{{ arr }}</h2>
</div>
</template>
<script>
export default {
data() {
return {
obj: {
a: "Hello World!",
},
arr: [1, 2, 3],
};
},
mounted() {
this.changeObj();
this.changeArr();
},
methods: {
changeObj() {
this.obj.b = "新增的属性b";
console.log(this.obj);
},
changeArr() {
this.arr[4] = 7;
this.arr.length = 5;
console.log(this.arr);
},
},
};
</script>
this.$set() this.$delete解决
this.$set(target, key, value)
this.$delete(target, key)
changeObj() {
this.$set(this.obj, b, "新增的属性b")
console.log(this.obj);
},
changeArr() {
this.$set(this.arr, 3, 7)
console.log(this.arr);
this.$delete(this.arr, 0)
console.log(this.arr);
},
vue3解构赋值原始类型失去响应式
原理
解构赋值原始类型失去响应式
解构赋值引用类型失去响应式
原始类型的赋值相当于按值传递,引用类型的值就相当于按引用传递
原始类型
// 假设a是个响应式对象
const a={ b:1}
// c 此时就是一个值跟当前的a 已经不沾边了
const c=a.b
// 你直接访问c就相当于直接访问这个值 也就绕过了 a 对象的get ,也就像原文中说的失去响应式
引用类型
// 假设a是个响应式对象
const a={ b:{c:3}}
// 当你访问a.b的时候就已经重新初始化响应式了,此时的c就已经是个代理的对象
const c=a.b
// 你直接访问c就相当于访问一个响应式对象,所以并不会失去响应式
禁止直接赋值reactive响应式对象
由于解构赋值的问题, 他直接禁止了reactive的解构赋值
// 当reactive 之后返回一个代理对象的地址被vue 存起来,
// 用一个不恰当的比喻来说,就是这个地址具备响应式的能力
const vue = reactive({ a: 1 })
// 而当你对于vue重新赋值的时候不是将新的对象赋值给那个地址,而是将vue 换了个新地址
// 而此时新地址不具备响应式,可不就失去响应式了吗
vue = { b: 2 }
通过storeToRefs解构pinia属性保持响应式
import { storeToRefs } from "pinia";
const system = useSystem();
const { isNewProject, isOpenEdit } = storeToRefs(system)
el-select 的option 绑定pinia数据失去响应
// 失去响应写法
<el-select
v-model="selectedValue"
clearable
popper-class="select_default"
class="my-select"
placeholder="全部"
size="default"
@change="selectChange"
>
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
import { OrderStore } from '@/store';
const orderStore = OrderStore(); // 实例化store
const option = orderStore.orderType
// 正确带响应写法1
<el-select
v-model="selectedValue"
clearable
popper-class="select_default"
class="my-select"
placeholder="全部"
size="default"
@change="selectChange"
>
<el-option v-for="item in orderStore.orderType" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
import { OrderStore } from '@/store';
const orderStore = OrderStore(); // 实例化store
// 正确带响应写法2
<el-select
v-model="selectedValue"
clearable
popper-class="select_default"
class="my-select"
placeholder="全部"
size="default"
@change="selectChange"
>
<el-option v-for="item in orderType" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
import { storeToRefs } from 'pinia';
import { OrderStore } from '@/store';
const orderStore = OrderStore(); // 实例化store
const { orderType } = storeToRefs(orderStore);