Vue做用域插槽 :slot-scope 實例

昨天看vue的官網文檔,在slot-scope這塊不是特別的明白,今天本身作了一個小例子,便於理解。vue

先說一下咱們假設的應用經常使用場景,咱們已經開發了一個代辦事項列表的組件,不少模塊在用,如今要求在不影響已測試經過的模塊功能和展現的狀況下,給已完成的代辦項增長一個對勾效果git

也就是說,代辦事項列表組件要知足一下幾點github

  1. 以前數據格式和引用接口不變,正常展現
  2. 新的功能模塊增長對勾

解決辦法不少,不過爲了解釋組件做用域插槽,咱們就用slot-scope了,寫列一下以前組件的代碼。數組

todo-list.vue 組件bash

<template>
  <ul>
    <li v-for="item in todoList" v-bind:key="item.id">
      <slot v-bind:itemValue = "item" >
         {{ item.test }} 
      </slot>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'todoList',
  props: {
    todos: Array
  },
  data(){
    return {
      todoList:this.todos
    }
  }
}
</script>
複製代碼

組件代碼數據結構

<template>
 <ul>
   <li v-for="item in todoList" v-bind:key="item.id">
     <slot>
        {{ item.test }} 
     </slot>
   </li>
 </ul>
</template>

<script>
export default {
 name: 'todoList',
 props: {
   todos: Array
 },
 data(){
   return {
     todoList:this.todos
   }
 }
}
</script>
複製代碼

父組件代碼app

<template>
 <div id="app">
  <h2>以前組件調用</h2>
  <todo-list v-bind:todos="todosBefore" ></todo-list>
 </div>
</template>

<script>
import todoList from './components/todo-list.vue'

export default {
 name: 'app',
 data:function(){
   return {
     todosBefore:[
       {
         test:'詢問時間',
         id:12312313123
       },
       {
         test:'代辦1',
         id:123123123423423
       },
       {
         test:'愛你地方年末見覅',
         id:12312313123234234
       },
       {
         test:'時間2',
         id:1231231312323333
       },
       {
         test:'師生情是行情',
         id:12313333333
       }
     ]
   }
 },
 components: {
   todoList
 }
}
</script>
複製代碼

展現效果 函數

步驟

爲了實現代辦事項增長對勾效果,咱們要在data中調整數據結構,新增todosAfter數組,並給每一項增長isComplete標識。測試

todosAfter:[
        {
          test:'詢問時間',
          isComplete:true,
          id:12312313123
        },
        {
          test:'代辦1',
          isComplete:false,
          id:123123123423423
        },
        {
          test:'愛你地方年末見覅',
          isComplete:false,
          id:12312313123234234
        },
        {
          test:'時間2',
          isComplete:true,
          id:1231231312323333
        },
        {
          test:'師生情是行情',
          isComplete:true,
          id:12313333333
        }
      ],
複製代碼

理解插槽和數據傳遞

本身在看別人的帖子比較吃力的地方就是弄不清楚這個插槽做用域究竟是什麼,有什麼功能,我用大白話來屢屢思路。 弄清楚兩個問題ui

  1. 插槽solt代碼在哪裏編寫? 固然在父組件內,solt是子組件暴露給父組件的接口,須要父組件傳給子組件
  2. 插槽做用域,做用域插槽字面理解,僅僅只對插槽生效。

那傳遞步驟是

  1. 父組件把數據給子組件,父=>子
  2. 子組件把數據給插槽,並暴露給父組件接口
  3. 父組件調用子組件的插槽slot接口和數據

咱們以前給數據數據增長了isComplete屬性,如今要將子組件item傳遞給插槽,並給父組件暴露數據接口itemValue,重點在 v-bind:itemValue = "item"這一句 。

<template>
  <ul>
    <li v-for="item in todoList" v-bind:key="item.id">
      <slot v-bind:itemValue = "item" >
         {{ item.test }} 
      </slot>
    </li>
  </ul>
</template>
複製代碼

接下來是父組件調用子組件的slot和itemValue數據。

<h2>以前組件調用</h2>
<todo-list v-bind:todos="todosAfter">
    <template slot-scope="slotProps">
        <!-- 打印itemvalue數據-->
        <div style="background:red; border-bottom:2px solid blue;">
            {{slotProps.itemvalue}}
        </div>
        <!-- 根據判斷條件展現對號元素 -->
        <span v-if="slotProps.itemValue.isComplete">✓</span>
        <!-- 顯示代辦事項名稱 -->
        {{ slotProps.itemValue.test }}
    </template>

</todo-list>
複製代碼

效果以下

附實例代碼:github link

總結

其實做用域插槽很相似於入參函數,組件至關於cb,而cb的入參就至關與slotProps接收的參數,只不過名稱和形式變了個樣子。

<!-- 函數 -->
function foo(str,cb){
    var msg = str + '你好';
    cb(msg);
}
<!-- 調用 -->
foo('愚坤',function(msg){
    alert(msg)
})

foo('愚坤',function(msg){
    console.log(msg)
})

複製代碼

才疏學淺,若有問題懇請斧正。

相關文章
相關標籤/搜索