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

詳解Vue組件復(fù)用和擴(kuò)展之道

 更新時間:2021年05月08日 10:51:41   作者:李中凱  
這篇文章主要介紹了Vue組件復(fù)用和擴(kuò)展,對vue感興趣的同學(xué),可以參考下

概述

軟件編程有一個重要的原則是 D.R.Y(Don't Repeat Yourself),講的是盡量復(fù)用代碼和邏輯,減少重復(fù)。組件擴(kuò)展可以避免重復(fù)代碼,更易于快速開發(fā)和維護(hù)。那么,擴(kuò)展 Vue 組件的最佳方法是什么?

Vue 提供了不少 API 和模式來支持組件復(fù)用和擴(kuò)展,你可以根據(jù)自己的目的和偏好來選擇。

本文介紹幾種比較常見的方法和模式,希望對你有所幫助。

擴(kuò)展組件是否必要

要知道,所有的組件擴(kuò)展方法都會增加復(fù)雜性和額外代碼,有時候還會增加性能消耗。

因此,在決定擴(kuò)展組件之前,最好先看看有沒有其他更簡單的設(shè)計模式能完成目標(biāo)。

下面幾種組件設(shè)計模式通常足夠替代擴(kuò)展組件了:

  • props 配合模板邏輯
  • slot 插槽
  • JavaScript 工具函數(shù)

props 配合模板邏輯

最簡單的方法是通過props結(jié)合模板條件渲染,來實現(xiàn)組件的多功能。

比如通過 type 屬性:
MyVersatileComponent.vue

<template>
  <div class="wrapper">
    <div v-if="type === 'a'">...</div>
    <div v-else-if="type === 'b'">...</div>
    <!--etc etc-->
  </div>
</template>
<script>
export default {
  props: { type: String },
  ...
}
</script>

使用組件的時候傳不同的type值就能實現(xiàn)不同的結(jié)果。

// *ParentComponent.vue*
<template>
  <MyVersatileComponent type="a" />
  <MyVersatileComponent type="b" />
</template>

如果出現(xiàn)下面兩種情況,就說明這種模式不適用了,或者用法不對:

  • 組件組合模式把狀態(tài)和邏輯分解成原子部分,從而讓應(yīng)用具備可擴(kuò)展性。如果組件內(nèi)存在大量條件判斷,可讀性和可維護(hù)性就會變差。
  • props 和模板邏輯的本意是讓組件動態(tài)化,但是也存在運行時資源消耗。如果你利用這種機(jī)制在運行時解決代碼組合問題,那是一種反模式。

slot(插槽)

另一種可避免組件擴(kuò)展的方式是利用 slots(插槽),就是讓父組件在子組件內(nèi)設(shè)置自定義內(nèi)容。

// *MyVersatileComponent.vue*
<template>
  <div class="wrapper">
    <h3>Common markup</div>
    <slot />
  </div>
</template>
// *ParentComponent.vue*
<template>
  <MyVersatileComponent>
    <h4>Inserting into the slot</h4>
  </MyVersatileComponent>
</template>

渲染結(jié)果:

<div class="wrapper">
  <h3>Common markup</div>
  <h4>Inserting into the slot</h4>
</div>

這種模式有一個潛在約束, slot 內(nèi)的元素從屬于父組件的上下文,在拆分邏輯和狀態(tài)時可能不太自然。scoped slot會更靈活,后面會在無渲染組件一節(jié)里提到。

JavaScript 工具函數(shù)

如果只需要在各組件之間復(fù)用獨立的函數(shù),那么只需要抽取這些 JavaScript 模塊就行了,根本不需要用到組件擴(kuò)展模式。

JavaScript 的模塊系統(tǒng)是一種非常靈活和健壯的代碼共享方式,所以你應(yīng)該盡可能地依靠它。
MyUtilityFunction.js

export default function () {
  ...
}

MyComponent.vue

import MyUtilityFunction from "./MyUtilityFunction";
export default {
  methods: {
    MyUtilityFunction
  }
}

擴(kuò)展組件的幾種模式

如果你已經(jīng)考慮過以上幾種簡單的模式,但這些模式還不夠靈活,無法滿足需求。那么就可以考慮擴(kuò)展組件了。

擴(kuò)展 Vue 組件最流行的方法有以下四種:

  • Composition 函數(shù)
  • mixin
  • 高階組件(HOC)
  • 無渲染組件

每一種方法都有其優(yōu)缺點,根據(jù)使用場景,或多或少都有適用的部分。

Composition API

組件之間共享狀態(tài)和邏輯的最新方案是 Composition API。這是 Vue 3 推出的 API,也可以在 Vue 2 里當(dāng)插件使用。

跟之前在組件定義配置對象里聲明data,computed,methods等屬性的方式不同,Composition API 通過一個 setup 函數(shù)聲明和返回這些配置。

比如,用 Vue 2 配置屬性的方式聲明 Counter 組件是這樣的:
Counter.vue

<template>
  <button @click="increment">
    Count is: {{ count }}, double is: {{ double }}
  </button>
<template>
<script>
export default {
  data: () => ({
    count: 0
  }),
  methods: {
    increment() {
      this.count++;
    }
  },
  computed: {
    double () {
      return this.count * 2;
    }
  }
}
</script>

用 Composition API 重構(gòu)這個組件,功能完全一樣:
Counter.vue

<template><!--as above--><template>
<script>
import { reactive, computed } from "vue";

export default {
  setup() {
    const state = reactive({
      count: 0,
      double: computed(() => state.count * 2)
    });

    function increment() {
      state.count++
    }

    return {
      count,
      double,
      increment
    }
  }
}
</script>

用 Composition API 聲明組件的主要好處之一是,邏輯復(fù)用和抽取變得非常輕松。

進(jìn)一步重構(gòu),把計數(shù)器的功能移到 JavaScript 模塊 useCounter.js中:
useCounter.js

import { reactive, computed } from "vue";

export default function {
  const state = reactive({
    count: 0,
    double: computed(() => state.count * 2)
  });

  function increment() {
    state.count++
  }

  return {
    count,
    double,
    increment
  }
}

現(xiàn)在,計數(shù)器功能可以通過setup函數(shù)無縫引入到任意 Vue 組件中:
MyComponent.vue

<template><!--as above--></template>
<script>
import useCounter from "./useCounter";

export default {
  setup() {
    const { count, double, increment } = useCounter();
    return {
      count,
      double,
      increment
    }
  }
}
</script>

Composition 函數(shù)讓功能模塊化、可重用,是擴(kuò)展組件最直接和低成本的方式。

Composition API 的缺點

Composition API 的缺點其實不算什么——可能就是看起來有點啰嗦,并且新的用法對一些 Vue 開發(fā)者來說有點陌生。

關(guān)于 Composition API 優(yōu)缺點的討論,推薦閱讀:When To Use The New Vue Composition API (And When Not To)

mixin

如果你還在用 Vue 2,或者只是喜歡用配置對象的方式定義組件功能,可以用 mixin 模式。mixin 把公共邏輯和狀態(tài)抽取到單獨的對象,跟使用 mixin 的組件內(nèi)部定義對象合并。

我們繼續(xù)用之前的Counter組件例子,把公共邏輯和狀態(tài)放到CounterMixin.js模塊中。
CounterMixin.js

export default {
  data: () => ({
    count: 0
  }),
  methods: {
    increment() {
      this.count++;
    }
  },
  computed: {
    double () {
      return this.count * 2;
    }
  }
}

使用 mixin 也很簡單,只要導(dǎo)入對應(yīng)模塊并在mixins數(shù)組里加上變量就行。組件初始化時會把 mixin 對象與組件內(nèi)部定義對象合并。
MyComponent.vue

import CounterMixin from "./CounterMixin";

export default {
  mixins: [CounterMixin],
  methods: {
    decrement() {
      this.count--;
    }
  }
}

選項合并

如果組件內(nèi)的選項跟 mixin 沖突怎么辦?

比如,給組件定義一個自帶的increment方法,哪個優(yōu)先級更高呢?
MyComponent.vue

import CounterMixin from "./CounterMixin";

export default {
  mixins: [CounterMixin],
  methods: {
    // 自帶的 `increment`` 方法會覆蓋 mixin 的`increment` 嗎?
    increment() { ... }
  }
}

這個時候就要說到 Vue 的合并策略了。Vue 有一系列的規(guī)則,決定了如何處理同名選項。

通常,組件自帶的選項會覆蓋來自 mixin 的選項。但也有例外,比如同類型的生命周期鉤子,不是直接覆蓋,而是都放進(jìn)數(shù)組,按順序執(zhí)行。

你也可以通過 自定義合并策略 改變默認(rèn)行為。

mixin 的缺點

作為擴(kuò)展組件的一種模式,mixin 對于簡單的場景還算好用,一旦規(guī)模擴(kuò)大,問題就來了。不僅需要注意命名沖突問題(尤其是第三方 mixin),使用了多個 mixin 的組件,很難搞清楚某個功能到底來自于哪里,定位問題也比較困難。

高階組件

高階組件(HOC)是從 React 借用的概念,Vue 也能使用。

為了理解這個概念,我們先拋開組件,看看兩個簡單的 JavaScript 函數(shù),increment和 double。

function increment(x) {
  return x++;
}

function double(x) {
  return x * 2;
}

假設(shè)我們想給這兩個函數(shù)都加一個功能:在控制臺輸出結(jié)果。

為此,我們可以用高階函數(shù)模式,新建一個addLogging函數(shù),接受函數(shù)作為參數(shù),并返回一個帶有新增功能的函數(shù)。

function addLogging(fn) {
  return function(x) {
    const result = fn(x);
    console.log("The result is: ", result);
    return result;
  };
}

const incrementWithLogging = addLogging(increment);
const doubleWithLogging = addLogging(double);

組件如何利用這種模式呢?類似地,我們創(chuàng)建一個高階組件來渲染Counter組件,同時添加一個decrement方法作為實例屬性。

實際代碼比較復(fù)雜,這里只給出偽代碼作為示意:

import Counter from "./Counter";

// 偽代碼
const CounterWithDecrement => ({
  render(createElement) {
    const options = {
      decrement() {
        this.count--;
      }
    }
    return createElement(Counter, options);
  }
});

HOC 模式比 mixin 更簡潔,擴(kuò)展性更好,但是代價是增加了一個包裹組件,實現(xiàn)起來也需要技巧。

無渲染組件

如果需要在多個組件上使用相同的邏輯和狀態(tài),只是展示方式不同,那么就可以考慮無渲染組件模式。

該模式需要用到兩類組件:邏輯組件用于聲明邏輯和狀態(tài),展示組件用于展示數(shù)據(jù)。

邏輯組件

還是回到Counter的例子,假設(shè)我們需要在多個地方重用這個組件,但是展示方式不同。

創(chuàng)建一個CounterRenderless.js用于定義邏輯組件,包含邏輯和狀態(tài),但是不包含模板,而是通過 render函數(shù)聲明 scoped slot。

scoped slot暴露三個屬性給父組件使用:狀態(tài)count,方法increment 和計算屬性 double。
CounterRenderless.js

export default {
  data: () => ({
    count: 0
  }),
  methods: {
    increment() {
      this.count++;
    }
  },
  computed: {
    double () {
      return this.count * 2;
    }
  },
  render() {
    return this.$scopedSlots.default({
      count: this.count,
      double: this.double,
      increment: this.toggleState,
    })
  }
}

這里的scoped slot是這種模式里邏輯組件的關(guān)鍵所在。

展示組件

接下來是展示組件,作為無渲染組件的使用方,提供具體的展示方式。

所有的元素標(biāo)簽都包含在scoped slot里??梢钥吹剑@些屬性在使用上跟模板直接放在邏輯組件里沒什么兩樣。
CounterWithButton.vue

<template>
  <counter-renderless slot-scope="{ count, double, increment }">
    <div>Count is: {{ count }}</div> 
    <div>Double is: {{ double }}</div>
    <button @click="increment">Increment</button>
  </counter-renderless>
</template>
<script>
import CounterRenderless from "./CountRenderless";
export default {
  components: {
    CounterRenderless
  }
}
</script>

無渲染組件模式非常靈活,也容易理解。但是,它沒有前面那幾種方法那么通用,可能只有一種應(yīng)用場景,那就是用于開發(fā)組件庫。

模板擴(kuò)展

上面的 API 也好,設(shè)計模式也罷,都有一種局限性,就是無法擴(kuò)展組件的模板。Vue 在邏輯和狀態(tài)方面有辦法重用,但是對于模板標(biāo)簽就無能為力了。

有一種比較 hack 的方式,就是利用 HTML 預(yù)處理器,比如 Pug,來處理模板擴(kuò)展。

第一步是創(chuàng)建一個基礎(chǔ)模板.pug文件,包含公共的頁面元素。還要包含一個block input,作為模板擴(kuò)展的占位符。

BaseTemplate.pug

div.wrapper
  h3 {{ myCommonProp }} <!--common markup-->
  block input <!--extended markup outlet -->

為了能擴(kuò)展這個模板,需要安裝 Vue Loader 的 Pug 插件。然后就可以引入基礎(chǔ)模板并利用block input語法替換占位部分了:
MyComponent.vue

<template lang="pug">
  extends BaseTemplate.pug
  block input
    h4 {{ myLocalProp }} <!--gets included in the base template-->
</template>

一開始你可能會認(rèn)為它跟 slot 的概念是一樣的,但是有個區(qū)別,這里的基礎(chǔ)模板不屬于任何單獨的組件。它在編譯時跟當(dāng)前組件合并,而不是像 slot 那樣是在運行時替換。

以上就是詳解Vue組件復(fù)用和擴(kuò)展之道的詳細(xì)內(nèi)容,更多關(guān)于Vue組件復(fù)用和擴(kuò)展的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue3 axios 實現(xiàn)自動化api配置詳解

    vue3 axios 實現(xiàn)自動化api配置詳解

    這篇文章主要為大家介紹了vue3 axios 實現(xiàn)自動化api配置詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • vue使用el-table 添加行手動填寫數(shù)據(jù)和刪除行及提交保存功能

    vue使用el-table 添加行手動填寫數(shù)據(jù)和刪除行及提交保存功能

    遇到這樣的需求點擊新增按鈕實現(xiàn)下列彈窗的效果,點擊添加行新增一行,點擊刪除進(jìn)行刪除行,點擊提交將數(shù)據(jù)傳遞到后端進(jìn)行保存,怎么實現(xiàn)的呢,下面通過實例代碼給大家詳細(xì)講解,感興趣的朋友一起看看吧
    2023-12-12
  • spring-cloud-stream的手動消息確認(rèn)問題

    spring-cloud-stream的手動消息確認(rèn)問題

    這篇文章主要介紹了spring-cloud-stream的手動消息確認(rèn)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • element-ui 中使用upload多文件上傳只請求一次接口

    element-ui 中使用upload多文件上傳只請求一次接口

    這篇文章主要介紹了element-ui 中使用upload多文件上傳只請求一次接口,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • Vue——解決報錯 Computed property

    Vue——解決報錯 Computed property "****" was assigned to but it ha

    這篇文章主要介紹了Vue——解決報錯 Computed property "****" was assigned to but it has no setter.的方法,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2020-12-12
  • Vue.js手風(fēng)琴菜單組件開發(fā)實例

    Vue.js手風(fēng)琴菜單組件開發(fā)實例

    這篇文章主要為大家詳細(xì)介紹了Vue.js手風(fēng)琴菜單組件開發(fā)實例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • vue 輸入框輸入任意內(nèi)容返回數(shù)字的實現(xiàn)

    vue 輸入框輸入任意內(nèi)容返回數(shù)字的實現(xiàn)

    本文主要介紹了vue 輸入框輸入任意內(nèi)容返回數(shù)字的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • 基于Vue2實現(xiàn)簡易的省市區(qū)縣三級聯(lián)動組件效果

    基于Vue2實現(xiàn)簡易的省市區(qū)縣三級聯(lián)動組件效果

    這是一個基于Vue2的簡易省市區(qū)縣三級聯(lián)動組件,可以控制只顯示省級或只顯示省市兩級,可設(shè)置默認(rèn)值等。提供原始省市縣代碼和名稱數(shù)據(jù),適用于各種有關(guān)城市區(qū)縣的應(yīng)用。需要的朋友可以參考下
    2018-11-11
  • 使用vue打包進(jìn)行云服務(wù)器上傳的問題

    使用vue打包進(jìn)行云服務(wù)器上傳的問題

    這篇文章主要介紹了使用vue打包進(jìn)行云服務(wù)器上傳,本文給大家介紹的非常詳細(xì),對大家的工作或?qū)W習(xí)具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • vue 利用路由守衛(wèi)判斷是否登錄的方法

    vue 利用路由守衛(wèi)判斷是否登錄的方法

    今天小編就為大家分享一篇vue 利用路由守衛(wèi)判斷是否登錄的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09

最新評論

毕节市| 平乡县| 沈阳市| 女性| 陆河县| 军事| 缙云县| 贞丰县| 太湖县| 镇江市| 新源县| 正安县| 三江| 凤城市| 名山县| 曲阳县| 莱阳市| 祁阳县| 天等县| 石渠县| 周至县| 澳门| 武城县| 禄丰县| 翁牛特旗| 夏津县| 通城县| 苍梧县| 剑河县| 咸阳市| 津市市| 泽州县| 屏山县| 定远县| 定日县| 乐平市| 开化县| 米脂县| 平遥县| 江阴市| 炉霍县|