前端招聘去哪个网站,杭州建站软件,网络营销和网络推广,手机网站 设计图目录 一、修改数据时的一个问题1.1 现象一1.2 现象二 二、Vue监测数据原理2.1 模拟一个数据监测2.2 数据劫持2.3 Vue.set()/vm.$set()2.4 基本原理2.4.1 如何监测对象中的数据?2.4.2 如何监测数组中的数据?2.4.3 修改数组中的某个元素 2.5 案例2.5.1 需求功能2.5.2 实现 一、… 目录 一、修改数据时的一个问题1.1 现象一1.2 现象二 二、Vue监测数据原理2.1 模拟一个数据监测2.2 数据劫持2.3 Vue.set()/vm.$set()2.4 基本原理2.4.1 如何监测对象中的数据?2.4.2 如何监测数组中的数据?2.4.3 修改数组中的某个元素 2.5 案例2.5.1 需求功能2.5.2 实现 一、修改数据时的一个问题 下面案例中我们定义了一个按钮期望是点击按钮更新persons[0] 的信息。
但实际问题是Vue监测不到数据的变化。
div idrooth2列表过滤/h2button clickchange更新令狐冲信息/buttonulli v-for(p,index) in persons :keyp.id {{p.name}} - {{p.use}} - {{p.age}}/li/ul/div
scriptconst vm new Vue({el:#root,data:{persons:[{id:001,name:令狐冲,use:独孤九剑,sex:男,age:20},{id:002,name:任盈盈,use:仙女下凡,sex:女,age:19},{id:003,name:任我行,use:吸星大法,sex:男,age:50}]},methods: {change(){// 可行的方式// this.persons[0].name 假的令狐冲;// this.persons[0].use 葵花宝典;// this.persons[0].age 100;// Vue没发现你修改了数据其实已经改了this.persons[0] {id:001,name:假的令狐冲,use:葵花宝典,sex:男,age:100}}},})
/script1.1 现象一
在浏览器中打开页面在打开vue-devtools点击按钮观察工具中的数据竟然没有发生变化但其实数据已经真实改变了我们可以通过控制台输入vm.persons[0] 查看发现数据确实变了。 1.2 现象二
在浏览器中打开页面然后先点击按钮再打开vue-devtools查看工具中数据发现数据改变了 二、Vue监测数据原理 2.1 模拟一个数据监测
下面案例中当data的数据发生变化就会在控制台打印出一句话。
let data {name:令狐冲,menpai:华山派
}// 创建一个监视的实例对象用于监视data中属性的变化
const obs new Observer(data)// 准备一个vm的实例对象
let vm {}
vm._data data obs;function Observer (obj) {// 汇总对象中所有的属性形成一个数组const keys Object.keys(obj);keys.forEach((k){Object.defineProperty(this,k,{get(){return obj[k]},set(val){console.log(${k}被改了之后解析模板生成虚拟DOM....);obj[k] val}})})
}2.2 数据劫持
数据劫持在访问或修改对象的某个属性时通过一段代码拦截这个行为进行额外的操作如修改返回结果。
Vue 2.x 使用的是 Object.defineProperty()而 Vue 在 3.x 版本之后改用 Proxy 进行实现
2.3 Vue.set()/vm.$set() 语法Vue.set( target, propertyName/index, value ) 功能向响应式对象中添加一个 property并确保这个新property同样是响应式的且触发视图更新。 注意它必须用于向响应式对象上添加新 property因为 Vue无法探测普通的新增 property (比如 this.myObject.newProperty hi) Vue.set(this.person.hobby, 0, 哈哈哈)this.$set(this.person.hobby, 0, 哈哈哈)// 从第0个位置删一个在插入一个
// this.person.hobby.splice(0,1,哈哈哈)2.4 基本原理
Vue监测到data中的数据所有层次的数据发生变化就会调用setter重新解析模板解析引用的到的数据的值。
2.4.1 如何监测对象中的数据? 通过setter实现监视且要在new Vue时就传入要监测的数据。 (1). 对象中后追加的属性Vue默认不做响应式处理 (2). 如需给后添加的属性做响应式请使用如下API: Vue.set(target, propertyName/indexvalue)vm.$set(target, propertyName/index,value)2.4.2 如何监测数组中的数据?
Vue通过包裹数组的更新元素的方法实现本质就是做了两件事
(1). 调用原生对应的方法对数组进行更新。(2). 重新解析模板,进而更新页面。
数组中这些被包裹过的方法包括
push()pop()shift()unshift()splice()sort()reverse()
2.4.3 修改数组中的某个元素
在Vue中修改数组中的某个元素一定要用如下方法才能实现响应式
被包裹过的方法push()、pop()、shift()、unshift()、splice()、sort(). reverse()通过Vue.set()或vm.$set()
注意Vue.set()和 vm.$set() 不能给vm或 vm的根数据对象(vm.data)添加属性。
2.5 案例
2.5.1 需求功能
需求如下截图 2.5.2 实现
div idrooth2笑傲江湖/h2hrdivbutton clickperson.age年龄1岁/button button clickaddSex添加性别属性,默认值:男/button button clickaddFriend在列表首位添加一个朋友/buttonbutton clickupdateFName修改第一个朋友的名字为:小三/buttonbutton clickaddHobby添加一个爱好/buttonbutton clickupdateHobby修改第一个爱好为: 哈哈哈/buttonbutton clickremoveHobby过滤爱好中的喝酒/button/divh3姓名{{person.name}}/h3h3年龄{{person.age}}/h3h3 v-ifperson.sex性别{{person.sex}}/h3h3爱好/h3ulli v-for(h,index) in person.hobby ::keyindex{{h}}/li/ulh3朋友/h3ulli v-for(f,index) in person.friends ::keyindex{{f.name}} - {{f.age}}/li/ul/div
scriptconst vm new Vue({el:#root,data:{person:{name:令狐冲,age:26,hobby:[喝酒,练剑,行侠仗义],friends:[{name:田伯光,age:30},{name:任我行,age:50}]}},methods: {addSex(){// Vue.set(this.person,sex,男)this.$set(this.person,sex,男)},addFriend(){this.person.friends.unshift({name:任盈盈,age:26})},updateFName(){this.person.friends[0].name 小三},addHobby(){this.person.hobby.push(大笑)},updateHobby(){// 从第0个位置删一个在插入一个// this.person.hobby.splice(0,1,哈哈哈)// Vue.set(this.person.hobby, 0, 哈哈哈)this.$set(this.person.hobby, 0, 哈哈哈)},removeHobby(){this.person.hobby this.person.hobby.filter((h){return h ! 喝酒})}},})
/script