vue2 data methods computed watch面试常见考点

176 阅读2分钟

data

data为什么必须是一个函数

对于根Vue实例,data可以是一个对象,也可以是函数。因为根实例只会被创建一次,不会出现数据冲突的情况。

对于组件,组件可能会被多次使用,那么data必须是一个函数。这样组件每次被使用就会调用一次data函数,返回一个新的对象,开辟了一块新的内存空间,每个组件修改自己的数据不会影响其他的组件。但是对象是引用类型,堆中是对于内存地址的引用,当我们尝试改变data的时候,其他用到这个组件的地方的data也会改变!

举个栗子:比如data={a:1,b:2},变量A、变量B就是一个组件被使用多次的data在内存中的情况,栈中存储对象的地址,数据存在堆内存。

image.png

如果一个修改了另一个也会跟着变,代码如下:

           `let obj = { key: 'value' };
            let a = obj;
            let b = obj;
            a.key = 'new value';
            console.log(b.key); 

` 注意: 根本原因是一个组件可能会被使用多次,如果我每个组件都只使用一次,理论上不会发生数据冲突,因为不同组件的数据是独立的。但是我很难避免一个组件使用一次,所以Vue强制规定,组件中的data必须使用函数!!!根组件无所谓。

methods

这个比较简单,没什么好说的,是一个对象,里面是一个一个的k-v,v是函数。

computed

示例:

             new Vue({
              el: '#app',
              data: {
                a: 1
              },
              computed: {
                b: function () {
                  return this.a + 1
                }
              }
            })
           

计算属性原理:当我们在组件中使用计算属性的时候,Vue会为为该计算属性创建一个watcher,当所依赖的数据发生变化的时候,会触发watcher。dep会通知watcher,执行计算属性中的回调函数,和响应式原理差不多。

何时触发computed中的回调函数

1.Vue组件实例化的时候,即模板第一次渲染时。

2.所依赖的数据发生变化时。因为计算属性有缓存,如果数据没有发生变化,就不会重新计算,缓存在哪里呢?watcher实例里面。

watch

             new Vue({
              el: '#app',
              data: {
                message: 'Hello Vue!'
              },
              watch: {
                message: function (newVal, oldVal) {
                  console.log('message changed from', oldVal, 'to', newVal)
                }
              }
            })

watch原理:跟computed差不多,就是创建一个watcher实例,监听数据的变化,dep去通知watcher去执行相应的回调函数。

两者区别

1.watch没有缓存,computed有缓存。

2.使用场景不同:computed用于拿着data或者props的数据去计算得到一个新的数据,我们不需要关心里面的细节,Vue帮我们搞定。watch通过监听某些数据并在数据源发生变化的时候来进行一些“副作用”(回调函数操作)。