您现在的位置是:网站首页> 编程资料编程资料
Vue不能检测到数据变化的几种情况说明_vue.js_
2023-05-24
447人已围观
简介 Vue不能检测到数据变化的几种情况说明_vue.js_
Vue不能检测到数据变化的情况
Vue 实现了数据的双向绑定,所以我们在更改数据时,页面就会实时的反映出修改的变化
但是由于javascript 的限制,有几种情况,vue是不能检测到数据变化的
第一类:对于数组
1. 当你利用索引直接设置一个项时,例如:
vm.items[indexOfItem] = newValue
2. 当你修改数组的长度时,例如:
vm.items.length = newLength
如下例
new Vue({ data(){ return { arr:[ {id:1,name:"haha",age:18}, {id:2,name:"hehe",age:19} ] } } }) ...... methods:{ change(){ this.arr[0] = {id:1,name:"gege",age:30}; //这种写法vue是不能检测到的, 也就是说页面的数据不会改变 this.arr[0].name = "gege"; this.arr[0].age = 30; //这种方式是可以检测到的, 这是更改的数组内部的对象的属性是可以检测到变化的 //也可以使用 vue 提供的方法 this.$set(this.arr,0,{id:1,name:"gege",age:30}) ; //这种方法也是可以的 //还可以使用 vue 的变种函数 this.arr.splice(0,1,{id:1,name:"gege",age:30}); //这里的 splice方法其实已经不是 js 的 splice方法了, 它是被vue 改写过的方法 } }从上面我们可以看到,如果想要通过数组下标修改数组的话,vue 是检测不到数据的变化的,要么使用 $set , splice 等数组的方法,要么就再向组数内部走一级,直接修改内部对象的属性也是可以的
第二类:对于对象
vue 是可以检测到对象中数据发生的改动的,因为初始化的时候 对象的每一个属性 都生成好了 getter 和setter方法,但是我们如果在程序运行过程中 动态的给对象添加新的属性,删除属性,vue 是检测不到的
new Vue({ data(){ return { a:{ b:"c" } } } ...... mehtods:{ changes(){ this.a.bb = "bbbb"; //这种写法是在 a 对象上面添加了一个 bb 的属性, vue 是检测不到的 //所以这种情况下, 我们要使用 $set this.$set(this.a,"bb","bbbbb"); //这样就可以解决问题, } } })上面只写了添加对象属性时的情况,删除对象的属性时,1.也可使用 $set
有时你可能需要为已有对象赋予多个新属性,比如使用 Object.assign() 或 _.extend()。在这种情况下,你应该用两个对象的属性创建一个新的对象。所以,如果你想添加新的响应式属性,不要像这样:
Object.assign(vm.userProfile, { age: 27, favoriteColor: ‘Vue Green' })你应该这样做:
vm.userProfile = Object.assign({}, vm.userProfile, { age: 27, favoriteColor: ‘Vue Green' })Vue检测数据的原理
一个简单的例子,总结一下vue监测数据
学生信息
姓名:{{student.name}}
性别:{{student.sex}}
爱好:
- {{h}}
朋友们:
- {{f.name}} -- {{f.age}}
const app = new Vue({ el: "#app", data: { student: { name: "AIpoem", hobby: ["抽烟","喝酒","烫头"], friends: [ {name: "jerry",age: 18}, {name: "Cici",age:19} ] } }, methods: { addSex() { // this.student.sex = "男" 不是响应式 this.$set(this.student,"sex","男"); }, changeSex() { // 直接改即可,因为上面添加的sex属性为响应式 this.student.sex='女' }, unshiftFriend() { this.student.friends.unshift({name:"newFriend",age:20}); }, changeFriendName() { // 这里直接改即可,name属性是响应式的 this.student.friends[0].name = "张三"; }, addHobby() { this.student.hobby.push("新爱好"); }, changeHobby() { // this.student.hobby[0] = "开车" 不是响应式 this.student.hobby.splice(0,1,"开车"); } } }) 关于vue监视对象:
直接添加的sex属性,没有getter和setter,无法实现响应式

利用Vue.set()添加的sex属性,有getter和setter,可以实现响应式

另一种写法,和上面作用一样

关于vue监视数组:

比如这个例子,一开始页面是抽烟和喝酒,button绑定的点击事件中的语句是this.student.hobby[0] = "学习";,之后再输出app.student.hobby,可以发现数据确实已经改变,但是页面是没有相应变化的,因为这样通过数组下标来改变数据的方式,vue监测不到
正确写法:this.student.hobby.splice(0,1,"学习");

总结一下
1.vue会监视data中所有层次的数据
vue监视的数据都是响应式的
2.如何监测对象中的数据
通过setter实现监视,且要在new Vue时就传入要监测的数据
(1).对象中后追加的属性,Vue默认不做响应式处理
(2).如需给后添加的属性做响应式处理
Vue.set(target, propertyName/index, value)
或
app.$set(target, propertyName/index, value)
3.如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质上就是做了两件事:
- 1.调用原生对应的方法对数组进行更新(push()、pop()、、、)
- 2.重新解析模版,进而更新页面
4.在Vue中修改数组中的某个元素一定要用如下方法:
- 1.使用这些API: push()、pop()、shift()、unshift()、splice()、sort()、reverse() 注意:以上为变更方法,会变更调用了这些方法的原始数组。也有非变更方法,例如filter()、concat()和slice(),它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组直接替换旧数组
- 2.Vue.set()或app.$set()
特别注意:Vue.set()和app.$set()不能给app或者app的根数据对象(app._data)添加属性
(target参数不可以是app或者app._data)
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
相关内容
- JS开发前端团队展示控制器来为成员引流_JavaScript_
- Vue Router嵌套路由(children)的用法小结_vue.js_
- package.json与package-lock.json的区别及详细解释_javascript技巧_
- vue watch中如何获取this.$refs.xxx节点_vue.js_
- JS实现页面炫酷的时钟特效示例_JavaScript_
- node.js 实现手机号验证码登录功能_node.js_
- vite前端构建Turborepo高性能monorepo方案_vue.js_
- vue里的axios如何获取本地json数据_vue.js_
- vue项目及axios请求获取数据方式_vue.js_
- 详解React 的数据流和生命周期_React_
