Vue 源码阅读(五)响应式实现

说明

  • Vue 版本:2.5.13

正文

先来看看 Vue 的配置,以组件为例this

{
    render(h) {
        
    },
    props: {
        props1: Number
    },
    data() {
        return {
            data1: 1,
            data2: 0
        }
    },
    computed: {
        computed1() {
            return this.data1 +  this.props1
        }
    },
    watch: {
        computed1(newValue) {
            setTimeout(()=>{
                console.log(newValue)
            },0)
        }
    }
}

响应式实现过程大概能够分为三块:lua

数据 Data

初始化 data、props、computed 时(初始化 render 时还有一些其余内置属性),经过 Object.defineProperty 将属性定义成 getset,并为每一个属性绑定一个 Dep 实例。code

详见 src/core/instance/state.jsinitDatainitPropsget

组件 Component

能够把整个 Vue 应用认为是大大小小的组件堆砌而成。Vue 为每一个组件都定义了两块重要的内容:Watcher 和 Render。it

执行 $mount 时调用 mountComponent、初始化 watch、computed时、调用实例方法 $watch时,都会给实例化一个 Watcher。而 Watcher 初始化时会进行一次求值(执行实例中的 getter 方法),首先会将当前实例设置为 Dep 当前目标,而后触发数据的相关属性的 get 方法。console

详见 src/core/instance/state.jsinitComputedinitWatchclass

依赖 Dep

Dep 类就是用来关联数据与组件的 Watcher 的。响应式

// the current target watcher being evaluated.
// this is globally unique because there could be only one
// watcher being evaluated at any time.
Dep.target = null

其实初始化 Watcher 时,经过执行了对应属性的 get 方法,将Watcher 实例放入数据对应的 Dep 实例的订阅列表中。而当数据发生变化时,对应属性执行 set 方法,会通知到对应的 Dep 实例,再通知订阅列表中的 Watcher。配置

此时,Watcher 将通知组件执行 Render,从新计算出新的 VNode,经过新旧 VNode 的对比,进行视图更新。方法

相关文章
相关标签/搜索