资讯专栏INFORMATION COLUMN

vue源码分析系列之响应式数据(一)

liujs / 1082人阅读

摘要:代码初始化部分一个的时候做了什么当我们一个时,实际上执行了的构造函数,这个构造函数内部挂载了很多方法,可以在我的上一篇文章中看到。合并构造函数上挂载的与当前传入的非生产环境,包装实例本身,在后期渲染时候,做一些校验提示输出。

概述

在使用vue的时候,data,computed,watch是一些经常用到的概念,那么他们是怎么实现的呢,让我们从一个小demo开始分析一下它的流程。

demo演示代码片段 html代码


  
    demo
    
  
  
    

a:{{a}}

b: {{b}}

a+b: {{total}}

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函数,分别展开,探究其内部做了什么。

文章链接

vue源码分析系列

vue源码分析系列之debug环境搭建

vue源码分析系列之入口文件分析

vue源码分析系列之响应式数据(二)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101648.html

相关文章

  • vue源码分析系列响应数据(四)

    摘要:执行当时传入的回调,并将新值与旧值一并传入。文章链接源码分析系列源码分析系列之环境搭建源码分析系列之入口文件分析源码分析系列之响应式数据一源码分析系列之响应式数据二源码分析系列之响应式数据三 前言 上一节着重讲述了initComputed中的代码,以及数据是如何从computed中到视图层的,以及data修改后如何作用于computed。这一节主要记录initWatcher中的内容。 ...

    GHOST_349178 评论0 收藏0
  • vue源码分析系列入debug环境搭建

    摘要:目标是为了可以调试版本的,也就是下的源码,所以主要是的开启。结语至此就可以开心的研究源码啦。文章链接源码分析系列源码分析系列之入口文件分析源码分析系列之响应式数据一源码分析系列之响应式数据二 概述 为了探究vue的本质,所以想debug一下源码,但是怎么开始是个问题,于是有了这样一篇记录。目标是为了可以调试es6版本的,也就是src下的源码,所以主要是sourceMap的开启。原文来自...

    nihao 评论0 收藏0
  • vue源码分析系列入口文件分析

    摘要:中引入了中的中引入了中的中,定义了的构造函数中的原型上挂载了方法,用来做初始化原型上挂载的属性描述符,返回原型上挂载的属性描述符返回原型上挂载与方法,用来为对象新增删除响应式属性原型上挂载方法原型上挂载事件相关的方法。 入口寻找 入口platforms/web/entry-runtime-with-compiler中import了./runtime/index导出的vue。 ./r...

    kgbook 评论0 收藏0
  • vue源码分析系列

    摘要:本系列文章旨在化繁为简,通读源码,描述背后的实现逻辑。记录方式主要是代码注释文章链接源码分析系列之环境搭建源码分析系列之入口文件分析源码分析系列之响应式数据一源码分析系列之响应式数据二 概述 在使用vue的时候,会遇到很多神奇的地方,比如 修改vue实例中data对象的属性值,会触发dom值的改变;改变dom中的输入,会触发data对应属性的改变,即双向数据绑定。 通过watch可以...

    Joonas 评论0 收藏0
  • vue源码分析系列响应数据(二)

    摘要:巴拉巴拉省略大法,去除无关代码巴拉巴拉省略大法,去除无关代码核心就这一句话。文章链接源码分析系列源码分析系列之环境搭建源码分析系列之入口文件分析源码分析系列之响应式数据一 前言 接着上一篇的初始化部分,我们细看initData中做了什么。 正文 initData function initData (vm: Component) { let data = vm.$options.d...

    CKJOKER 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<