前言
在日常的开发中我们经常会在table中使用各种表单元素 比如:
-
1. 为了验证状态 加入 [switch](https://element.eleme.cn/#/zh-CN/component/switch#) 2. 为了加入操作行加入 [按钮](https://element.eleme.cn/#/zh-CN/component/button#) 3. 为了显示详情加入 [Tooltip 文字提示](https://element.eleme.cn/#/zh-CN/component/tooltip#)
这都是很常见的需求,可不是项目经理给你整活,请善待项目经理 除非忍不住。
当然为了实现上述的这些操作可以通过在Table中加入插槽来实现。
但是没加一个类型你就要多上一个插槽么?那Vue的组件化理念不是白提了,而且不利于封装 (写那么多插槽不累么,还费事)
就在我苦恼怎么去最大程度上封装这些组件的时候,我发现公司提供的组件库,大多数组件都提供了**render函数**
在我想在组件中添加一些没有预设插槽的子组时,我可以很方便的通过render 动态渲染进去,爽到飞起。
正文
这是我实验性封装Table的代码 1.父组件
<template>
<div class="hello">
<my-table :tableData='tableData' :tableColumns="tableColumns">
</my-table>
</div>
</template>
<script>
import Vue from 'vue'
import myTable from './myTable/myTableRender.vue'
export default {
name: 'HelloWorld',
props: {
msg: String
},
components:{
myTable
},
data(){
return {
tableData:[
{name:'张三',age:14}
],
tableColumns:[
{
label:'姓名',
prop:'name'
},
{
label:'年龄',
prop:'age',
render(h,data){
return (
<el-input v-model={data.row.age} placeholder="请输入内容"></el-input>
)
}
}
]
}
}
}
</script>
2.封装的Table
<template>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
v-for="(th,key) in tableColumns"
:key="key"
:prop="th.prop"
:label="th.label"
>
<template slot-scope="scope">
<ex-slot
v-if='th.render'
:render='th.render'
:row='scope.row'
:column='th'
:index='scope.$index'
/>
<!-- 这里可以通过判断 插入一些预设的常用组件 比如数字框、下拉框、按钮等等 -->
<span v-else>{{scope.row[th.prop]}}</span>
</template>
</el-table-column>
</el-table>
</template>
<script>
//////定义一个中间组件////////
/**目的是封装render函数 提供一个空的可以渲染的环境 */
const exSlot={
functional:true,
// props都是一些需要传入的值 当然你也可以选择性的传入一些值 这都是为了render函数可以响应式的调用值
props:{
index:Number,
row:Object,
columns:Object,
render:Function
},
render:(h,data)=>{
// 这里将值封装起来 以便于我们在父组件里调用
const params={
index:data.props.index,
row:data.props.row
}
// columens 代表我们封装的列属性
// row 代表我们真实传入的这一行的数据
if(data.props.columns){
params.columns=data.props.columns
}
return data.props.render(h,params)
}
}
/////////////////////
export default {
data() {
return {}
},
components:{
exSlot
},
props:{
tableData:{
type: Array,
default: function () {
return [];
},
},
tableColumns:{
type: Array,
default: function () {
return [];
},
}
}
}
</script>