亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue.js中怎么實現一個可復用組件

發布時間:2021-07-09 11:29:14 來源:億速云 閱讀:132 作者:Leah 欄目:web開發

Vue.js中怎么實現一個可復用組件,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

構成組件

組件,是一個具有一定功能,且不同組件間功能相對獨立的模塊。組件可以是一個按鈕、一個輸入框、一個視頻播放器等等。

可復用組件,高內聚、低耦合。

那么,什么構成了組件呢。以瀏覽器的原生組件 video 為例,分析一下組件的組成部分。

<video
 src="example.mp4"
 width="320"
 height="240"
 onload="loadHandler"
 onerror="errorHandler">
 Your browser does not support the video tag.
</video>

實例中能看出,組件由狀態、事件和嵌套的片斷組成。狀態,是組件當前的某些數據或屬性,如 video 中的 src、width 和 height。事件,是組件在特定時機觸發一些操作的行為,如 video 在視頻資源加載成果或失敗時會觸發對應的事件來執行處理。片段,指的是嵌套在組件標簽中的內容,該內容會在某些條件下展現出來,如在瀏覽器不支持 video 標簽時顯示提示信息。

在 Vue 組件中,狀態稱為 props,事件稱為 events,片段稱為 slots。組件的構成部分也可以理解為組件對外的接口。良好的可復用組件應當定義一個清晰的公開接口。

  • Props 允許外部環境傳遞數據給組件

  • Events 允許組件觸發外部環境的副作用

  • Slots 允許外部環境將額外的內容組合在組件中。

使用 vue 對 video 組件做拓展,構造出一個支持播放列表的組件 myVideo:

<my-video
 :playlist="playlist"
 width="320"
 height="240"
 @load="loadHandler"
 @error="errorHandler"
 @playnext="nextHandler"
 @playprev="prevHandler">
 <div slot="endpage"></div>
</my-video>

myVideo 組件有著清晰的接口,接收播放列表、播放器寬高等狀態,能夠觸發加載成功或失敗、播放上一個或下一個的事件,并且能自定義播放結束時的尾頁,可用于插入廣告或顯示下一個視頻信息。

組件間通信

在 Vue.js 中,父子組件的關系可以總結為 props down, events up 。父組件通過 props 向下傳遞數據給子組件,子組件通過 events 給父組件發送消息。看看它們是怎么工作的。

Vue.js中怎么實現一個可復用組件

業務無關

命名

組件的命名應該跟業務無關。應該依據組件的功能為組件命名。

例如,一個展示公司部門的列表,把每一項作為一個組件,并命名為 DepartmentItem。這時,有一個需求要展示團隊人員列表,樣式跟剛剛的部門列表一樣。顯然,DepartmentItem 這個名字就不適合了。

因此,可復用組件在命名上應避免跟業務扯上關系,以組件的角色、功能對其命名。Item、ListItem、Cell。可以參考 Bootstrap、ElementUI 等一些 UI 框架的命名。

業務數據無關

可復用組件只負責 UI 上的展示和一些交互以及動畫,如何獲取數據跟它無關,因此不要在組件內部去獲取數據,以及任何與服務端打交道的操作。可復用組件只實現 UI 相關的功能。

組件職責

約束好組件的職責,能讓組件更好地解耦,知道什么功能是組件實現的,什么功能不需要實現。

組件可以分為通用組件(可復用組件)和業務組件(一次性組件)。

可復用組件實現通用的功能(不會因組件使用的位置、場景而變化):

  • UI 的展示

  • 與用戶的交互(事件)

  • 動畫效果

業務組件實現偏業務化的功能:

  • 獲取數據

  • 和 vuex 相關的操作

  • 埋點

  • 引用可復用組件

可復用組件應盡量減少對外部條件的依賴,所有與 vuex 相關的操作都不應在可復用組件中出現。

組件應當避免對其父組件的依賴,不要通過 this.$parent 來操作父組件的示例。父組件也不要通過 this.$children 來引用子組件的示例,而是通過子組件的接口與之交互。

命名空間

可復用組件除了定義一個清晰的公開接口外,還需要有命名空間。命名空間可以避免與瀏覽器保留標簽和其他組件的沖突。特別是當項目引用外部 UI 組件或組件遷移到其他項目時,命名空間可以避免很多命名沖突的問題。

<xl-button></xl-button>
<xl-table></xl-table>
<xl-dialog></xl-dialog>
...

業務組件也可以有命令空間,跟通用組件區分開。這里用 st (section) 來代表業務組件。

<st-recommend></st-recommend>
<st-qq-movie></st-qq-movie>
<st-sohu-series></st-sohu-series>

上下文無關

還是上面那句話,可復用組件應盡量減少對外部條件的依賴。沒有特別需求且單個組件不至于過重的的前提下,不要把一個有獨立功能的組件拆分成若干個小組件。

<table-wrapper>      
 <table-header slot="header" :headers="exampleHeader"></table-header>      
 <table-body slot="body" :body-content="exampleContents"></table-body>     
</table-wrapper>

TableHeader 組件和 TableBody 組件依賴當前的上下文,即 TableWrapper 組件嵌套的環境下。你可以有更好的解決辦法:

<xl-table :headers="exampleHeader" :body-content="exampleContents"></xl-table>

上下文無關原則能夠降低組件使用的門檻。

數據扁平化

定義組件接口時,盡量不要將整個對象作為一個 prop 傳進來。

<!-- 反例 -->
<card :item="{ title: item.name, description: item.desc, poster: item.img }></card>

每個 prop 應該是一個簡單類型的數據。這樣做有下列幾點好處:

  • 組件接口清晰

  • props 校驗方便

當服務端返回的對象中的 key 名稱與組件接口不一樣時,不需要重新構造一個對象

<card
 :title="item.name"
 :description="item.desc"
 :poster="item.img">
</card>

扁平化的 props 能讓我們更直觀地理解組件的接口。

使用自定義事件實現數據的雙向綁定

有時候,對于一個狀態,需要同時從組件內部和組件外部去改變它。

例如,模態框的顯示和隱藏,父組件可以初始化模態框的顯示,模態框組件內部的關閉按鈕可以讓其隱藏。一個好的辦法是,使用自定義事件改變父組件中的值:

<modal :show="show" @showchange="show = argument[0]"></modal>
<!-- Modal.vue -->

<template>
 <div v-show="show">
  <h4>標題</h4>
  <p>內容</p>
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" @click="close">關閉</a>
 </div>
</template>

<script>
 export default {
  props: {
   show: String
  },
  methods: {
   close () {
    this.$emit('input', false)
   }
  }
 }
</script>

用戶點擊關閉按鈕時,Modal 組件發送一個 input 自定義事件給父組件。父組件監聽到 input 事件時,把 show 設置為事件回調的第一個參數。

特別地,當狀態名稱為 value,事件名稱為 input 時,可以使用 v-model 指令語法糖:

<modal :value="show" @input="show = argument[0]"></modal>

等價于

<modal v-model="show"></model>

要讓組件的 v-model 生效,它必須:

  • 接受一個 value 屬性

  • 在有新的 value 時觸發 input 事件

注意:由于每個組件的 input 事件只能用來對一個數據進行雙向綁定,所以當存在多個需要向上同步的數據時,請不要使用 v-model,請使用多個自定義事件,并在父組件中同步新的值。

<modal
 :show="show" @showchange="show = argument[0]"
 :content="content" @contentchange="content = argument[0]">
</model>

使用自定義 watcher 優化 DOM 操作

在開發中,有些邏輯無法使用數據綁定,無法避免需要對 DOM 的操作。例如,視頻的播放需要同步 Video 對象的播放操作及組件內的播放狀態。可以使用自定義 watcher 來優化 DOM 的操作。

<!-- MyVideo.vue -->

<template>
 <div>
  <video ref="video" src="src"></video>
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" @click="togglePlay">{{ playing ? '暫停' : '播放' }}</a>
 </div>
</template>

<script>
 export default {
  props: {
   src: String // 播放地址
  },
  data () {
   return {
    playing: false // 是否正在播放
   }
  },
  watch: {
   // 播放狀態變化時,執行對應操作
   playing (val) {
    let video = this.$refs.video
    if (val) {
     video.play();
    } else {
     video.pause();
    }
   }
  },
  method: {
   // 切換播放狀態
   togglePlay () {
    this.playing = !this.playing
   }
  }
 }
</script>

示例中,自定義 watcher 在監聽到 playing 狀態變化時,會執行播放或暫停操作。遇到對視頻播放狀態的處理時,只需要關注 playing 狀態即可。

項目骨架

單組件不異過重,組件在功能獨立的前提下應該盡量簡單,越簡單的組件可復用性越強。當你實現組件的代碼,不包括CSS,有好幾百行了(這個大小視業務而定),那么就要考慮拆分成更小的組件。

當組件足夠簡單時,就可以在一個更大的業務組件中去自由組合這些組件,實現我們的業務功能。因此,理想情況下,組件的引用層級,只有兩級。業務組件引用通用組件。

我們可以得到一個扁平化的結構。

Vue.js中怎么實現一個可復用組件

在一個龐大的項目當中,組件間的引用關系會更復雜一些。當單頁應用有多個路由,每個路由組件過重,需要拆分模塊時。組件結構會變成下圖這樣。

Vue.js中怎么實現一個可復用組件

按照這個思路構建我們的項目,最后的源代碼目錄結構(不包括構建流程文件):

│ App.vue     # 頂級組件
│ client-entry.js # 前端入口文件
│ config.js    # 配置文件
│ main.js     # 主入口文件
│ 
├─api        # 接口 API
├─assets      # 靜態資源
├─components    # 通用組件
├─directives    # 自定義指令
├─mock       # Mock 數據
├─plugins      # 自定義插件
├─router      # 路由配置
├─sections     # 業務組件
├─store       # Vuex Store
├─utils       # 工具模塊
└─views       # 路由頁面組件

看完上述內容,你們掌握Vue.js中怎么實現一個可復用組件的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

当雄县| 文安县| 梧州市| 云浮市| 翁源县| 洛宁县| 建昌县| 库尔勒市| 苍梧县| 乌审旗| 景宁| 南安市| 北碚区| 东乌珠穆沁旗| 大城县| 隆昌县| 通辽市| 湖南省| 贞丰县| 周至县| 凤庆县| 麦盖提县| 密云县| 高淳县| 浦东新区| 东平县| 新泰市| 兰考县| 巴林右旗| 遵化市| 陆川县| 灵宝市| 平乡县| 两当县| 济阳县| 瑞金市| 历史| 孟州市| 成安县| 英山县| 紫阳县|