惠州网站制作设计,常德做网站专业公司哪家好,建e网全景图合成教程,如何在公司建网站系统一、更新时的一个问题
如果我要点击按钮实现更新冯万宁儿的信息#xff0c;那么如果一个属性一个属性地改#xff0c;可以修改成功#xff0c;并且Vue也会检测到并更新到页面。
但是我如果直接把要修改的信息写在this.persons[0] { id: 001, name: 冯千宁儿, age: 66, se…一、更新时的一个问题
如果我要点击按钮实现更新冯万宁儿的信息那么如果一个属性一个属性地改可以修改成功并且Vue也会检测到并更新到页面。
但是我如果直接把要修改的信息写在this.persons[0] { id: 001, name: 冯千宁儿, age: 66, sex: 女 };这里就不行Vue监测不到并且不更新到页面这是为什么 !-- 准备好一个容器 --div idrooth1人员列表/h1button clickupdateNing点击更新冯万宁儿/buttonulli v-for(p,index) in persons :keyp.id{{p.name}}----{{p.age}}----{{p.sex}}/li/ul/divscriptconst vm new Vue({el: #root,data: {keyword: ,persons: [{ id: 001, name: 冯万宁儿, age: 23, sex: 男 },{ id: 002, name: 屁及万儿, age: 18, sex: 男 },{ id: 003, name: 及丽热巴, age: 10, sex: 女 },{ id: 004, name: 冯小刚儿, age: 60, sex: 男 }]},methods: {updateNing() {// this.persons[0].name 冯千宁儿; //奏效// this.persons[0].age 66; //奏效// this.persons[0].sex 女; //奏效this.persons[0] { id: 001, name: 冯千宁儿, age: 66, sex: 女 };//上面这么写也奏效数据实际上已经改了但是Vue监测不到所以没更新到页面为啥捏}}})/script
二、原生js模拟Vue监视data对象中的数据
用原生js写一个Vue监视data数据改变的效果
可以看出Vue监视数据的原理就是靠setter
script typetext/javascriptlet data {name : cgp,age : 18}// 创建一个监视的实例对象用于监视data中属性的变化const obs new Observer(data)console.log(obs);// 准备一个vm实例对象let vm {}vm._data data obsfunction 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}})})}/script
这只是个模拟实际上Vue做了更多事情比如 1、在setter中不是简单的输出而是重新解析模板生成虚拟DOM新旧虚拟DOM对比更新页面实现响应式。 2、Vue中vm还对_data做了数据代理我可以直接vm.name不用vm._data.name 3、我这么写如果数据是套娃的对象中还有对象还有对象就监测不到。但是Vue就可以不管你数据藏得多深Vue都能找到每个数据都有自己的getter和setter。只要有数据被改就会实现响应式。这里面好像涉及了深拷贝的知识 三、Vue监测对象中的数据 1、监视对象中的数据
1、vue会监视data中所有层次的数据不管你藏得有多深。 2、如何监测对象中的数据 通过setter实现监视且要在new Vue时就传入要监测的数据。 (1).对象中后追加的属性Vue默认不做响应式处理 (2).如需给后添加的属性做响应式请使用如下API
Vue.set(targetpropertyName/indexvalue) 或
vm.$set(targetpropertyName/indexvalue)2、Vue.set的使用
用法
向响应式对象中添加一个 property并确保这个新 property 同样是响应式的且触发视图更新。它必须用于向响应式对象上添加新 property因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty hi)
注意对象不能是 Vue 实例或者 Vue 实例的根数据对象。
_data在收集data中的数据之前先做了一个加工这个加工也可以称之为数据劫持那就是给每个数据匹配一个getter和setter前面说了Vue监视数据的原理就是靠setter。所以如果我们后期手动直接给_data添加属性注意区别手动添加和从data中收集是无法实现响应式的因为没办法给它setter只有从data中收集过来的属性才能通过一个鱿鱼西定义的好像是叫Observer什么什么的方法给它搞个setter。
Vue.set()是有局限性的它只能给data中的某个对象追加属性不能给vm 或 vm的根数据对象data或_data 添加属性 也就是说第一个参数不能是 Vue 实例或者 Vue 实例的根数据对象_data
例如给学生添加性别 div idrooth1学校信息/h1h2学校名称{{name}}/h2h2学校地址{{address}}/h2hrh1学生信息/h1button clickadd添加性别/buttonh2学生姓名{{student.name}}/h2h2 v-ifstudent.sex学生性别{{student.sex}}/h2h2学生年龄真实{{student.age.rAge}}, 对外{{student.age.sAge}}/h2h2朋友/h2ulli v-for(f,index) in student.friends :keyindex{{f.name}}----{{f.age}}/li/ul/divscriptconst vm new Vue({el:#root,data:{name:椰果,address:郑州,student:{name:cgp,age:{rAge:18,sAge:19},friends:[{name:yhg,age:20},{name:zym,age:21}]}},methods:{add(){// Vue.set(this.student,sex,男)this.$set(this.student,sex,男)}}})/script
四、Vue监测数组中的数据
1.如何监测数组中的数据 其实是Vue里面定义了一个非常牛逼的方法目的只有一个实现响应式。
方法里包装的代码本质就是做了两件事 1调用原生对应的方法对数组进行更新。然后第二步在这个基础上再加点料 2重新解析模板生成虚拟DOMdiff算法……进而更新页面实现响应式。
所以在Vue修改数组中的某个元素实现响应式一定要用如下方法 1使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse() 2Vue.set() 或 vm.$set()也可以实现响应式第二个参数写索引第三个写元素可以改也可以加
2、例如
div idrooth2我的名字{{name}}/h2h2我的年龄{{age}}/h2hrh2他的名字{{boyfriend.name}}/h2button clickaddHobby点击替换跳的爱好/buttonh2爱好/h2ulli v-for(h,index) in girlfriend.hobby :keyindex{{h}}/li/ul
/div
scriptconst vm new Vue({el: #root,data: {name: cgp,age: 18,girlfriend: {name: ht,hobby: [唱, 跳, rap]}},methods: {addHobby() {//除了那7个方法外set方法也可以改变数组实现响应式Vue.set(this.girlfriend.hobby, 1, 打游戏);}},})
/script
五、回头看看第一个问题
说了这么多再回头看第一个问题就恍然大悟了 1、单独改每个属性可以奏效是因为Vue可以监测到对象里的每个属性不管它藏的多深只要是个对象就有相应的getter和setter 2、将数组中的元素单独替换数据修改成功但是Vue没有监测到页面不显示这是因为数组中的每个元素是没有getter和setter的如果修改数组中的元素无法实现响应式. 3、要想让更改数组中的元素实现响应式就得调用数组的七个api或者用Vue.set()方法
!-- 准备好一个容器 --
div idrooth1人员列表/h1button clickupdateNing更新冯万宁儿/buttonulli v-for(p,index) in persons :keyp.id{{p.name}}----{{p.age}}----{{p.sex}}/li/ul
/divscriptconst vm new Vue({el: #root,data: {persons: [{ id: 001, name: 冯万宁儿, age: 23, sex: 男 },{ id: 002, name: 屁及万儿, age: 18, sex: 男 },{ id: 003, name: 及丽热巴, age: 10, sex: 女 },{ id: 004, name: 冯小刚儿, age: 60, sex: 男 }],},methods: {updateNing() {// this.persons[0].name 冯千宁儿; //奏效// this.persons[0].age 66; //奏效// this.persons[0].sex 女; //奏效// this.persons[0] { id: 001, name: 冯千宁儿, age: 66, sex: 女 };//上面这么写也奏效数据实际上已经改了但是Vue监测不到所以没更新到页面为啥捏//实际上是因为Vue监测数组时数组没有相应的setter和getter直接改Vue监测不到//但是数组中的每个对象中的属性都有自己的gettersetter所以单独改属性时可以监测到的//要想让更改数组中的元素实现响应式就得调用数组的七个api或者用setthis.persons.splice(0, 1, { id: 001, name: 冯千宁儿, age: 66, sex: 女 });}}})
/script六、练习
div idrootbutton clickaddSex添加一个性别属性默认为女/buttonbutton clickaddHeight添加一个身高属性默认为170/buttonbrbutton clickgirlfriend.age.realAge--年龄-1/buttonbutton clickaddFriend在列表前加一个朋友/buttonbrbutton clickupdateFriend修改第一个朋友的名字为张三/buttonbutton clickaddHobby添加一个爱好/buttonbrbutton clickupdateHobby修改第一个爱好为散步/buttonbutton clickremoveHobby过滤掉爱好中的跳/buttonh2名字{{girlfriend.name}}/h2h2年龄对外{{girlfriend.age.fakeAge}}真实{{girlfriend.age.realAge}}/h2h2 v-ifgirlfriend.sex性别{{girlfriend.sex}}/h2h2 v-ifgirlfriend.height身高{{girlfriend.height}}/h2h2朋友们/h2ulli v-forp in girlfriend.friends :keyp.id{{p.name}}----{{p.age}}/li/ulh2爱好/h2ulli v-for(h,index) in girlfriend.hobby :keyindex{{h}}/li/ul
/div
scriptconst vm new Vue({el: #root,data: {name: zzy,age: 18,girlfriend: {name: ht,// sex: 女,age: {realAge: 23,fakeAge: 18},friends: [{ id: 001, name: jack, age: 10 },{ id: 002, name: rose, age: 8 },],hobby: [唱, 跳, rap]}},methods: {addSex() {Vue.set(this.girlfriend, sex, 女);},addHeight() {this.$set(this.girlfriend, height, 170);},addFriend() {this.girlfriend.friends.unshift({ id: 003, name: alice, age: 5 }); //有效写法},updateFriend() {this.girlfriend.friends[0].name 张三;},addHobby() {this.girlfriend.hobby.push(打游戏);},updateHobby() {// this.girlfriend.hobby[0] 散步; //无效写法// this.girlfriend.hobby.splice(0, 1, 散步); //有效写法Vue.set(this.girlfriend.hobby, 0, 散步); //有效写法},removeHobby() {// 变更方法顾名思义会变更调用了这些方法的原始数组。相比之下也有非变更方法// 例如 filter()、concat() 和 slice()。它们不会变更原始数组而总是返回一个新数组。// 当使用非变更方法时可以用新数组替换旧数组this.girlfriend.hobby this.girlfriend.hobby.filter((ele) {return ele ! 跳;})}},})
/scriptps今天一个好消息补考过了听懂了 也要再练习一下哦