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)
})

复制代码

才疏学浅,若有问题恳请斧正。

相关文章
相关标签/搜索