vue源码剖析系列之相应式数据(一)

概述

在运用vue的时刻,data,computed,watch是一些常常用到的观点,那末他们是怎样完成的呢,让我们从一个小demo最先剖析一下它的流程。

demo演示代码片断

html代码

<!DOCTYPE html>
<html>
  <head>
    <title>demo</title>
    <script src="../../dist/vue.js"></script>
  </head>
  <body>
    <div id="demo">
      <div>
          <p>a:{{a}}</p>
          <p>b: {{b}}</p>
          <p>a+b: {{total}}</p>
          <button @click="addA">a+1</button>
      </div>
    </div>
    <script src="app.js"></script>
  </body>
</html>

js代码

var demo = new Vue({
  el: '#demo', 
  data: {
    a: 1,
    b: 2,
  },
  computed:{
    total() {
      return this.a + this.b;
    }
  },
  methods: {
    addA() {
      this.a += 1;
    }
  }
})

简朴申明

这是一段简朴的代码。页面中引用了data中的a,b属性,盘算属性total则是求a与b的和。页面中供应一个button按钮,每点击一次会对属性a+1。total属性则会依据依靠变化,推断total值是不是须要更新,并在适宜的机遇更新。

代码初始化部份

new一个Vue的时刻做了什么

当我们new一个vue时,实际上执行了vue的组织函数,这个组织函数内部挂载了许多要领,能够在我的上一篇文章中看到。组织函数内部挪用了_init要领,那我们看看init里做了什么即可。

function Vue (options) {
  this._init(options)
}

init函数

Vue.prototype._init = function (options?: Object) {
  const vm: Component = this
  // a uid
  vm._uid = uid++

  // 经由过程_isVue标识该对象不须要被做相应式处置惩罚。
  vm._isVue = true
  // 兼并组织函数上挂载的options与当前传入的options.
  if (options && options._isComponent) {
    initInternalComponent(vm, options)
  } else {
    vm.$options = mergeOptions(
      resolveConstructorOptions(vm.constructor),
      options || {},
      vm
    )
  }
  // 非生产环境,包装实例自身,在后期衬着时刻,做一些校验提醒输出。
  if (process.env.NODE_ENV !== 'production') {
    initProxy(vm)
  } else {
    vm._renderProxy = vm
  }
  // expose real self
  vm._self = vm
  // 初始化生命周期相干
  initLifecycle(vm)
  // 初始化事宜相干
  initEvents(vm)
  // 初始化衬着相干
  initRender(vm)
  // 这里挪用beforeCreate钩子
  callHook(vm, 'beforeCreate')
  // inject/provide相干处置惩罚
  initInjections(vm) // resolve injections before data/props
  // 初始化data、props以及computed,watch等。
  initState(vm)
  initProvide(vm) // resolve provide after data/props
  // 挪用created钩子
  callHook(vm, 'created')


  if (vm.$options.el) {
    // 挂载组件到页面上的
    vm.$mount(vm.$options.el)
  }
}

这篇文章报告的内容,须要我们偏重关注一下initState函数与vm.$mount中衬着部份的内容。

initState函数

export function initState (vm: Component) {

  vm._watchers = []
  const opts = vm.$options
  //初始化props
  if (opts.props) initProps(vm, opts.props)
  // 初始化methods
  if (opts.methods) initMethods(vm, opts.methods)
  // 初始化data
  if (opts.data) {
    initData(vm)
  } else {
    observe(vm._data = {}, true /* asRootData */)
  }
  // 初始化盘算属性
  if (opts.computed) initComputed(vm, opts.computed)
  // 初始化watch
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }
}

接下里的几篇我们将围绕着initData,initComputed,initWatch函数,离别睁开,探讨其内部做了什么。

文章链接

    原文作者:A_大白
    原文地址: https://segmentfault.com/a/1190000018145146
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞