Vue初始化
Vue上面的函数怎么来的
vue的打包路径
- 在web中使用的vue打包路径:
npm run build
打包生成vue.js - 下面是依次引入:
- src/platforms/web/entry-runtime-with-compiler.js
- src/platforms/web/runtime/index.js
- src/core/index.js
- src/core/instance/index.js
instance/index.js
- 这个js文件就是Vue本身了
- 首先这是一个构造函数, 然后在执行
new
的时候, 会执行一个this._init
函数 - 导出这个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) {
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)
}
initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
export default Vue
initMixin
- 主要就是挂载了_init方法, 这是最关键的.
stateMixin
- $set
- $delete
- $watch
eventsMixin
- $on
- $once
- $off
- emit
lifecycleMixin
- $_update
- $forceUpdate
- $destroy
renderMixin
- $nextTick
- _render
$mount
- 在
src/platforms/web/runtime/index.js
进行挂载. - 这里引入了
/src/core/instance/lifecycle.js
中的mountComponent
函数
new vue
都干了什么
在这里就执行了一个_init函数
总览函数, 逐个分析
Vue.prototype._init = function (options?: Object) {
const vm: Component = this
// a uid
vm._uid = uid++
let startTag, endTag
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
startTag = `vue-perf-start:${vm._uid}`
endTag = `vue-perf-end:${vm._uid}`
mark(startTag)
}
// a flag to avoid this being observed
vm._isVue = true
// merge options
if (options && options._isComponent) {
// optimize internal component instantiation
// since dynamic options merging is pretty slow, and none of the
// internal component options needs special treatment.
initInternalComponent(vm, options)
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}
/* istanbul ignore else */
if (process.env.NODE_ENV !== 'production') {
initProxy(vm)
} else {
vm._renderProxy = vm
}
// expose real self
vm._self = vm
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
vm._name = formatComponentName(vm, false)
mark(endTag)
measure(`vue ${vm._name} init`, startTag, endTag)
}
if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
}
initLifecycle
- 初始化各种状态
export function initLifecycle (vm: Component) {
const options = vm.$options
// locate first non-abstract parent
let parent = options.parent
if (parent && !options.abstract) {
// 不断向下深复制所有的parent, 找到最终元素,
while (parent.$options.abstract && parent.$parent) {
parent = parent.$parent
}
parent.$children.push(vm)
}
// 确定该组件的状态, 初始化一些需要东西
vm.$parent = parent
vm.$root = parent ? parent.$root : vm
vm.$children = []
vm.$refs = {}
vm._watcher = null
vm._inactive = null
vm._directInactive = false
vm._isMounted = false
vm._isDestroyed = false
vm._isBeingDestroyed = false
}
initEvents
- 初始化事件, 尤其是events, 还有一个listenners.
export function initEvents (vm: Component) {
vm._events = Object.create(null)
vm._hasHookEvent = false
// init parent attached events
const listeners = vm.$options._parentListeners
// 更新监听函数什么鬼呢?
if (listeners) {
updateComponentListeners(vm, listeners)
}
}
initRender
export function initRender (vm: Component) {
vm._vnode = null // the root of the child tree
vm._staticTrees = null // v-once cached trees
const options = vm.$options
const parentVnode = vm.$vnode = options._parentVnode // the placeholder node in parent tree
const renderContext = parentVnode && parentVnode.context
vm.$slots = resolveSlots(options._renderChildren, renderContext)
vm.$scopedSlots = emptyObject
// bind the createElement fn to this instance
// so that we get proper render context inside it.
// args order: tag, data, children, normalizationType, alwaysNormalize
// internal version is used by render functions compiled from templates
// 这里的createElement关键, 确定了我们需要页面上需要渲染的函数
vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
// normalization is always applied for the public version, used in
// user-written render functions.
vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)
// todo: 这里还没有搞太懂
// $attrs & $listeners are exposed for easier HOC creation.
// they need to be reactive so that HOCs using them are always updated
const parentData = parentVnode && parentVnode.data
/* istanbul ignore else */
if (process.env.NODE_ENV !== 'production') {
defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, () => {
!isUpdatingChildComponent && warn(`$attrs is readonly.`, vm)
}, true)
defineReactive(vm, '$listeners', options._parentListeners || emptyObject, () => {
!isUpdatingChildComponent && warn(`$listeners is readonly.`, vm)
}, true)
} else {
defineReactive(vm, '$attrs', parentData && parentData.attrs || emptyObject, null, true)
defineReactive(vm, '$listeners', options._parentListeners || emptyObject, null, true)
}
}
这个时候, 调用钩子函数beforeCreate钩子
initInjections
- 这是一个高级用法, 在初识话data和prop之前, 来设置一些应该设置的值
- 好吧, 还没有深入
initState
- 关键步骤:
- props
- methods
- data
- computed
- watcher
export function initState (vm: Component) {
vm._watchers = []
const opts = vm.$options
if (opts.props) initProps(vm, opts.props)
if (opts.methods) initMethods(vm, opts.methods)
if (opts.data) {
initData(vm)
} else {
observe(vm._data = {}, true /* asRootData */)
}
if (opts.computed) initComputed(vm, opts.computed)
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch)
}
}
initProvide
- 在初识完一系列的data, 和prop之后执行调用, 需要深入
调用created
函数
mount
- 如果存在options.el上面的el, 那么就会调用, mount函数
- 这个函数指的就是在
mountComponent
函数.
这时候, 调用beforeMount
在mount中
- 开始执行一系列的update和render函数
- 执行结束后, 执行mounted, 这个时候, 这个组件就算渲染完成了.
疑问
- 如果在一个父组件中有两个子组件, 那么这个两个组件生命周期的执行顺序是什么?
- 需要深入的还很多啊, 看了很多的文章, 杜宇Dep, Watcher, Observer的关系还是没这么清楚
- 还有就是vue在初识化的过程中做了很多不知道的操作
Vue初始化的更多相关文章
- vscode 用户代码片段 vue初始化模板 Snippet #新加入开头注释 自动生成文件名 开发日期时间等内容
vue文件模板 模板变量 https://code.visualstudio.com/docs/editor/userdefinedsnippets#_variables vue.json { // ...
- Vue初始化过程
用vue也有一两年了,始终对vue一知半解,不怎么了解内部的执行过程,最近在看vue源码,还是不少收获的,其中不乏浏览器事件轮询机制.闭包.设计模式等,还是非常值得一读.本篇简要记录下vue的初始化过 ...
- 无法执行vue初始化命令
无法执行vue初始化命令:https://www.jianshu.com/p/9eb3cf854aa8 今天vue 初始化项目时提示错误 执行命令: npm install -g vue-cli 执行 ...
- vue初始化页面闪动问题
使用vue开发时,在vue初始化之前,由于div是不归vue管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于{{message}}的字样,虽然一般情况下这个时间很短暂,但是我们 ...
- Vue.js源码解析-Vue初始化流程
目录 前言 1. 初始化流程概述图.代码流程图 1.1 初始化流程概述 1.2 初始化代码执行流程图 2. 初始化相关代码分析 2.1 initGlobalAPI(Vue) 初始化Vue的全局静态AP ...
- Vue.js源码解析-Vue初始化流程之动态创建DOM
目录 前言 一._update 如何判断是初始化还是更新操作? 二.patch 2.1 patch 定义 2.2 初始化的 patch 三.createElm 动态创建DOM 3.1 创建组件节点 3 ...
- vue 2.0源码学习笔记—new Vue ( Vue 初始化过程 )
new Vue(Vue 初始化) 一个vue实例化到底经历了什么?已下是博主自己的总结,不正确的地方请指出,谢谢~ 一.简述 从使用角度来看,挂载的顺序如下 1. $slots 2. $scopedS ...
- Vue 源码解读(2)—— Vue 初始化过程
当学习成为了习惯,知识也就变成了常识. 感谢各位的 点赞.收藏和评论. 新视频和文章会第一时间在微信公众号发送,欢迎关注:李永宁lyn 文章已收录到 github 仓库 liyongning/blog ...
- vue初始化项目,构建vuex的后台管理项目架子
构架vuex的后台管理项目源码:https://github.com/saucxs/structure-admin-web 一.node安装 可以参考这篇文章http://www.mwcxs.top/ ...
- Vue 初始化多个Vue 及之间的相互修改
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
随机推荐
- Long转换为date
public static void main(String[] args) { Long time = System.currentTimeMillis(); System.out.println( ...
- 网页中的title中设置图标
每个网页中title旁边的图标是怎么实现的呢?像这个百度的图标,今天做了一下,很简单,下面记录一下. 做一个图片,一般的图标都可以,把图标后缀改为.ico格式就OK了,放在项目路径下,保证该图片可以被 ...
- 数据结构之 线性表---单链表操作A (删除链表中的指定元素)
数据结构上机测试2-1:单链表操作A Time Limit: 1000MS Memory limit: 4096K 题目描述 输入n个整数,先按照数据输入的顺序建立一个带头结点的单链表,再输入一个数据 ...
- codeforces B. Ping-Pong (Easy Version) 解题报告
题目链接:http://codeforces.com/problemset/problem/320/B 题目意思:有两种操作:"1 x y" (x < y) 和 " ...
- 简单使用FusionCharts(Free)
介绍 FusionCharts Free 是一个跨平台,跨浏览器的flash图表组件解决方案,能够被 ASP.NET, ASP, PHP, JSP, ColdFusion, Ruby on Rails ...
- 我的CSDN博客
从csdn搬过来的: csdn地址:http://blog.csdn.net/WR_technology
- MSTAR GUI
1.架构 WIN32 SDK ACT->CTL->API->GE/GOP ACT: Customized logic parts CTL: Behavior widgets API: ...
- HDU2222(AC自动机入门题)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- 64位windows7下安装python,配置numpy和matplotlib库
一.Python的安装 1.下载python2.7,下载地址:http://www.python.org/,选择系统相应版本,我选择是的是python2.7.6 . python-2.7.6rc1.a ...
- Console Event Handling
http://www.codeproject.com/Articles/2357/Console-Event-Handling Console Event Handling Kumar Gaurav ...