vue2
由于javascript限制,vue不能检测
数组和对象的变化
什么意思呢,举例子来说吧
深入响应式原理
对象
比如说我们在data里面定义了一个info的对象
html
<template>
<div id="app">
<div>姓名: {{ info.name }}</div>
<div>年龄: {{ info.age }}</div>
<div>地址: {{ info.address }}</div>
<button @click="handleAddProp">追加prop</button>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
info: {
name: "于十月",
age: 28,
},
};
},
methods: {
handleAddProp() {
this.info.address = "山东省济南市";
},
},
};
</script>
我们在info
对象里面只定义了name
,age
两个字段,然后我们在页面展示了name,age,address
三个字段,我们想再点击按钮的时候,给address
赋值,这个时候会有什么效果?可以自己试一下,效果就是,页面上没有任何效果
也就是说我们在info声明的时候没有address
这个字段,后续我们在操作中去修改这个字段,vue是不能给我们检测到的
所以要想实现效果的话官方给提供实现方案
Vue.set或者this.$set
Object.assign()或者_.extend()
具体实现如下:
html
<template>
<div id="app">
<div>姓名: {{ info.name }}</div>
<div>年龄: {{ info.age }}</div>
<div>地址: {{ info.address }}</div>
<div>手机号: {{ info.phone }}</div>
<button @click="handleAddProp">追加prop</button>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
info: {
name: "于十月",
age: 28,
},
};
},
methods: {
handleAddProp() {
// this.info.address = "山东省济南市";
this.$set(this.info, "address", "山东省济南市");
// or
this.info = Object.assign({}, this.info, { phone: 138888888888 });
},
},
};
</script>
数组
vue不能检测以下数组的变动
- 当你利用索引直接设置一个数组项时
vm.items[index] = newValue
- 当你修改数组的长度时
vm.items.length = newLength
html
<template>
<div id="app">
<p v-for="(val, index) in list" :key="index">{{ val }}</p>
<button @click="handleChangeList">修改数组项</button>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
list: [1, 2, 3, 4],
};
},
methods: {
handleChangeList() {
this.list[0] = "小明";
},
},
};
</script>
我们希望点击按钮的时候1
能够变成小明
,但发现并没有任何效果,要想实现的话也可以使用$set
html
<template>
<div id="app">
<p v-for="(val, index) in list" :key="index">{{ val }}</p>
<button @click="handleChangeList">修改数组项</button>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
list: [1, 2, 3, 4],
};
},
methods: {
handleChangeList() {
// this.list[0] = "小明";
this.$set(this.list, 0, "小明");
},
},
};
</script>
vue3
我们可以按照上面的数据在vue里面试一下
html
<script setup>
const info = reactive({
name: '于十月',
});
const list = ref([1, 2, 3]);
const handleAddProp = () => {
info.address = '山东省济南市';
info.age = 28;
};
const handleChangeList = () => {
list.value[0] = '小明';
};
</script>
<template>
<div>姓名: {{ info.name }} -- 年龄 {{ info.age }} --- {{ info.address }}</div>
<a-button @click="handleAddProp">修改prop</a-button>
<div>
<p v-for="(val, index) in list" :key="index">{{ val }}</p>
</div>
<a-button @click="handleChangeList">修改数组的值</a-button>
</template>
然后发现不需要做特殊的处理,就可以实现我们想要的效果
其实这里面就牵扯到了关于vue2与vue3内部实现响应式的原理了,vue2使用defineProperty
,vue3的时候直接放弃用了proxy
具体怎么他俩怎么实现的后面在写
这就可以延伸出来很多面试题,比如
1.vue2跟vue3在处理数据这一块有什么不同吗?
2.vue2里面我往对象里面新增一个属性,这个时候界面会有变化吗?
3.为什么使用 $set之后就可以实现数据的响应, $set的实现原理是什么?
4.vue2在处理对象和数据的时候有什么弊端?
。。。。。
即使没搞明白深层原理,把官方文档看明白,碰到这些问题也会迎刃而解~