|
1. Vue 实例创建和挂载的过程概述
Vue 实例的挂载过程涉及多个关键步骤,包括创建实例、编译模板、初始化数据和事件绑定等。它的核心流程大致如下:
- 初始化 Vue 实例:在调用时,Vue 实例会创建并初始化相关的属性,如、、等。
- 初始化生命周期:Vue 会初始化生命周期钩子,包括、、、等。
- 编译模板:Vue 会解析传入的模板,生成虚拟 DOM(VNode)。
- 渲染:将虚拟 DOM 转换为真实的 DOM,最终将 Vue 实例挂载到指定的 DOM 节点上。
- 更新:在响应式数据变化时,Vue 会触发更新,重新渲染组件。
2. 分析源码:Vue 实例的创建与挂载过程
我们从 Vue 2.x 的源码分析 Vue 实例的挂载过程。以下是大致的分析步骤。
2.1 Vue 实例的构建函数
首先,我们来看 Vue 的构建函数,它通常是通过来实例化 Vue 对象的。对象包含了组件的配置项,比如、、等。- 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);
- }
复制代码 在构造函数中,调用了,也就是实例化时 Vue 会调用内部的方法进行初始化。
2.2 Vue 的 _init 方法
- Vue.prototype._init = function (options) {
- const vm = this;
- vm._uid = uid$1++; // 生成唯一 ID
- vm._isVue = true; // 标记 Vue 实例
- vm.$options = mergeOptions(
- resolveConstructorOptions(vm.constructor),
- options || {}
- ); // 合并构造函数默认选项和用户传入的选项
- vm._renderProxy = vm; // 渲染代理
- vm._self = vm; // 指向自己
- initLifecycle(vm); // 初始化生命周期
- initEvents(vm); // 初始化事件
- initRender(vm); // 初始化渲染
- callHook(vm, 'beforeCreate'); // 调用生命周期钩子 beforeCreate
- initState(vm); // 初始化数据、计算属性等
- initInjections(vm); // 处理依赖注入
- callHook(vm, 'created'); // 调用生命周期钩子 created
- if (vm.$options.el) {
- vm.$mount(vm.$options.el); // 挂载实例
- }
- };
复制代码
- 生命周期的初始化:在方法中,Vue 会进行生命周期的初始化,并调用和钩子。
- 渲染代理:用于实现模板访问时的代理。
- :如果传入了选项,Vue 会调用方法来挂载实例。
2.3 Vue 的 $mount 方法
挂载的核心方法是,它接受一个 DOM 元素或选择器字符串,并将 Vue 实例与这个 DOM 节点进行绑定。- Vue.prototype.$mount = function (el, hydrating) {
- el = el && query(el); // 如果传入了 el,进行选择并获取 DOM 元素
- if (el === document.body || el === document.documentElement) {
- warn('Do not mount Vue to <html> or <body> - mount to normal elements instead.');
- return;
- }
- const options = this.$options;
- if (!options.render) {
- let template = options.template;
- if (template) {
- if (typeof template === 'string') {
- // 编译模板
- template = compileToFunctions(template, this);
- }
- } else if (el) {
- // 没有模板时,从 DOM 中获取内容作为模板
- template = el.outerHTML;
- }
- options.render = template ? compileToFunctions(template, this) : createEmptyVNode;
- }
- return mountComponent(this, el, hydrating);
- };
复制代码
- DOM 查询:首先,被解析成 DOM 元素。
- 模板编译:如果没有传入渲染函数 (),Vue 会尝试从模板字符串中编译生成渲染函数。
- :最后,调用来进行组件的挂载。
2.4 mountComponent 方法
是挂载组件的核心方法,它会调用将实例挂载到指定的 DOM 上。- function mountComponent(vm, el, hydrating) {
- vm.$el = el;
- callHook(vm, 'beforeMount');
- let updateComponent;
-
- // 这里通过 render 函数来渲染视图
- updateComponent = function () {
- vm._update(vm._render(), hydrating);
- };
-
- // 调用 Vue 的渲染函数,执行视图更新
- new Watcher(vm, updateComponent, noop, { before: callHook.bind(vm, 'beforeUpdate') }, true);
- callHook(vm, 'mounted');
- return vm;
- }
复制代码
- 调用:在渲染之前,会先执行生命周期钩子。
- 渲染和更新:会触发方法进行视图更新。是用于生成虚拟 DOM 的方法,它会调用渲染函数。
- Watcher:Vue 通过来观察响应式数据的变化,并在数据变化时触发更新。
2.5 Vue 的 _update 方法
方法会根据虚拟 DOM 的变化,重新渲染并更新 DOM。- Vue.prototype._update = function (vnode, hydrating) {
- const vm = this;
- const prevEl = vm.$el;
- const prevVnode = vm._vnode;
- vm._vnode = vnode;
- if (!prevVnode) {
- // 初次渲染
- vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);
- } else {
- // 更新渲染
- vm.$el = vm.__patch__(prevVnode, vnode);
- }
- // 更新生命周期钩子
- callHook(vm, 'updated');
- };
复制代码
- 虚拟 DOM 比对:会执行虚拟 DOM 与真实 DOM 的比对,更新页面内容。
- 生命周期钩子:更新后,会调用生命周期钩子。
3. 总结 Vue 实例挂载的过程
Vue 实例的挂载过程包含以下几个主要步骤:
- 初始化实例:通过创建 Vue 实例,调用方法进行初始化。
- 编译模板:如果没有传入函数,Vue 会通过模板字符串生成渲染函数。
- 挂载组件:通过方法将 Vue 实例挂载到指定的 DOM 元素上。
- 渲染更新:通过方法更新 DOM,生成新的视图。
- 生命周期钩子:在每个阶段会触发相应的生命周期钩子函数(如、、、等)。
通过以上分析,我们可以理解 Vue 实例挂载的完整过程,以及其中涉及的关键函数和生命周期钩子。
到此这篇关于Vue实例创建和挂载的详细过程的文章就介绍到这了,更多相关Vue实例创建和挂载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
来源:https://www.jb51.net/javascript/331170tdk.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|