欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue.extend和VueComponent的關(guān)系源碼解析

 更新時(shí)間:2023年02月09日 11:45:23   作者:給小葉倒茶  
這篇文章主要為大家詳解了Vue.extend和VueComponent的關(guān)系源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

寫Vue.js已經(jīng)3年了吧,對(duì)Vue.extend全局方法的了解也就停留在了解啦,一直抱著不用就不學(xué)的思想,造成了一次又一次的錯(cuò)過(guò)~~~

直到最近,才通過(guò)公司10年禿頭少年的代碼,才知道錯(cuò)過(guò)Vue.extend方法,也就等于錯(cuò)過(guò)了對(duì)Vue組件的第二春了解的機(jī)會(huì)!??!

需求分析

在頁(yè)面中彈出消息提示框,比如在用戶點(diǎn)擊按鈕給予回應(yīng)

這種業(yè)務(wù)場(chǎng)景很常見(jiàn)吧,肯定是先創(chuàng)建一個(gè)彈框組件,在需要使用彈框的地方注冊(cè)組件并掛載到頁(yè)面上去

但是需求還沒(méi)結(jié)束,又提出在所以頁(yè)面都可以彈出這個(gè)消息提示框

首選局部注冊(cè)肯定是不行了,局部注冊(cè)只能當(dāng)前頁(yè)面使用,所以要選擇在App.vue中注冊(cè)并掛載,因?yàn)锳pp.vue是所有組件的根組件,所以組件也都能訪問(wèn)到App.vue中的方法,我們只需要在App.vue暴露一個(gè)彈框顯示的方法就可以了

產(chǎn)品還不打算放過(guò)我,又提出需求是可以同時(shí)出現(xiàn)多個(gè)消息提示框

這個(gè)就不好實(shí)現(xiàn)了呀,一個(gè)組件掛載只能彈出一個(gè)提示框,總不能在App.vue掛載很多個(gè)吧,其實(shí)這也是解決方案,但是不利于擴(kuò)展、占用內(nèi)存?。?!

那就沒(méi)有辦法了嗎?也不是,那就要請(qǐng)出主角Vue.extend全局方法?。?!

Vue.extend

看看官方的八股文:

使用基礎(chǔ) Vue 構(gòu)造器,創(chuàng)建一個(gè)“子類”。參數(shù)是一個(gè)包含組件選項(xiàng)的對(duì)象

我認(rèn)為這段文字表達(dá)十分明了,首先Vue.extend參數(shù)是包含組件選項(xiàng)的對(duì)象,返回值是Vue的子類

import Vue from 'vue'
let VueComponent = Vue.extend({})
VueComponent.prototype.__proto__ == Vue.prototype	// true

我們這里將子類稱為VueComponent

你對(duì)這個(gè)名稱很熟悉吧~~~

import Vue from 'vue/dist/vue.esm.js'   // 必須引入這個(gè)版本的Vue才可以使用template選項(xiàng)
new Vue({
    el: "#app",
    template: `
        <App></App>
    `,
    components: { App },
    mounted() {
        let app = this.$children[0];        // App組件實(shí)例
        let VueComponent = app.constructor  // App構(gòu)造函數(shù)
        console.log(app);
        console.log(VueComponent);
        console.log(VueComponent.prototype.__proto__ == Vue.prototype);
    }
})

不難發(fā)現(xiàn)VueComponent就是組件的構(gòu)造函數(shù)~~~

是不是一下就明白了,Vue.extend的返回值就是組件的構(gòu)造函數(shù),傳入的選項(xiàng)就是組件的初始配置

Vue.extend作用可以理解為:

首選創(chuàng)建一個(gè)Vue類的子類(組件的構(gòu)造函數(shù)),將傳入的組件選項(xiàng)配置當(dāng)做實(shí)例子類的默認(rèn)值(組件的初始配置),并返回這個(gè)類(組件的構(gòu)造函數(shù))

Vue.component("Toast", {})              // 全局注冊(cè)組件
console.log(Vue.component("Toast"));    // Toast組件構(gòu)造函數(shù)

在使用Vue.component方法注冊(cè)全局組件時(shí),其實(shí)內(nèi)部也是先調(diào)用Vue.extend生成VueComponent,再聲明到全局組件中,局部組件也是一樣的~~~

其實(shí)這里還能了解一個(gè)知識(shí)點(diǎn):所以的組件構(gòu)造函數(shù)的父類都是Vue,所以組件可以使用Vue上所以方法和屬性,比如emit、set等

編程式的使用組件

VueComponent可以被稱為小Vue,VueComponent的使用也就可以對(duì)照Vue

let VueComponent = Vue.extend({})
new VueComponent({
    el: "#app",
    template: `<h1>Vue.extend的使用</h1>`
})

是不是和Vue的使用一模一樣喃?

區(qū)別在于Vue.extend可以通過(guò)參數(shù)確定組件的初始配置~~~

現(xiàn)在完成一下最開(kāi)始的需求吧~

編寫my-toast.vue

<template>
  <h1 class="title" v-if="show">{{ title }}</h1>
</template>
<script>
  export default {
    name: "my-toast",
    props: {
      title: {
        typeof: String,
        default: ""
      }
    },
    data() {
      return {
        show: true
      };
    },
    created() {
      setTimeout(() => {
        this.show = false;
        this.$nextTick(() => {
          this.$destroy();
        });
      }, 2000);
    }
  };
</script>
<style>
  .title {
    width: 180px;
    height: 50px;
    position: fixed;
    right: 20px;
    top: 20px;
    background-color: rgba(0, 0, 0, 0.15);
    text-align: center;
    line-height: 50px;
    border-radius: 8px;
    font-size: 16px;
  }
</style>

在vue的原型上綁定顯示彈框方法

import Vue from 'vue';
import myToast from './components/my-toast.vue';
Vue.prototype.$toast = function (title) {
    const ToastComponent = Vue.extend(myToast);
    const toastComponent = new ToastComponent({
        propsData: {
            title
        }
    })
    toastComponent.$mount(document.createElement('div'));
    document.body.appendChild(toastComponent.$el);
}

在需要彈框的地方調(diào)用方法

// ....某vue頁(yè)面  
mounted() {
    this.$toast("測(cè)試");
}

let vm = new VueComponent(options)的注意點(diǎn):

  • 傳遞的props配置需要配置到propsData屬性中
  • 使用VueX、VueRoter等第三方模塊,需要把這些模塊掛載到options上
  • 使用插槽需要通過(guò)vm.$scopedSlots傳遞

源碼分析

你可以在源碼目錄src/core/global-api/extend.js下找到這個(gè)函數(shù)的定義

Vue.extend = function (extendOptions: any): typeof Component {
    extendOptions = extendOptions || {}
    // this指的是Vue
    const Super = this
    // 每個(gè)組件構(gòu)造函數(shù)都有唯一的cid
    const SuperId = Super.cid
    // 創(chuàng)建完的VueComponent構(gòu)造函數(shù),會(huì)保存到_Ctor中
    // 如果下次傳入相同的extendOptions和SuperId,就直接取用緩存內(nèi)的值
    const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
    if (cachedCtors[SuperId]) {
      return cachedCtors[SuperId]
    }
    // 獲取組件name
    const name =
      getComponentName(extendOptions) || getComponentName(Super.options)
    if (__DEV__ && name) {
        // 校驗(yàn)組件name
      validateComponentName(name)
    }
    // 創(chuàng)建VueComponent構(gòu)造函數(shù)
    const Sub = function VueComponent(this: any, options: any) {
      this._init(options)
    } as unknown as typeof Component
    // 重點(diǎn):實(shí)現(xiàn)了原型鏈繼承,讓VueComponent的原型指向Vue的原型
    // Vue的原型的所有方法和屬性,在VueComponent也存在
    Sub.prototype = Object.create(Super.prototype)
    Sub.prototype.constructor = Sub
    // 生成唯一cid
    Sub.cid = cid++
    // 傳入的extendOptions和Vue.options合并
    Sub.options = mergeOptions(Super.options, extendOptions)
    Sub['super'] = Super
    // 配置props的響應(yīng)式
    if (Sub.options.props) {
      initProps(Sub)
    }
    // 配置computed的響應(yīng)式
    if (Sub.options.computed) {
      initComputed(Sub)
    }
    // 繼承靜態(tài)方法
    Sub.extend = Super.extend
    Sub.mixin = Super.mixin
    Sub.use = Super.use
    //  ASSET_TYPES = ['component', 'directive', 'filter']
    ASSET_TYPES.forEach(function (type) {
      Sub[type] = Super[type]
    })
    if (name) {
      Sub.options.components[name] = Sub
    }
    // 保存基礎(chǔ)配置
    Sub.superOptions = Super.options
    Sub.extendOptions = extendOptions
    Sub.sealedOptions = extend({}, Sub.options)
    // 設(shè)置緩存
    cachedCtors[SuperId] = Sub
    return Sub
  }

Vue.extend關(guān)鍵在于繼承Vue,拋開(kāi)其他功能代碼,主要實(shí)現(xiàn)繼承的代碼:

// 繼承原型
Sub.prototype = Object.create(Super.prototype)
Sub.prototype.constructor = Sub
// 繼承靜態(tài)方屬性和方法
// 繼承靜態(tài)方法
Sub.extend = Super.extend
Sub.mixin = Super.mixin
Sub.use = Super.use
//  ASSET_TYPES = ['component', 'directive', 'filter']
ASSET_TYPES.forEach(function (type) {
    Sub[type] = Super[type]
})

以上就是Vue.extend和VueComponent的關(guān)系源碼解析的詳細(xì)內(nèi)容,更多關(guān)于Vue.extend和VueComponent的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue 如何向集合的頭部添加元素

    Vue 如何向集合的頭部添加元素

    在 Vue 中,如果要向集合的頭部添加元素,可以使用 JavaScript 的 unshift 方法或 Vue 的 $set 方法,本文給大家介紹Vue 向集合的頭部添加元素的方法,感興趣的朋友一起看看吧
    2023-12-12
  • vue:左右過(guò)渡展開(kāi)折疊的組件

    vue:左右過(guò)渡展開(kāi)折疊的組件

    在網(wǎng)上找了好久關(guān)于左右過(guò)渡動(dòng)畫折疊的組件,沒(méi)有合適的代碼,效果類似于element UI中的Drawer抽屜組件,只不過(guò)ele中的都是懸浮的組件,工作中遇到的很多都是占用空間的展開(kāi)折疊,網(wǎng)上很多也是上下展開(kāi)收起的組件,于是就自己寫了一個(gè),分享給大家,感興趣的朋友參考下吧
    2023-11-11
  • vite前端構(gòu)建Turborepo高性能monorepo方案

    vite前端構(gòu)建Turborepo高性能monorepo方案

    這篇文章主要為大家介紹了vite前端構(gòu)建Turborepo高性能monorepo方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 淺談Vue.js 組件中的v-on綁定自定義事件理解

    淺談Vue.js 組件中的v-on綁定自定義事件理解

    這篇文章主要介紹了淺談Vue.js 組件中的v-on綁定自定義事件理解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • el-date-picker設(shè)置日期默認(rèn)值兩種方法(當(dāng)月月初至月末)

    el-date-picker設(shè)置日期默認(rèn)值兩種方法(當(dāng)月月初至月末)

    這篇文章主要給大家介紹了關(guān)于el-date-picker設(shè)置日期默認(rèn)值(當(dāng)月月初至月末)的相關(guān)資料,文中通過(guò)代碼示例將解決的辦法介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • 基于Vue3+TypeScript實(shí)現(xiàn)圖片預(yù)覽組件

    基于Vue3+TypeScript實(shí)現(xiàn)圖片預(yù)覽組件

    在現(xiàn)代的 Web 應(yīng)用中,圖片預(yù)覽是一個(gè)常見(jiàn)的需求,本文將介紹如何使用 Vue3 和 TypeScript 開(kāi)發(fā)一個(gè)圖片預(yù)覽組件,支持展示單張或多張圖片,并提供了豐富的配置選項(xiàng),需要的朋友可以參考下
    2024-04-04
  • vue+springmvc導(dǎo)出excel數(shù)據(jù)的實(shí)現(xiàn)代碼

    vue+springmvc導(dǎo)出excel數(shù)據(jù)的實(shí)現(xiàn)代碼

    這篇文章主要介紹了vue+springmvc導(dǎo)出excel數(shù)據(jù)的實(shí)現(xiàn)代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-06-06
  • vue中對(duì)象數(shù)組去重的實(shí)現(xiàn)

    vue中對(duì)象數(shù)組去重的實(shí)現(xiàn)

    這篇文章主要介紹了vue中對(duì)象數(shù)組去重的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • vue中tinymce的使用實(shí)例詳解

    vue中tinymce的使用實(shí)例詳解

    TinyMCE Vue是TinyMCE官方發(fā)布的Vue組件,可以更輕松地在Vue應(yīng)用程序中使用TinyMCE,這篇文章主要介紹了vue中tinymce的使用,需要的朋友可以參考下
    2022-11-11
  • vue router 路由跳轉(zhuǎn)方法講解

    vue router 路由跳轉(zhuǎn)方法講解

    這篇文章主要介紹了vue router 路由跳轉(zhuǎn)方法概述,使用到Vue的項(xiàng)目,我們最常見(jiàn)使用的就是Vue配套的Vue Router庫(kù),本文結(jié)合示例代碼給大家詳細(xì)講解,需要的朋友可以參考下
    2022-12-12

最新評(píng)論