Vue学习12--插槽

Vue学习12–插槽

什么是插槽

插槽是子组件提供给父组件使用的一个占位符,用,父组件可以在这个占位符中填充任何模板代码,如HTML,组件等,填充的内容会替换子组件中的slot标签。相当于在子组件中放置了一个占位符,父组件传递进来的html片段会被加载到这个占位符的地方。

简单理解就是,在子组件内占坑,在父组件里填坑。 放在组件元素之间的html片段会被插槽占位符进行加载。

插槽如何使用

1、在子组件中使用插槽组件 指定插槽的名字:
2、使用方:在父组件引入的子组件元素之间直接添加需要传递的html片段:<组件标签> 传递hmtl片段 </组件标签>

还可以指定插槽名字,把html片段放置在指定插槽位置
1)<组件标签><div slot=“插槽名字”></组件标签>
2)<template v-slot:插槽名字=“接收到的数据”></template>

插槽传值:

子向父,插槽是一个slot标签,所以采用属性传值的方式传值

在父组件中使用,在组件元素之间插入html片段,有两种接收数据的方法:
1)slot-scope=“接收到的数据”
2)<template v-slot=“接收到的数据”></template>

注:
1) v-slot只能在template标签里使用,否者会报错。
2) 以上两种方式接收到的数据,都是传递过来对象封装的一个整体对象,哪怕只有一个传递的参数也要通过"."或中括号[]的方式去获取参数的值。

父向子,直接按照正常的父向子传递数据就行。

示例

父组件 index.vue

<template>
    <div>
        <list :columns="columns" :data="data">
            <h3 slot="title">待办列表</h3>
          
          <!-- v-slot只能在template标签里使用 -->
           <template v-slot:state="state">
               <span>
                   {{state.state}}
               </span>
           </template> 

            <div slot="opt" slot-scope="data">
                <button v-if="data.state === '新增'" @click="clickEvt(data.id)">处理</button>
                <button v-else @click="clickEvt(data.id)">激活</button>
            </div>
        </list>
    </div>
</template>

<script>
import List from './component/List.vue'

export default {
  components: { List },
    comments:{List},
    data(){
        return {
            columns:[
                {key: 'title', name: '标题'},
                {key: 'date', name: '时间'},
                {key: 'handler', name: '处理人'},
                {key: 'time', name: '完成时间'},
                // 用状态来演示v-slot插槽传值 
                {slot: 'state', name: '状态'},
                // 用操作来演示常规的指定插槽和插槽传值
                {name: '操作'}
            ],
            data:Array(10).fill("").map((_, i) => {
                return {id:"id-" + i, title:"事件-" + i, handler:"zs", time:new Date(), date:"21-10-28", state:Math.random() > .5 ? "新增" : "完成"}
            })
        }
    },
    methods:{
        clickEvt(id){
           this.data.map(it => {
               if(it.id === id){
                   if(it.state === "新增"){ it.state = "完成"}
                   else {it.state = "新增"}
                   return it
               }
           }); 
        }
    }
    
}
</script>

子组件 List.vue

<template>
    <div>
        <div>
            <slot name="title"/>
        </div>
        <table>
            <thead>
                <tr>
                    <th v-for="col in columns" :key="col.key">{{col.name}}</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="row in data" :key="row.id">
                    <!-- 遍历标题栏的数组, 以标题栏数组的key值作为数据对象的key值(键名),这样来匹配让排盘不错乱 -->
                    <td v-for="col in columns" :key="col.key">
                      <!-- 当col.key的值存在时,就显示当前的值 -->
                        <div v-if="!!col.key">{{row[col.key]}}</div>
                        <div v-else-if="!!col.slot">
                            <slot name='state' :state="row.state"/>
                        </div>
                        <div v-else>
                            <slot name='opt' :id="row.id" :state="row.state"/>
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

<script>
export default {
    props:{
        columns:{
            type:Array,
            required:true
        },
        data:{
            type:Array,
            default:() =>[]
        }
    }

}
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值