Vue源码学习二 ———— Vue原型对象包装
Vue原型对象的包装
在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式。在使用前都通过 new Vue({})。记录一下 Vue构造函数的包装。
在 src/core/instance/index.js 这个文件是 Vue构造函数的出生地。
import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '../util/index'
function Vue (options) {
// 使用安全模式来提醒要使用new操作符来调用Vue
if (process.env.NODE_ENV !== 'production' &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword')
}
this._init(options)
}
/**
* 在执行npm run dev构建运行时执行, 包装Vue.prototype。为其添加一些属性和方法
*/
initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
export default Vue
首先导入了五个方法
- initMixin
- stateMixin
- renderMixin
- eventsMixin
- lifecycleMixin
如果不是在生产环境下,且不通过 new 来调用Vue 会得到警告。
接下来执行 initMixin方法, 到 initMixin来源文件看。
export function initMixin (Vue: Class<Component>) {
Vue.prototype._init = function (){}
}
首先会在 Vue这个构造函数的原型对象上定义一个 _init方法。这个方法是在通过 new Vue({})的时候执行。在 Vue 构造函数中可以看到 this._init(options)。
接着将 Vue构造函数作为参数传递给下一个 stateMixin方法, 到stateMixin来源文件看。
export function stateMixin (Vue: Class<Component>) {
// flow somehow has problems with directly declared definition object
// when using Object.defineProperty, so we have to procedurally build up
// the object here.
const dataDef = {}
dataDef.get = function () { return this._data }
const propsDef = {}
propsDef.get = function () { return this._props }
// 设置两个只读的属性 $data $props
if (process.env.NODE_ENV !== 'production') {
dataDef.set = function () {
warn(
'Avoid replacing instance root $data. ' +
'Use nested data properties instead.',
this
)
}
propsDef.set = function () {
warn(`$props is readonly.`, this)
}
}
Object.defineProperty(Vue.prototype, '$data', dataDef)
Object.defineProperty(Vue.prototype, '$props', propsDef)
Vue.prototype.$set = set
Vue.prototype.$delete = del
Vue.prototype.$watch = function (){}
}
其中
Object.defineProperty(Vue.prototype, '$data', dataDef)
Object.defineProperty(Vue.prototype, '$props', propsDef)
这是在 Vue的原型对象上定义了两个属性 $data 和 $props。其中分别代理了 _data 和 _props。看 dataDef 这个对象上定义了一个 get 方法, 最终返回当前实例对象的 _data。props 也是这样子的。
if (process.env.NODE_ENV !== 'production') {
dataDef.set = function () {
warn(
'Avoid replacing instance root $data. ' +
'Use nested data properties instead.',
this
)
}
propsDef.set = function () {
warn(`$props is readonly.`, this)
}
}
当你在非生产环境时, 如果修改 $data 和 $props会得到警告信息。
最后在 Vue.prototype上还定义了 $set、$delete以及 $watch。。
接下来是 eventMixin方法, 进入这个方法的来源文件
export function eventsMixin (Vue: Class<Component>) {
Vue.prototype.$on = function(){};
Vue.prototype.$once = function(){};
Vue.prototype.$off = function(){};
}
又再 Vue.prototype 上定义了三个方法, 分别是 $on、$once和$off。
接下来执行 lifecycleMixin 方法, 看lifecycleMixin方法的来源文件:
export function lifecycleMixin (Vue: Class<Component>) {
Vue.prototype._update = function() {}
Vue.prototype.$forceUpdate = function() {}
Vue.prototype.$destroy = function(){}
在 lifecycleMixin 方法中又向 Vue的原型对象 prototype上添加了三个方法。分别是 _update、$$forceUpdate和$$destroy。
$forceUpdate: 迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。
最后一个执行 renderMixin方法。在renderMixin来源文件可以到。
首先执行了一个 installRenderHelpers(Vue.prototype),这个方法的主要作用也是向 Vue.prototype上添加方法, 看它源文件是:
// 这个函数主要在Vue.prototype上面添加一些方法
export function installRenderHelpers (target: any) {
target._o = markOnce
target._n = toNumber
target._s = toString
target._l = renderList
target._t = renderSlot
target._q = looseEqual
target._i = looseIndexOf
target._m = renderStatic
target._f = resolveFilter
target._k = checkKeyCodes
target._b = bindObjectProps
target._v = createTextVNode
target._e = createEmptyVNode
target._u = resolveScopedSlots
target._g = bindObjectListeners
}
紧接着又向 Vue.prototype对象上添加了 $nextTick和_render方法。
export function renderMixin (Vue: Class<Component>) {
// install runtime convenience helpers
installRenderHelpers(Vue.prototype)
Vue.prototype.$nextTick = function (fn: Function) {
return nextTick(fn, this)
}
Vue.prototype._render = function (): VNode {}
执行完 renderMixin这个方法, Vue构造函数的出生文件也运行完了。也就是指在 npm run dev命令构建时运行。这里的每一个方法 *Mixin的作用就是包装 Vue.prototype, 对其挂载一些属性和方法。最后 export default Vue将其导出这个构造函数。此时 Vue.prototype上添加的属性和方法有这些。
然后在哪里用到了呢。在 src/core/index.js中导入了Vue的出生文件。看Vue源码学习三 ———— Vue构造函数包装
Vue源码学习二 ———— Vue原型对象包装的更多相关文章
- Vue源码学习1——Vue构造函数
Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...
- Vue源码学习三 ———— Vue构造函数包装
Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...
- Vue源码分析(二) : Vue实例挂载
Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...
- vue 源码学习二 实例初始化和挂载过程
vue 入口 从vue的构建过程可以知道,web环境下,入口文件在 src/platforms/web/entry-runtime-with-compiler.js(以Runtime + Compil ...
- vue 源码学习三 vue中如何生成虚拟DOM
vm._render 生成虚拟dom 我们知道在挂载过程中, $mount 会调用 vm._update和vm._render 方法,vm._updata是负责把VNode渲染成真正的DOM,vm._ ...
- Vue源码学习一 ———— Vue项目目录
Vue 目录结构 可以在 github 上通过这款 Chrome 插件 octotree 查看Vue的文件目录.也可以克隆到本地.. Vue 是如何规划目录的 scripts ------------ ...
- Vue源码学习(二)$mount() 后的做的事(1)
Vue实例初始化完成后,启动加载($mount)模块数据. (一)Vue$3.protype.$mount 标红的函数 compileToFunctions 过于复杂,主要是生 ...
- 手牵手,从零学习Vue源码 系列二(变化侦测篇)
系列文章: 手牵手,从零学习Vue源码 系列一(前言-目录篇) 手牵手,从零学习Vue源码 系列二(变化侦测篇) 陆续更新中... 预计八月中旬更新完毕. 1 概述 Vue最大的特点之一就是数据驱动视 ...
- 【Vue源码学习】依赖收集
前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...
随机推荐
- thinkphp5.1页面页面模板及参数配置
success和error跳转的模板在thinkphp/tpl/dispatch_jump.tpl 配置参数在thinkphp\library\traits\controller\jump.php文件 ...
- EcmaScript内置对象的属性与方法
- 牛客假日团队赛1 D.Promotion Counting
链接: https://ac.nowcoder.com/acm/contest/918/D 题意: Bessie the cow is helping Farmer John run the USA ...
- win10系统添加照片查看器(win7版)
很多人不习惯win10的照片查看器,还是比较怀念win7版本的照片查看器,通过以下两种方法可以在win10图片上点击右键时,"打开方式"中重现"Windows照片查看器& ...
- Maven的安装以及介绍
附录:带阿里源的maven用户设置文件-settings.xml <?xml version="1.0" encoding="UTF-8"?> &l ...
- SpringBoot | 番外:使用小技巧合集
前言 最近工作比较忙,事情也比较多.加班回到家都十点多了,洗个澡就想睡觉了.所以为了不断更太多天,偷懒写个小技巧合集吧.之后有时间都会进行文章更新的.原创不易,码字不易,还希望大家多多支持!话不多说, ...
- Get和Post的请求
get post请求 <form method="post","get", action="a.ashx"> <input ...
- Spring MVC的测试
测试是保证软件质量的关键. 与 Spring MVC 相关的测试,主要涉及控制器的测试. 为了测试Web项目通常不需要启动项目,需要一些Servlet相关的一些模拟对象,比如MockMVC.MockH ...
- aar、jar、so的引入和aar打包包含so、aar、jar文件
so依赖 1,先建本地仓库,指向so放置的目录
- meterpreter > migrate 1548
1548 1500 explorer.exe x86 0 LIXIULI-VCS86VR\test C:\WINDOWS\Explorer.EXE 19 ...