最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue中extends繼承和組件復(fù)用性詳解

 更新時(shí)間:2023年11月01日 11:02:00   作者:是席木木啊  
這篇文章主要給大家介紹了關(guān)于Vue中extends繼承和組件復(fù)用性的相關(guān)資料,組件(Component)是Vue.js最強(qiáng)大的功能之一,組件可以擴(kuò)展HTML元素,封裝可重用的代碼,需要的朋友可以參考下

前言

提到extends繼承,最先想到的可能是ES6中的class、TS中的interface、面向?qū)ο缶幊陶Z(yǔ)言中中的類和接口概念等等,但是我們今天的關(guān)注點(diǎn)在于:如何在Vue中使用extends繼承特性。

再開(kāi)始探討Vue繼承相關(guān)的內(nèi)容之前,有必要回顧一下創(chuàng)建Vue組件實(shí)例的幾種方式,個(gè)人總結(jié)如下,

構(gòu)造函數(shù)方式:new Vue

這種方式是較為常見(jiàn)的,在Vue-cli腳手架構(gòu)建的前端項(xiàng)目中,經(jīng)??吹饺缦滤镜拇a段,

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

這就是在以Vue構(gòu)造函數(shù)的方式創(chuàng)建實(shí)例,然后將其掛載到id選擇器為app的DOM元素上。

Vue.extend方式

Vue.js開(kāi)發(fā)庫(kù)提供了Vue.extend()API,用于創(chuàng)建一個(gè)組件。

Vue.extend()方法的源碼如下,內(nèi)部主要是創(chuàng)建了一個(gè)Vue組件對(duì)象,并通過(guò)外部配置項(xiàng),將其props、computed、mixin等選項(xiàng)設(shè)置為可用,最終將對(duì)象返回,

/**
       * Class inheritance
       */
      Vue.extend = function (extendOptions) {
          extendOptions = extendOptions || {};//外部配置項(xiàng)-即:Vue組件的選項(xiàng)配置
          console.log(extendOptions)
          var Super = this;//指向Vue自身實(shí)例的引用
          var SuperId = Super.cid;
          var cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {});
          if (cachedCtors[SuperId]) {
              return cachedCtors[SuperId];
          }
          var name = getComponentName(extendOptions) || getComponentName(Super.options);
          if (name) {
              validateComponentName(name);
          }
          var Sub = function VueComponent(options) {
              this._init(options);
          };
          Sub.prototype = Object.create(Super.prototype);
          Sub.prototype.constructor = Sub;
          Sub.cid = cid++;
          Sub.options = mergeOptions(Super.options, extendOptions);
          Sub['super'] = Super;
          // For props and computed properties, we define the proxy getters on
          // the Vue instances at extension time, on the extended prototype. This
          // avoids Object.defineProperty calls for each instance created.
          if (Sub.options.props) {
              initProps(Sub);
          }
          if (Sub.options.computed) {
              initComputed(Sub);
          }
          // allow further extension/mixin/plugin usage
          Sub.extend = Super.extend;
          Sub.mixin = Super.mixin;
          Sub.use = Super.use;
          // create asset registers, so extended classes
          // can have their private assets too.
          ASSET_TYPES.forEach(function (type) {
              Sub[type] = Super[type];
          });
          // enable recursive self-lookup
          if (name) {
              Sub.options.components[name] = Sub;
          }
          // keep a reference to the super options at extension time.
          // later at instantiation we can check if Super's options have
          // been updated.
          Sub.superOptions = Super.options;
          Sub.extendOptions = extendOptions;
          Sub.sealedOptions = extend({}, Sub.options);
          // cache constructor
          cachedCtors[SuperId] = Sub;
          return Sub;
      }

通過(guò)查看Vue.extend()方法的源碼,我們會(huì)發(fā)現(xiàn),它內(nèi)部是在調(diào)用Vue原型對(duì)象上面的_init()方法來(lái)完成組件初始化,通過(guò)如下圖所示的一些核心配置,使其成為一個(gè)名副其實(shí)的Vue組件實(shí)例,

那么我們自己如何調(diào)用Vue.extend()方法創(chuàng)建組件呢?示例代碼如下,

    /**
     * 方式1-Vue.extend-使用基礎(chǔ) Vue 構(gòu)造器,創(chuàng)建一個(gè)組件
     * PS:此種方式中,data必須為函數(shù)
     * */
    const IButton = Vue.extend({
      name: "IButton",
      template: `<button class="btn" @click="clickBtnHandler($event)">Click</button>`,
      methods: {
        clickBtnHandler(e) {
          console.log(e.target.dataset)
        }
      },
    })
    Vue.component('i-button', IButton);//Vue.component用途之一:將組件注冊(cè)到全局環(huán)境

Vue.component方式

 Vue.component()方法有兩個(gè)作用,其①:將組件注冊(cè)全局可用的組件;其②:以給定的id,創(chuàng)建一個(gè)全局范圍內(nèi)可用的組件。使用此接口創(chuàng)建一個(gè)Vue組件的示例代碼如下,

    /**
     * 方式2-Vue.component-間接調(diào)用Vue.extend,創(chuàng)建一個(gè)組件
     * PS:此種方式中,data必須為函數(shù)
     * */
    const IList = Vue.component('i-list', {
      template: `<div>
        <p>列表</p>
        <ul>
          <li v-for="n in number">{{n}}</li>
        </ul></div>`,
      data: function () {
        return {
          number: 5
        }
      }
    })
    // Vue.component('i-list', IList);//Vue.component創(chuàng)建的組件無(wú)需再注冊(cè)

render渲染函數(shù)方式

也可以通過(guò)Vue.js提供的render()渲染函數(shù)創(chuàng)建一個(gè)Vue組件,如下示例代碼,通過(guò)render函數(shù)的函數(shù),根據(jù)props參數(shù)level來(lái)創(chuàng)建了一個(gè)級(jí)別為level的h標(biāo)簽,并提供插槽供開(kāi)發(fā)者對(duì)其進(jìn)行拓展。

 //方式3:基于渲染函數(shù)構(gòu)造函數(shù)式組件-[基于slot插槽方式提供組件內(nèi)容1]
    const ITitle = Vue.component(
      "i-title",
      {
      render: function (createElement) {
        return createElement(
          'h' + this.level,   // 標(biāo)簽名稱
          this.$slots.default // 子節(jié)點(diǎn)數(shù)組
        )
      },
      props: {
        level: {
          type: Number,
          required: true
        }
      }
    });

對(duì)象方式

通過(guò)對(duì)象的形式定義組件-這也是我們?cè)赩ue前端應(yīng)用開(kāi)發(fā)中最常使用的方式,然后通過(guò)export default導(dǎo)出。示例代碼如下,

    //方式4-通過(guò)對(duì)象的形式定義組件-這也是我們?cè)赩ue前端應(yīng)用開(kāi)發(fā)中最常使用的方式,然后通過(guò)export default導(dǎo)出
    const InfoBox = {
      name: "InfoBox",
      template: `<div class="box" :style="styleObject">{{content}}</div>`,
      data() {
        return {
          content: '消息內(nèi)容',
          styleObject: {
            boxSizing: "border-box",
            padding: "25px",
            width: '300px',
            height: '200px',
            backgroundColor: 'rgba(0,0,0,0.3)'
          }
        }
      }
    }
    Vue.component('info-box', InfoBox);//Vue.component用途之一:將組件注冊(cè)到全局環(huán)境

Vue:extends繼承特性

第一部分只介紹了如何創(chuàng)建一個(gè)組件,并沒(méi)有介紹如何去提高一個(gè)組件的復(fù)用性。既然談到復(fù)用性,可行的方法有很多,例如:slot插槽、mixix混入、Vue.directive自定義一個(gè)可復(fù)用的指令、通過(guò)Install方法開(kāi)發(fā)一個(gè)可復(fù)用的插件、通過(guò)Vue.filter定義一個(gè)可復(fù)用的過(guò)濾器等。關(guān)于如上內(nèi)容,Vue官網(wǎng)都有詳細(xì)的介紹。

而接下來(lái)要討論的就是Vue官網(wǎng)里面介紹比較含蓄的一種方法:借助extends實(shí)現(xiàn)組件的繼承。

那么具體如何操作呢?我們先來(lái)定義一個(gè)基礎(chǔ)列表組件IList,并以事件委托的方式為每一個(gè)列表元素注冊(cè)點(diǎn)擊事件,示例代碼如下,

<!--
 * @Description: IList列表組件,基于事件委托機(jī)制對(duì)列表事件回調(diào)做了優(yōu)化處理
 * @Author: Xwd
 * @Date: 2023-02-16 00:21:49
 * @LastEditors: Xwd
 * @LastEditTime: 2023-02-19 17:03:25
 * @Attention: 此列表組件的clickHandler()點(diǎn)擊事件默認(rèn)基于index下標(biāo)來(lái)選擇性的返回item的值,在一些場(chǎng)景下存在風(fēng)險(xiǎn)-->
<template>
  <div class="i-list">
    <p v-if="!!title" class="i-title">{{ title }}</p>
    <!-- <div class="split-horizon"></div> -->
    <div v-if="(list || []).length > 0" class="i-content" @click="clickHandler($event)">
      <div class="i-item" v-for="(item, index) in list" :key="index">
        <img class="i-item-icon" :src="item.image || noImage" />
        <div class="i-item-body">
          <div class="i-item-title">{{ item.title }}<span class="iconfont" title="地圖定位" :data-id="item.id"
              :data-index="index">&#xe75d;</span></div>
          <div class="i-item-desc" :title="item.desc">{{ item.desc }}</div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import noImage from '@/assets/images/no.png';
export default {
  name: "IList",
  props: {
    title: {
      type: String,
      required: false,
      default: "",
    },
    list: {
      type: Array,
      required: false,
      default: () => [],
    }
  },
  mounted() { },
  methods: {
    /**
     * 列表元素點(diǎn)擊事件-回調(diào)函數(shù)
     * @param {*} event 
     */
    clickHandler(event) {
      const index = event.target.dataset.index;
      if (typeof index !== "undefined" && index !== null) {
        this.$emit("click", this.list[Number(index)], Number(index));
      }
    }
  }
}
</script>
<style lang="less" scoped>
 
</style>

而由于我們存在一些不確定因素,例如:props中的list是否具有唯一id、點(diǎn)擊回調(diào)函數(shù)中的具體邏輯是什么?所以我們可以將次組件作為一個(gè)基組件,在后續(xù)使用過(guò)程中,在子組件TownList.vue中通過(guò)extends的選項(xiàng),來(lái)繼承IList組件,實(shí)現(xiàn)復(fù)用。示例代碼如下,

<!--
 * @Description: 
 * @Author: Xwd
 * @Date: 2023-02-19 16:50:16
 * @LastEditors: Xwd
 * @LastEditTime: 2023-02-19 16:56:57
-->
<script>
import IList from '@/components/layout/IList.vue';
export default {
  name:"TownList",
  extends:IList,
  methods:{
     /**
     * 列表元素點(diǎn)擊事件-回調(diào)函數(shù),覆寫父組件方法,基于元素id值重定義處理邏輯
     * @param {*} event 事件對(duì)象
     */
     clickHandler(event) {
      const id = event.target.dataset.id;
      console.log(`id=${id}`)
      if (typeof id !== "undefined" && id !== null) {
        const dataIndex = this.list.findIndex(item => item.id == id);
        dataIndex !== -1 & this.$emit("click", this.list[dataIndex], dataIndex)
      }
    }
  }
}
</script>

此處我們通過(guò)id來(lái)區(qū)分每一個(gè)元素,并覆寫了父組件中的clickHandler——點(diǎn)擊事件回調(diào)方法。最終效果如下,

此種方式的不足之處在于:無(wú)法在子組件中添加template節(jié)點(diǎn),否則會(huì)直接覆蓋掉原有的template模板。

總結(jié)

到此這篇關(guān)于Vue中extends繼承和組件復(fù)用性的文章就介紹到這了,更多相關(guān)Vue extends繼承和組件復(fù)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue2.x與vue3.x中自定義指令詳解(最新推薦)

    vue2.x與vue3.x中自定義指令詳解(最新推薦)

    vue自定義指令(2.x丨3.x)可以幫助我們實(shí)現(xiàn)需要操作,比如防抖、節(jié)流、懶加載、輸入框自動(dòng)聚焦等等,使用起來(lái)非常方便,比如vue自帶的v-text、v-html、v-show、v-if等等,這篇文章主要介紹了vue2.x與vue3.x中自定義指令詳解,需要的朋友可以參考下
    2022-12-12
  • Vue中如何引用公共方法和公共組件

    Vue中如何引用公共方法和公共組件

    這篇文章主要介紹了Vue中如何引用公共方法和公共組件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • vue項(xiàng)目登錄頁(yè)面實(shí)現(xiàn)記住用戶名和密碼的示例代碼

    vue項(xiàng)目登錄頁(yè)面實(shí)現(xiàn)記住用戶名和密碼的示例代碼

    本文主要介紹了vue項(xiàng)目登錄頁(yè)面實(shí)現(xiàn)記住用戶名和密碼的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • VUE學(xué)習(xí)之Element-ui文件上傳實(shí)例詳解

    VUE學(xué)習(xí)之Element-ui文件上傳實(shí)例詳解

    今天進(jìn)行了element?文件上傳組件的運(yùn)用,寫一下心得,下面這篇文章主要給大家介紹了關(guān)于VUE學(xué)習(xí)之Element-ui文件上傳的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • vue3.0父子傳參,子修改父數(shù)據(jù)的實(shí)現(xiàn)

    vue3.0父子傳參,子修改父數(shù)據(jù)的實(shí)現(xiàn)

    這篇文章主要介紹了vue3.0父子傳參,子修改父數(shù)據(jù)的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue3應(yīng)對(duì)后端接口返回十萬(wàn)條數(shù)據(jù)的解決方案

    Vue3應(yīng)對(duì)后端接口返回十萬(wàn)條數(shù)據(jù)的解決方案

    在前端開(kāi)發(fā)中,我們有時(shí)會(huì)遇到后端接口直接返回 十萬(wàn)條數(shù)據(jù) 的情況,很多初學(xué)者會(huì)直接把數(shù)據(jù)全部 v-for 渲染到頁(yè)面上,結(jié)果瀏覽器瞬間卡死甚至崩潰,本文將從問(wèn)題原因出發(fā),逐步給出幾種常見(jiàn)解決方案,需要的朋友可以參考下
    2025-09-09
  • vue中百度地圖定位及附近搜索功能使用步驟

    vue中百度地圖定位及附近搜索功能使用步驟

    這篇文章主要為大家介紹了vue中百度地圖定位及附近搜索功能使用步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Vue3新?tīng)顟B(tài)管理工具實(shí)例詳解

    Vue3新?tīng)顟B(tài)管理工具實(shí)例詳解

    Vue3公布曾經(jīng)有一段時(shí)間了,它采納了新的響應(yīng)式零碎,而且構(gòu)建了一套全新的 Composition API,下面這篇文章主要給大家介紹了關(guān)于Vue3新?tīng)顟B(tài)管理工具的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • vue中element 的upload組件發(fā)送請(qǐng)求給后端操作

    vue中element 的upload組件發(fā)送請(qǐng)求給后端操作

    這篇文章主要介紹了vue中element 的upload組件發(fā)送請(qǐng)求給后端操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • Vue實(shí)現(xiàn)左右菜單聯(lián)動(dòng)實(shí)現(xiàn)代碼

    Vue實(shí)現(xiàn)左右菜單聯(lián)動(dòng)實(shí)現(xiàn)代碼

    這篇文章主要介紹了Vue實(shí)現(xiàn)左右菜單聯(lián)動(dòng)實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08

最新評(píng)論

上饶县| 井陉县| 平遥县| 疏附县| 云浮市| 定兴县| 来安县| 西华县| 收藏| 安义县| 巧家县| 逊克县| 湖南省| 明星| 西华县| 台山市| 井冈山市| 乐昌市| 元谋县| 深泽县| 唐海县| 仲巴县| 中宁县| 环江| 平利县| 宜良县| 酒泉市| 翁源县| 定州市| 南城县| 广河县| 五华县| 文化| 保亭| 日喀则市| 德阳市| 永济市| 五莲县| 阿克苏市| 冷水江市| 铁岭市|