IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> VUE初始化的主要过程 -> 正文阅读

[JavaScript知识库]VUE初始化的主要过程

new 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)
}

?可见在new Vue后,构造函数内部调用了_init方法,其中_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)
    }
  }

大概讲讲,部分忽略?

1.添加uid

vm._uid = uid++

给当前实例添加一个唯一的uid标识。

2.合并options

    // 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
      )
    }

首先通过_isComponent判断该组件是否为子组件

为子组件:调用initInternalComponent函数,其主要做了两件事情:1.指定组件$options原型,2.把组件依赖于父组件的props、listeners也挂载到options上,方便子组件调用。

为根组件:对?options?进行合并,vue?会将相关的属性和方法都统一放到?vm.$options?中。vm.$options?的属性来自两个方面,一个是?Vue?的构造函数?vm.constructor?预先定义的,一个是?new Vue?时传入的入参对象。

3.initProxy

在非生产环境下执行了?initProxy?函数,参数是实例;在生产环境下设置了实例的?_renderProxy?属性为实例自身。

将实例的?_self?属性设置为实例自身。

4.initLifecycle

初始化组件实例关系属性 , 比如?$parent$children$root$refs?等 (不是组件生命周期?mounted?,?created…)。

5.initEvents

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)
  }
}

这个函数的功能就是初始化了一个存放事件的空对象,只存放挂载在该组件上的事件。_hasHookEvent属性是表示父组件是否有将钩子函数绑定到该组件上。如果父组件有绑定事件到该组件上则调用updateComponentListeners方法,下面看一下该方法的实现

function updateComponentListeners (
  vm: Component,
  listeners: Object,
  oldListeners: ?Object
) {
  target = vm
  updateListeners(listeners, oldListeners || {}, add, remove, vm)
  target = undefined
}

其中addremove是Vue中自己实现的两个添加Listener、移除Listener的方法。?

6.initRender

初始化插槽 , 获取?this.slots?, 定义?this._cthis.$createElement方法。其中_c 用于从模板<template>编译得到的组件中使用,通常是vue内部使用生成vnode,而$createElement是放给用户用作render渲染写法。

// a: 标签
// b: 标签属性
// c: children
// d: normalizationType(是否需要额外兜底处理)
vm._c = (a, b, c,d) => createElement(vm, a, b, c, d, false);
vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true);

7.callHook(vm, 'beforeCreate')

执行?beforeCreate?生命周期函数。

8.initInjections

初始化?inject?选项。

9.initState

响应式原理的核心 , 处理?propsmethodscomputeddatawatch?等。

10.initProvide

解析组件配置项上的?provide?对象,将其挂载到?vm._provided?属性上。

11.callHook(vm, 'created')

执行 create?生命周期函数。

最后判断vm.$options.el属性是否存在

存在:调用?vm.$mount?方法挂载?vm?,挂载的目标就是把模板渲染成最终的?DOM

不存在new Vue时手动挂载。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:34:49  更:2022-08-06 10:36:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/11 12:34:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码