国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

從組件封裝看Vue的作用域插槽的實現

2019-11-19 12:09:41
字體:
來源:轉載
供稿:網友

作用域插槽不是那么直觀的一個概念。Vue文檔使用了一段描述性的話來解釋作用域插槽:

有的時候你希望提供的組件帶有一個可從子組件獲取數據的可復用的插槽
……
但是在我們應用的某些部分,我們希望每個獨立的待辦項渲染出和 todo.text 不太一樣的東西。這也是作用域插槽的用武之地。

但在我看來,至少是第一次讀到的時候,這段話相當不好理解。插槽不是分發內容到子組件嗎,為什么還要從子組件中獲取數據?不是已經有了通過emit事件的方法從子組件向父組件傳遞數據嗎,為什么需要它?作用域插槽到底是來干嘛的?……

在瀏覽了不少博客、自己思考“如果不這么做,就會怎么樣”再動手實踐之后,作用域插槽的含義才逐漸明了。其實作用域插槽提供了一種封裝可復用組件的新思路。下面我會從最簡單的例子開始。

簡單的展示列表

現在我們做一個純展示用途的列表組件,如下圖所示:

第一個例子先用slot來分發內容

<template> <div class="list">  <div class="list-title">   <slot name="title"></slot>  </div>  <div class="list-content">   <slot name="content"></slot>  </div> </div></template><script> export default {  name: "MyList" }</script>

在父組件中使用MyList

<template> <MyList>  <span slot="title">title</span>  <ul slot="content">   <li v-for="item in listData">{{item}}</li>  </ul> </MyList></template><script> import myList from './List.vue'; export default {  name: 'HelloWorld',  components: {   'MyList': myList  },  data() {   return {    listData: [      '列表項1',      '列表項2',      '列表項3'    ]   }  } }</script>

省略了其中的樣式代碼,結果如圖所示

滿足了基本的需求,但是作為組件的使用者,這樣的一個組件會讓我覺得非常麻煩,content中循環的邏輯還需要我自己動手來寫,這樣的使用毫無便利性。于是有了下面第二個版本

使用prop來傳遞數據

因為考慮到列表的內容總是一個數組,我把循環結構寫進了組件中

列表組件第二版:

<template> <div class="list">  <div class="list-title">{{title}}</div>  <ul class="list-content">   <li v-for="(item ,index) in content" :key="index">{{item}}</li>  </ul> </div></template><script> export default {  name: "MyList",  props: {   title: {    type: String,    required: true   },   content: {    type: Array,    required: true   }  } }</script>

使用起來也非常方便,只需通過prop將數據傳入組件中

<template> <div>  <MyList title="標題1" :content="listData"></MyList>  <MyList title="標題2" :content="newListData"></MyList> </div></template><script> import myList from './List.vue'; export default {  name: 'HelloWorld',  components: {   'MyList': myList  },  data() {   return {    listData: [      '列表項1',      '列表項2',      '列表項3'    ],    newListData: [      '新的列表項1',      '新的列表項2',      '新的列表項3'    ],   }  } }</script>

改進之后,每當我使用組件只需一行代碼,大大簡化了工作量

易用性的需求也滿足了,但現在又有了新的問題,組件的拓展性不好!每次只能生成相同結構的列表,一旦業務需求發生了變化,組件就不再適用了。比如我現在有了新的需求,在一個列表的每個列表項前加入了一個小logo,我總不可能又寫一個新的組件來適應需求的變化吧?假如需要更多的定制化場景呢?

作用域插槽

這里就有了第三版的列表組件,使用作用域插槽將子組件中的數據傳遞出去 

<template> <div class="list">  <div class="list-title">{{title}}</div>  <ul class="list-content">   <li v-for="(item ,index) in content" :key="index">    <!--這里將content中的每一項數據綁定到slot的item變量上,在父組件中可以獲取到item變量-->    <slot :item="item">{{item}}</slot>   </li>  </ul> </div></template>

使用組件時,將業務所需的content模板傳入

<template> <div>  <MyList title="標題1" :content="listData1"></MyList>  <MyList title="標題2" :content="listData2">   <template slot-scope="scope">    <img :src="scope.item.img" width="20">    <span>{{scope.item.text}}</span>   </template>  </MyList>  <MyList title="標題3" :content="listData3">   <template slot-scope="scope">    <b>{{scope.item.prefix ? '有前綴' : '無前綴'}}</b>    <span>{{scope.item.text}}</span>    <span>{{scope.item.remark}}</span>   </template>  </MyList> </div></template><script> import myList from './List.vue'; export default {  name: 'HelloWorld',  components: {   'MyList': myList  },  data() {   return {    listData1: [     '列表項1',     '列表項2',     '列表項3'    ],    listData2: [     {text: '第二個列表的列表項1', img: 'example.png'},     {text: '第二個列表的列表項2', img: 'example.png'},     {text: '第二個列表的列表項3', img: 'example.png'}    ],    listData3: [     {text: '第三個列表的列表項1', prefix: true, remark: '附加的備注1'},     {text: '第三個列表的列表項2', prefix: false, remark: '附加的備注2'},     {text: '第三個列表的列表項3', prefix: true, remark: '附加的備注3'}    ],   }  } }</script>

實現了定制化的列表

再回到開始的問題,作用域插槽到底是干嘛用的?很顯然,它的作用就如官網所說的一樣:將組件的數據暴露出去。而這么做,給了組件的使用者根據數據定制模板的機會,組件不再是寫死成一種特定的結構。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 瑞金市| 曲麻莱县| 堆龙德庆县| 额尔古纳市| 宁波市| 朔州市| 吴旗县| 西平县| 车致| 清远市| 车致| 综艺| 塘沽区| 满城县| 墨江| 昭苏县| 宽城| 晋州市| 开封县| 安平县| 天全县| 慈溪市| 灵川县| 阜新市| 什邡市| 额尔古纳市| 运城市| 固镇县| 永泰县| 临高县| 鸡西市| 广平县| 临安市| 洱源县| 武宁县| 财经| 铁力市| 台州市| 三穗县| 金山区| 浦江县|