系列文章:
- Vue源码解读(设计篇)
- Vue源码解读(Rollup篇)
- Vue源码解读(入口到构造函数整体流程)
- Vue源码解读(响应式原理介绍和Prop)
methods处理
在分析完props
相关逻辑后,接下来分析与methods
相关的逻辑,这部分相比于props
要简单得多。
在initState()
方法中,调用了initMethods()
并传入了当前实例vm
和撰写的methods
。接下来,看一下initMethods
方法具体的实现:
在以上代码中可以看到,initMethods()
方法实现中最重要的一段代码就是:
它首先判断了定义的methods
是不是function
类型,如果不是则赋值为一个noop
空函数,如果是则把这个方法进行bind
绑定,其中传入的vm
为当前实例。这样做的目的是为了把methods
方法中的this
指向当前实例,这样就能在methods
方法中通过this.xxx
的形式很方便的访问到props
、data
以及computed
等与实例相关的属性或方法。
在开发环境下,它还做了如下几种判断:
- 必须为
function
类型。
- 命名不能和
props
冲突。
- 命名不能和已有的实例方法冲突。
在分析完以上initMethods
流程后,能得到如下流程图:
data处理
Vue
中关于data
的处理,根实例和子组件有一点点区别,接下来着重分析子组件中关于data
的处理过程。
在以上代码中,首先判断了opts.data
,如果值为true
则代表是子组件(子组件如果没有显示定义data
,则使用默认值),否则代表是根实例。对于根实例而言不需要执行initData
的过程,只要对vm._data
进行observe
即可。
接下来,详细分析initData
的过程,它是定义在src/core/instance/state.js
文件中的一个方法:
虽然initData()
方法的代码有点长,但详细观察后可以发现,其主要做的就是四件事情:类型判断取值、命名冲突判断、proxy代理以及observe(data)。
然后,分别对以上几块进行详细解释:
- 类型判断取值:对于子组件而言,由于组件可以多次复用,因此函数必须通过工厂函数模式返回一个对象,这样在组件多次复用时就能避免引用类型的问题。
对于data
是一个函数的情况,调用getData
方法来取值,getData
方法定义如下:
代码分析:pushTarget
是一个与响应式依赖收集有关的,会在后续进行详细说明。getData
的取值过程包裹在try/catch
中,通过data.call(vm, vm)
进行调用返回,如果函数调用出错,则使用handleError
进行错误统一处理。
- 命名冲突判断:由于
props
和methods
有更高的优先级,因此data
属性的命名不能和props
、methods
中的命名冲突,因为无论是props
、methods
还是data
最后都会反映在实例上。另外一种命名冲突,是不能以$
或者_
开头,因为这样很容易和实例私有方法、属性或对外暴露以$
开头的方法、属性冲突。
- proxy代理:在之前已经介绍过
proxy
代理的作用,也讲过proxy
代理_props
的例子,这里代理_data
跟代理_props
是同样的道理。
- observe(data):
observe
的作用是把传入值所有的属性(包括嵌套属性)递归的进行响应式defineReactive
,会在之后的章节中详细介绍observe
的实现原理,在initData
中只要知道observe(data)
会把data
函数返回对象的所有属性全部变成响应式的即可。
在分析完initData
的实现后,可以得到initData
的整体流程图。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!