vue组件动态插槽实现
最近在公司又开始写一些前端了,现在公司的主流是vue,所以用了vue。在搭框架的时候对基础组件进行了封装,在做公共组件会经常用到插槽(slot),官方文档地址如下
https://cn.vuejs.org/v2/guide/components-slots.html
vue的v-solt
与angular的ngTemplateOutlet
类似,简单来说插槽就是用来填空的地方。简单的用法就不介绍了,主要在我的实践中遇到的动态插槽及通过插槽使用子组件的变量
场景
我在做通用表格组件(common-table)封装的时候需要实现根据列名的列表(columns)生成表的各列,每行默认填充各列对应的值,同时也提供定义特定列的显示,比如在名称列显示要加上转跳(a标签)。 在提供自定义实现上就需要用到插槽,并且列名不确定所以要实现动态插槽。
实现
以下只展示了关于插槽的代码
通用表格组件(common-table)组件
<template>
...
<md-table-row slot="md-table-row" slot-scope="{ item }">
<md-table-cell
v-for="column in columns"
:key="column.index"
:md-label="$t(column.title || column.index)"
:md-sort-by="column.index"
>
<slot :name="'column-' + column.index" v-bind:item="item"></slot>
</md-table-cell>
</md-table-row>
...
</template>
<script>
export default {
name: "common-table",
props: {
tableData: Array,
columns: Array,
}
};
</script>
columns 的数据格式为
[
{
index: String,
title: String
},
...
]
页面组件使用
<template>
...
<common-table
title=""
:tableData="data"
:columns="columns"
>
<template v-slot:column-name="{ item }">
<router-link :to="`/xxx/${item.id}`"></router-link>
</template>
</common-table>
...
</template>
<script>
import { CommonTable } from "@/components";
export default {
components: {
CommonTable
},
computed: {},
data() {
return {
data: [],
columns: [
{ index: "name", title: "Name" },
]
};
}
};
</script>
总结
通过for循环动态生成具名插槽,并绑定变量item
,设置槽的默认显示
<slot :name="'column-' + column.index" v-bind:item="item"></slot>
在父组件可以从子组件获取数据
<!-- 插槽名为column-name,获取变量item -->
<template v-slot:column-name="{ item }">
...
</template>
关于动态插槽名,根据文档貌似可以怎么写(未实践):
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>