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知识库 -> vue2源码(一)-- Vue.extend -> 正文阅读

[JavaScript知识库]vue2源码(一)-- Vue.extend

作用

使用基础的vue构造器,创建一个子类。参数是包含组件选项的对象。其中data必须是函数

使用场景

1、所有自定义组件都是通过extend方法构造出来的

2、实现js调用组件,element-uiMessageMessageBox等js调用组件,都是通过Vue.extend实现的

原理分析

1、获取父类的cid

2、从对象参数中获取缓存池,根据父类的cid判断缓存池中是否已经在之前创建过改子类。是,就直接返回缓存的。这是为了vue的性能考虑的。对于同一个组件选项对象,反复调用vue.extend返回的是同一个结果的

3、获取组件的 name 字段,校验组件名字是否合法

4、通过函数的方式创建一个sub类,并将父类的原型链继承到子类中(原型链继承方式),同时还需要修正constructor的指向

5、将父类的options字段和传入组件对象选项进行合并,并保存在子类suboptions字段中

6、将父类保存到子类的 super 字段中,确保子类能拿到父类

7、初始化props,实际上是代理到_props属性。根组件的 props 是在这里进行数据劫持的。好处就是不用为每个组件的实例都做一层 proxy,这是一种优化手段

8、初始化computed

9、将父类的extendmixin等全局 API 添加到子类中

10、如果name字段存在,则给子类sub添加name字段,方便进行组件递归

11、新增superOptionsextendOptions等子类独有的属性

12、将构造出来的子类sub放进缓存池,key值为父类的cid

13、返回子类sub

源码

源码位于src/core/global-api/extend.js

/* @flow */

import { ASSET_TYPES } from 'shared/constants'
import { defineComputed, proxy } from '../instance/state'
import { extend, mergeOptions, validateComponentName } from '../util/index'

export function initExtend (Vue: GlobalAPI) {
  // 每个vue实例都有一个唯一标识
  Vue.cid = 0
  let cid = 1

  // 类继承,作用是创建一个继承自vue类的子类,参数接收的是组件选项的对象
  // extendOptions:用户传入的组件选项参数
  Vue.extend = function (extendOptions: Object): Function {
    // 用户传入的一个包含组件选项的对象参数
    extendOptions = extendOptions || {}
    // 父类,即基础的vue类
    const Super = this
    // 父类id,无论是基础vue类还是继承的vue类,都有一个唯一标识
    const SuperId = Super.cid
    // 缓存池,用于缓存创建出来的类
    const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
    // 缓存池
    if (cachedCtors[SuperId]) {
      // 这一步是为了vue性能考虑,反复调用其实返回的是同一个结果
      // 已经创建过的不需要在创建
      // 避免多次执行 Vue.extend 的时候对同一个子组件重复构造。
      return cachedCtors[SuperId]
    }
    // 获取组件选项的name字段
    const name = extendOptions.name || Super.options.name
    // 校验组件名是否合法
    if (process.env.NODE_ENV !== 'production' && name) {
      validateComponentName(name)
    }

    // 创建一个vue类的子类,这个类即将要继承基础vue类
    const Sub = function VueComponent (options) {
      this._init(options)
    }
    // 原型链继承方式
    // 将父类的原型继承到子类
    Sub.prototype = Object.create(Super.prototype)
    // 修正constructor的指向
    Sub.prototype.constructor = Sub
    // id自增,保证唯一标识
    Sub.cid = cid++
    // 父类的options和传入的子类options进行合并
    Sub.options = mergeOptions(
      Super.options,
      extendOptions
    )
    // 将父类保存到子类的super字段中,确保子类能拿到父类
    Sub['super'] = Super

    // 初始化props,根组件的props是在这里进行数据劫持的。好处就是不用为每个组件的实例都做一层proxy,这是一种优化手段
    if (Sub.options.props) {
      // 初始化props其实就是代理到原型的_props属性
      initProps(Sub)
    }
    // 初始化computed
    if (Sub.options.computed) {
      initComputed(Sub)
    }

    // 将父类的一些属性添加到子类中
    Sub.extend = Super.extend
    Sub.mixin = Super.mixin
    Sub.use = Super.use

    // 'component',
    // 'directive',
    // 'filter'
    ASSET_TYPES.forEach(function (type) {
      Sub[type] = Super[type]
    })
    // 方便组件进行递归调用
    if (name) {
      Sub.options.components[name] = Sub
    }

    // 新增子类独有属性
    Sub.superOptions = Super.options
    Sub.extendOptions = extendOptions
    Sub.sealedOptions = extend({}, Sub.options)

    // 放入缓存池
    cachedCtors[SuperId] = Sub
    return Sub
  }
}

function initProps (Comp) {
  const props = Comp.options.props
  for (const key in props) {
    // 将props代理到原型上面的_props
    proxy(Comp.prototype, `_props`, key)
  }
}

function initComputed (Comp) {
  const computed = Comp.options.computed
  for (const key in computed) {
    defineComputed(Comp.prototype, key, computed[key])
  }
}

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

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:38:51-

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