关于vue的data&props思考

974 阅读3分钟

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属性会被添加为组件实例的属性,并且不具有响应式。