vue 数据来源是单向的有三种来源
1.来自父组件的属性
2.来自组件自身的状态data
3.来自vuex,Vue.observable
状态和属性的改变未必会触发试图更新

vue 数据变化的追踪
vue 实例化的时候vue对data里的数据处理方式
1.对象:Object.defineProperty 把属性全部转换成getter/setter。
2.数组:通过劫持数组的原始方法,当这些数据调用原生方法时候dep.notify(),通知依赖此数据的视图update()
3.data 里的属性且被模版render使用的数据 会被收集在依赖里面。当数据发生变化即有setter操作通知watcher监控,从而组件模版发生变化这里改变name 和 obj.a,list都是不会引起组件更新的 updated() 不会触发
obj.b 如果被修改了数据会发生变化,但是并不会造成组件的更新 updated() 不会触发
数组push 数组里的数据发生变化了,数组是引用类型,其实数组本身并没有变化
vue初始化未定义的对象不会触发视图的改变
- 已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性。 eg. Vue.set(this.obj, 'b', 2) this.$set(this.obj, 'a', 2)
- 需要为已有对象赋值多个新属性,比如使用 Object.assign() 或 _.extend()。添加到对象上的新属性不会触发更新
// 代替 `Object.assign(this.obj, { a: 1, b: 2 })`
this.obj = Object.assign({}, this.obj, { a: 1, b: 2 })
数组原生的操作方法会触发视图的改变
push() 数组末端添加项
pop() 数组末端删除项
shift() 数组头部添加项
unshift() 数组头部删除项
splice(index, num) 删除,num删除数量
sort() 排序
reverse() 反转
filter()、concat() 和 slice() 可以赋值到愿数据 也会引起视图更新vue不能检测数组变动的情况
1.利用index设置某一项
eg this.list[index] = newval
解决方案
Vue.set(this.list, index, newval)
this.$set(this.list, index, newval)
this.list.splice(index, 1, newval)
2.修改数组长度
eg this.list.length = newLen
解决方案
this.list.splice(newLen)
虽然这两个案例制图没有更新,但是数据是变化的,只是没有通知依赖的视图
3.如果这两种操作数据的方式和数组原生发法一起使用,视图会更新代码示例
<template>
<div>
<div>name = {{name}}</div>
<div>a= {{obj.a}}</div>
<div>c= {{obj.c}}</div>
<div>list = {{list}}</div>
<button @click="handleChangeName">更新name</button>
<button @click="handleChangeObj">更新obj.a</button>
<button @click="handleChangeList">更新list</button>
</div>
</template>
<script>
const name ='hello'
export default {
name: 'App',
data () {
// this.name = name // 1
return {
name: name, // 放在这里就改变了
obj: {
b: '22',
// a: '' // 放在这里就改变了
},
list: [1, 2, 3]
}
},
updated () {
console.log('更新了')
},
methods: {
handleChangeName () {
this.name = 'world'
console.log(this.name)
},
handleChangeObj () {
this.obj.a = 'world'
this.$set(this.obj, 'a', 2)
this.obj = Object.assign({}, this.obj, { c: 1111, d: 2222 })
console.log(this.obj)
},
handleChangeList () {
// this.list.reverse()
// this.list[0] = 0
// console.log(this.list) // 0,2,1
// this.list.reverse()
// this.list[0] = 0
const arr = [7, 8, 9]
this.list = this.list.concat(arr)
console.log(this.list)
}
}
}
</script>