16-Vue核心-Vue数据监视
我们先探讨一个数据更新时的问题,假设在以下人员列表中,改变"马冬梅"的信息,可以通过什么方法
1)第一种方法(奏效)
数据更新时,方法奏效
this.persons[0].name = "马老师" this.persons[0].age = 50 this.persons[0].sex = "男"
2)第二种方法(不奏效)
数据更新时,Vue不监听,模板不改变,但通过控制台命令,vm.persons[0].name 发现内部数据已经发生改变
this.persons[0] = {id:"001",name:"马老师",age:50,sex:"男"}
3)第三种方法(奏效)
// splice() 方法用于添加或删除数组中的元素 // 第一个参数代表要添加的索引位置,第二参数代表要添加或删除的个数,第三个参数代表内容 this.persons.splice(0,1,{id:"001",name:"马老师",age:50,sex:"男"})
完整代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>数据更新时的一个问题</title> <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!-- 准备好一个容器 --> <div id="root"> <!-- 遍历数组 --> <h2>人员列表</h2> <button @click="updateData">更新马冬梅的信息</button> <ul> <li v-for="(p,index) in persons" :key="index"> 姓名:{{p.name}}    年龄:{{p.age}}    性别:{{p.sex}} </li> </ul> </div> <script type="text/javascript"> // 阻止 vue 在启动时生成生产提示 Vue.config.productionTip = false new Vue({ el:"#root", data(){ return{ persons:[ {id:"001",name:"马冬梅",age:30,sex:"女"}, {id:"002",name:"周冬雨",age:28,sex:"女"}, {id:"003",name:"周杰伦",age:24,sex:"男"}, {id:"004",name:"温兆伦",age:32,sex:"男"} ], } }, methods:{ updateData(){ // this.persons[0].name = "马老师" // this.persons[0].age = 50 // this.persons[0].sex = "男" // this.persons[0] = {id:"001",name:"马老师",age:50,sex:"男"} // splice() 方法用于添加或删除数组中的元素 // 第一个参数代表要添加的索引位置,第二参数代表要添加或删除的个数,第三个参数代表内容 this.persons.splice(0,1,{id:"001",name:"马老师",age:50,sex:"男"}) } } }) </script> </body> </html>
模拟一个数据监测
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>数据更新时的一个问题</title> <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <script type="text/javascript"> // 阻止 vue 在启动时生成生产提示 Vue.config.productionTip = false // 声明一个变量 let data = { name:"马铃薯", address:"河北" } // // 声明一个中间变量 // let tmp = "" // // 定时器方法,每隔一定时间就调用函数,方法或对象 // setInterval(()=>{ // if(data.name !== tmp){ // tmp = data.name // console.log("name正在被修改") // } // },100) // 创建要给监视的实例对象,用于监视 data 中属性的变化 const obs = new Observer(data) console.log(obs) // Observer 构造函数 function Observer(obj){ // 汇总对象中所有属性,形成一个数组 const keys = Object.keys(obj) // 遍历,forEach() 方法对数组的每个元素执行一次提供的函数 keys.forEach((k)=>{ // Object.defineproperty方法的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性 Object.defineProperty(this,k,{ get(){ return obj[k] }, set(val){ obj[k] = val console.log(`${k}正在被修改,进行解析模板,生成虚拟DOM...`) } }) }) } //准备一个 vm 实例对象 let vm = {} vm._data = data = obs </script> </body> </html>
Vue中set的使用
在student中,使用vue.set()方法添加一个sex属性,看看前后效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue set的使用</title> <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!-- 准备好一个容器 --> <div id="root"> <!-- 遍历数组 --> <h2>学校名称:{{name}}</h2> <h2>学校地址:{{address}}</h2> <hr/> <h2>学生姓名:{{student.name}}</h2> <button @click="addSex">添加一个性别属性,默认值是男的</button> <!-- 控制台 Vue.set(vm._data.student,"sex","男") --> <!-- 判断是否有学生的性别属性,有则进行展示,否则不展示 --> <h2 v-if="student.sex">学生性别:{{student.sex}}</h2> <h2>学生年龄:对内{{student.age.rAge}},对外:{{student.age.sAge}}</h2> <h2>爱好</h2> <ul> <li v-for="(f,index) in student.hobby" :key="index">{{f}}</li> </ul> <h2>朋友列表</h2> <ul> <li v-for="(f,index) in student.friends" :key="index"> 姓名:{{f.name}}    年龄:{{f.age}} </li> </ul> </div> <script type="text/javascript"> // 阻止 vue 在启动时生成生产提示 Vue.config.productionTip = false const vm = new Vue({ el:"#root", data(){ return{ name:"尚硅谷", address:"北京", student:{ name:"马铃薯", age:{ rAge:26, sAge:30 }, hobby:["抽烟","喝酒","烫头"], friends:[ {name:"大宇",age:26}, {name:"帆帆",age:26} ] } } }, methods:{ updateData(){ // this.persons[0].name = "马老师" // this.persons[0].age = 50 // this.persons[0].sex = "男" // this.persons[0] = {id:"001",name:"马老师",age:50,sex:"男"} // splice() 方法用于添加或删除数组中的元素 // 第一个参数代表要添加的索引位置,第二参数代表要添加或删除的个数,第三个参数代表内容 this.persons.splice(0,1,{id:"001",name:"马老师",age:50,sex:"男"}) }, addSex(){ // Vue.set(vm._data.student,"sex","男") Vue.set(this.student,"sex","男") } } }) </script> </body> </html>
1)初始效果
2)使用Vue.set(vm._data.student,"sex","男"),添加之后的效果
Vue监视数据的原理
1.Vue会监视data中所有层次的数据
2.如何监测对象中的数据
通过setter实现监视,且要在new Vue时就传入要监测的数据
1)对象中后追加的属性,Vue默认不做响应式处理
2)如需给后添加的属性做响应式,请使用如下API:
Vue.set(target, propertyName/index, value) 或 vm.$set(target, propertyName/index, value)
3.如何监测数组中的数据
通过包裹数组更新元素的方法实现,本质就是做了两件事
1)调用原生对应的方法对数组进行更新
2)重新解析模板,进而更新页面
4.在Vue修改数组中的某个元素一定要用如下方法:
1)使用数组的这七个API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
push( )方法:可以将一个或者更多的参数添加在数组的尾部;返回添加后的数组的长度,原数组发生改变
// 写法:array.push(item1, item2, …, itemX) var arr=[1,2,3,4]; var a=arr.push(9,8,7); console.log(a,arr);
unshift( )方法:可以将一个或者更多的参数添加在数组的头部;返回添加后的数组的长度,原数组发生改变。
// 写法:array.unshift(item1,item2, …, itemX) var arr=[1,2,3,4]; var a=arr.unshift(9,8,7); console.log(a,arr);
pop( )方法:从数组尾部删除一个元素,返回这个被删除的元素,原数组发生改变。
// 写法:array.pop() var arr=[1,2,3,4]; var a=arr.pop(); console.log(a,arr)
shift( ) 方法:从数组头部删除一个元素,返回这个被删除的元素,原数组发生改变。
// 写法:array.shift() var arr = [1,2,3,4]; var a = arr.shift(); console.log(a,arr)
splice( ) 方法:方法用于添加或删除数组中的元素
没有参数,返回空数组,原数组不变;
一个参数,从该参数表示的索引位开始截取,直至数组结束,返回截取的 数组,原数组改变;
两个参数,第一个参数表示开始截取的索引位,第二个参数表示截取的长度,返回截取的 数组,原数组改变;
三个或者更多参数,第三个及以后的参数表示要从截取位插入的值。
var hobby = ["抽烟","喝酒","烫头"]; // 将数组的第一个元素改为”开车“ hobby.splice(0,1,"开车") //删除第二个元素 hobby.splice(1,1) console.log(hobby)
2)Vue.set() 或 vm.$set()
// Vue.set()方法 Vue.set(vm._data.student,"sex","男") Vue.set(this.student,"sex","男") //vm.$set()方法 this.$set(this.student,"sex","男")
特别注意:Vue.set() 和 vm.$set() 不能给 vm 或 vm的根数据对象 添加属性 !!!
完整代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue set的使用</title> <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!-- 准备好一个容器 --> <div id="root"> <h1>学生信息</h1> <button @click="student.age++">年龄+1岁</button><br/> <button @click="addSex">添加性别属性,默认值:男</button><br/> <button @click="student.sex === '男' ? student.sex = '女' : student.sex = '男'">修改性别</button><br/> <button @click="addFriend">在列表首位添加一个朋友</button><br/> <button @click="updataFirstFriendName">修改第一个朋友的名字为:张三</button><br/> <button @click="addHobby">添加一个爱好</button><br/> <button @click="updateHobby">修改第一个爱好为:开车</button><br/> <h3>姓名:{{student.name}}</h3> <!-- 控制台 Vue.set(vm._data.student,"sex","男") --> <!-- 判断是否有学生的性别属性,有则进行展示,否则不展示 --> <h3 v-if="student.sex">学生性别:{{student.sex}}</h3> <h3>年龄:{{student.age}}</h3> <h3>爱好</h3> <ul> <li v-for="(h,index) in student.hobby" :key="index">{{h}}</li> </ul> <h3>朋友列表</h3> <ul> <li v-for="(f,index) in student.friends" :key="index"> 姓名:{{f.name}}    年龄:{{f.age}} </li> </ul> </div> <script type="text/javascript"> // 阻止 vue 在启动时生成生产提示 Vue.config.productionTip = false const vm = new Vue({ el:"#root", data(){ return{ student:{ name:"马铃薯", age:26, hobby:["抽烟","喝酒","烫头"], friends:[ {name:"大宇",age:26}, {name:"帆帆",age:26} ] } } }, methods:{ addSex(){ // Vue.set(vm._data.student,"sex","男") // Vue.set(this.student,"sex","男") this.$set(this.student,"sex","男") }, addFriend(){ // 在数组,第一个位置添加一个元素 this.student.friends.unshift({name:"钦权",age:24}) }, updataFirstFriendName(){ this.student.friends[0].name = "张三" }, addHobby(){ // 在数组,最后一个位置添加一个元素 this.student.hobby.push("打豆豆") }, updateHobby(){ // splice() 方法用于添加或删除数组中的元素 // 第一个参数代表要添加的索引位置,第二参数代表要添加或删除的个数,第三个参数代表内容 // this.student.hobby[0].splice(0,1,"开车") // Vue.set(this.student.hobby,0,"开车") this.$set(this.student.hobby,0,"开车") } } }) </script> </body> </html>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本