data和props响应式理解
理论层面
结论:data和props都是响应式的。
理解:
data:data中的数据是响应式,这个就不解释了;
props:props为什么是响应式,因为props是将从父组件的data传递过来的,父组件的data数据是响应式的,所以子组件的props中的数据是响应式;这里要注意的是传入到props的是值传递还是引用传递;其次是不建议子组件直接修改props,具体解释可以参考官网。// todo有待验证,后续补充
借助浏览器循环渲染问题理解响应式
在vue中,如果在模板中调用方法fun,并且在fun方法中更改data的响应式变量,那么就会触发render渲染。
问题: 为什么++this.count
会触发浏览器死循环render呢?
因为++this.count
每次的值都不一样,一直被修改,所以就会一直render
问题: 为什么this.count = 5
没有造成重复render呢?
因为this.count
并不是每次都变化,this.count
一直是5,所以dom diff的时候发现跟之前的值一样没变化,就不会再进行渲染了。
++this.count的触发的浏览器死循环渲染结果如下:
data和props
data:在vue组件初始化时在data中的变量就是默认是响应式的,这些是data的初始数据,后面如果增加变量属性,则不具有响应式,需要手动set使其具有响应式。
props:// todo
this.$data和this.$options.data()
1. options.data()和data
1. this.$data: 保存的是组件的实时最新的data属性对象
2. this.$options.data(): 保存的时组件初始化时所具有的data最开始的对象以及属性值
2. 思考问题
问题:Object.assign(this, {key: value}) 添加{key: value}对象的属性给this这个组件实例,那么到底是添加给this的data属性中?还是添加到this的props属性中,还是都不是?
// 代码示例结合上下图
Object.assign(instance, { msg: '我是新msg' })
Object.assign(instance, { tttt: 'xxxxx' })
Object.assign(instance, { title: '我是props的新title' })
console.log('instance.$data', instance.$data);
console.log('instance.$props', instance.$props);
console.log('instance.$methods', instance.$methods);
console.log('instance.$options.data()', instance.$options.data());
console.log('instance.$options.props', instance.$options.props);
console.log('instance.$options.methods', instance.$options.methods);
结论:
1. 当添加的属性已经存在data中时:
我们给vue组价实例添加属性xxx时,如果xxx这个属性已经存在于vue实例的data中,那么此时xxx属性的值会直接覆盖掉data中xxx属性的值。
2. 当添加的属性已经存在props中时:
我们给vue组价实例添加属性xxx时,如果xxx这个属性已经存在于vue实例的props中,那么此时xxx属性的值会直接覆盖掉props中xxx属性的值。
3. 当添加的属性不存在于data中,也不存在与于props中时:
我们给vue组价实例添加属性xxx时,如果xxx这个属性不存在于data中,也不存在与于props,那么此时xxx属性会被添加为组件实例的属性,并且不具有响应式。