在对象中新增属性时,页面不会自动更新。可以用 Vue.set 方法解决。
通过下标修改数组中的值,页面也不会自动更新。可以用数组的方法或 Vue.set 方法解决。
特注:Vue.set 不能给 vm 或根数据对象 data 添加属性!!!
修改对象时的问题:
<div id="APP"> <h3>{{title}}:</h3> <p>{{info.name}}</p> <p>{{info.age}}</p> <button @click="editAge">修改学生年龄</button> </div>
const vm = new Vue({ el: "#APP", data(){ return { title: "学生信息", info:{ name: "张三", age: 20 } } }, methods:{ editAge(){ this.info.age = 26; } } });
注:当我们修改 data 中原有的数据时,Vue 可以识别到,并且自动更新页面的内容。
但是我们往对象中新增内容时,Vue 就识别不到了。
<div id="APP"> <h3>{{title}}:</h3> <p>姓名:{{info.name}}</p> <p>年龄:{{info.age}}</p> <button @click="addAge">添加学生年龄</button> </div>
注:在页面输出一个对象中没有的属性,并不会发生报错。
const vm = new Vue({ el: "#APP", data(){ return { title: "学生信息", info:{ name: "张三" } } }, methods:{ addAge(){ this.info.age = 20; } } });
注:点击按钮后,学生年龄并没有渲染到页面中。但是我们在控制台输入 vm.info.age 时,可以看到 info 中确实已经添加了 age 属性。
原因:在控制台输入 vm.info 查看时可以发现,新增的属性没有 get 和 set 方法,所以 Vue 监听不到 age 的变化,也就不会自动渲染到页面中了。
使用 Vue.set 修改对象:
解决以上问题很简单,只需要用 Vue.set 方法添加属性就可以解决了。
<div id="APP"> <h3>{{title}}:</h3> <p>姓名:{{info.name}}</p> <p>年龄:{{info.age}}</p> <button @click="addAge">添加学生年龄</button> </div>
const vm = new Vue({ el: "#APP", data(){ return { title: "学生信息", info:{ name: "张三" } } }, methods:{ addAge(){ // 语法格式:Vue.set(要修改的对象, 属性名, 属性值); Vue.set(this.info, 'age', 20); // 也可以使用 this.$set 效果一致。 // this.$set(this.info,'age',20); } } });
注:通过 Vue.set 方法添加的属性,Vue 是可以识别到的,它也会自动渲染到页面中。并且在控制台输入 vm.info 可以看到,新增的 age 属性也带有 get 和 set 方法。
需要注意的是,Vue.set 不能直接在 data 中添加属性。
<div id="APP"> <h3>标题:{{title}}</h3> <p>姓名:{{info.name}}</p> <button @click="addTitle">添加标题</button> </div>
注:直接在页面中输入一个没有的属性时,会发生报错。
const vm = new Vue({ el: "#APP", data(){ return { info:{ name: "张三" } } }, methods:{ addTitle(){ Vue.set(this,'title','学生信息'); } } });
注:直接在 data 中添加属性时,会发生报错!!!
总结:也就是说 Vue.set 只能给 data 中的某个对象添加属性,而不能直接给 data 添加属性。
修改数组时的问题:
<div id="APP"> <h3>{{title}}:</h3> <ul> <li v-for="(item,index) in list" :key="index">{{item}}</li> </ul> <button @click="editList">修改第一个爱好</button> </div>
const vm = new Vue({ el: "#APP", data(){ return { title: "爱好", list: ['草莓', '烧饼', '辣条'] } }, methods:{ editList(){ this.list[0] = '火锅'; } } });
注:当我们通过下标修改数组中的内容时,Vue 也是监测不到的。这是因为 Vue 没有给数组中的每个值设置 get 和 set 方法。所以修改后页面不会发生任何变化。
不过 Vue 为我们重新封装了数组中的七个方法,供我们使用操作数组。他们分别是:
// 尾部新增 push 数组.push(要新增的值); // 尾部删除 pop 数组.pop(); // 头部新增 unshift 数组.unshift(要新增的值); // 头部删除 shift 数组.shift(); // 数组指定删除 splice 数组.splice(从哪开始删除, 删除几个); // 数组指定添加 splice 数组.splice(在第几个之前添加, 0, 要添加的值); // 数组指定替换 splice 数组.splice(替换掉第几个内容, 1, 替换后的值); // 颠倒数组 reverse 数组.reverse(); // 排序数组 sort 数组.sort((a,b) => { return a-b; });
注:只有能修改原数组的方法才可以被 Vue 监听。当使用数组的其他方法时,需要将修改后的值重新赋给原数组。
所以,以上的问题我们就可以使用 splice 方法来解决。
<div id="APP"> <h3>{{title}}:</h3> <ul> <li v-for="(item,index) in list" :key="index">{{item}}</li> </ul> <button @click="editList">修改第一个爱好</button> </div>
const vm = new Vue({ el: "#APP", data(){ return { title: "爱好", list: ['草莓', '烧饼', '辣条'] } }, methods:{ editList(){ this.list.splice(0, 1, '火锅'); } } });
注:通过 splice 方法修改数组中的内容后,Vue 就可以识别到,并更新页面中的内容。
使用 Vue.set 修改数组:
<div id="APP"> <h3>{{title}}:</h3> <ul> <li v-for="(item,index) in list" :key="index">{{item}}</li> </ul> <button @click="editList">修改第一个爱好</button> </div>
const vm = new Vue({ el: "#APP", data(){ return { title: "爱好", list: ['草莓', '烧饼', '辣条'] } }, methods:{ editList(){ // 语法格式:Vue.set(要修改的数组, 下标, 修改后的值); Vue.set(this.list, 0, '火锅'); } } });
注:用 Vue.set 方法也可以通过下标修改数组中的内容。
原创作者: 吴小糖
创建事件:2023.3.16