review vue.js 官方文档

一、数组的变异(数组更新)

Vue.js 内部对被观察数组的变异方法 (mutating methods,包括 push() , pop() , shift() , unshift() , splic
e() , sort() 和 reverse() ) 进行了拦截,因此调用这些方法也将自动触发视图更新。

// 以下操作会触发 DOM 更新
demo.items.unshift({ childMsg: 'Baz' })
demo.items.pop()

无论是变异数组或是非变异数组,当数组值改变的时候,地址指针都不会改变。而 vue 是一个以数据驱动的框架,当数组值变化的时候,自然希望依赖于变化数据的视图也触发更新。用过 vue 的小伙伴都知道,当数组改变的时候,视图也更新了。那 vue 帮我们做了什么事情呢,就让我们深入源码一探究竟吧。
// vue 2.6  
// src/core/observer/array.js
const arrayProto = Array.prototype; // 获取数组原型对象
const arrayMethods = Object.create(arrayProto); // 生成一个新对象,且__proto__ 指向 数组原型对象
const methods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];

/**
 * Intercept mutating methods and emit events
 */
methods.forEach(method => {
    const original = arrayProto[method]; 
    let val = function mutator (...args) {
        const result = original.apply(this, args); //缓存原始方法
        let inserted = null;
        switch (method) {
            case 'push':
                inserted = args;
                break;
            case 'unshift':
                inserted = args;
                break;
            case 'splice':
                inserted = args.slice(2); // array.splice(start[, deleteCount[, item1[, item2[, ...]]]]) [item])
                break;
        }
        if (inserted) observeArray(inserted); // 获取插入的值,并设置响应式监听
        notify(); // 通知依赖像更新
        return result;
    }
    
    Object.defineProperty(arrayMethods, method, {
        value: val,
        writable: true,
        configurable: true,
        enumerable: true
    })
})

const observeArray = function observeArray (inserted) { // 简写,[具体实现](https://github.com/vuejs/vue/blob/2.6/src/core/observer/index.js)
    console.log(inserted); //新增的元素形成的数组
    console.log('响应式监听数组');
}

const notify = function notify () {
    console.log('视图更新了');
}

在Vue现有阶段中,对响应式处理利用的是Object.defineProperty对数据进行拦截,而这个方法并不能监听到数组内部变化,数组长度变化,数组的截取变化等,所以我们需要对这些操作进行hack,让vue能监听到其中的变化。

因此,在改变数组的值时不可直接用索引。这些改动是无法被 Vue.js 侦测到的。你应该使用扩展的 $set() 方法

// 不要用 `demo.items[0] = ...`
demo.items.$set(0, { childMsg: 'Changed!'})

$remove() 只是 splice() 方法的语法糖。它将移除给定索引处的元素。当参数不是数值时, $remove() 将在数组中搜索该值并删除第一个发现的对应元素  :

// 删除索引为 0 的元素。
demo.items.$remove(0)

二、自定义指令:

具体这个用的不多,感兴趣的可以了解下别人写的文章。。。

https://www.cnblogs.com/LO-ME/p/7767797.html

http://gitblogs.com/blogs/details?id=53f012d0-02d0-4a98-a64e-2c7f881b8b0a

三、关于对下面这句话的理解(ref/this.$refs)

当 ref 和 v-for 一起使用的时候,你得到的引用将会是一个包含了对应数据源的这些子组件的数组

参考这位大佬的:https://www.jianshu.com/p/6c8c39a7bf14

四、关于v-model

v-model 是语法糖,一般用在表单中数据的双向绑定,也可以用在自定义组件中,比如我们自定义一个select/option 组件。。

参考这位老哥写的文章:https://www.jianshu.com/p/296421704b25  https://www.jianshu.com/p/b3649529bff0

五、为什么要在data中初始化数据:

因为 Vue 是通过递归遍历初始数据中的所有属性,并用 Object.defineProperty 把它们转
化为 getter 和 setter 来实现数据观察的。如果一个属性在实例创建时不存在于初始数据中,那么 Vue 就没有
办法观察这个属性了。

六、关于nextTick ,DOM异步更新机制、宏任务微任务 任务队列、事件循环机制、MutationObserverHTML5 新增属性。。。

参考:https://www.leevii.com/2019/07/vue-nexttick-implementation.html

   https://segmentfault.com/a/1190000012861862?utm_source=tag-newest

     https://www.cnblogs.com/fozero/p/10863667.html

          https://www.jianshu.com/p/5d84815c2555

七、计算属性和watch的区别

计算属性其实和method一样,只不过计算属性是基于缓存机制的 必须有返回值,目的是计算一些复杂的表达式运算。。。watch是侦听器,监听data里的属性值的变化。。。

  • computed 是计算一个新的属性,并将该属性挂载到 vm(Vue 实例)上,而 watch 是监听已经存在且已挂载到 vm 上的数据,所以用 watch 同样可以监听 computed 计算属性的变化(其它还有 dataprops
  • computed 本质是一个惰性求值的观察者,具有缓存性,只有当依赖变化后,第一次访问 computed 属性,才会计算新的值,而 watch 则是当数据发生变化便会调用执行函数
  • 从使用场景上说,computed 适用一个数据被多个数据影响,而 watch 适用一个数据影响多个数据;

参考:https://juejin.im/entry/5b07824651882538a34c1694

   https://juejin.im/post/5ae91fa76fb9a07aa7677543

   https://segmentfault.com/a/1190000012948175

原文地址:https://www.cnblogs.com/jervy/p/12046494.html