本文包含了具名插槽、作用域插槽、jsx语法三种:
Render.vue(很重要,必须有):
<script>
export default {
name: "FreeRender",
functional: true,
props: {
scope:Object,
render: Function
},
render: (h, ctx) => {
console.log(222,ctx.props.render);// 通过打印会发现render函数会自动用h函数进行包裹
return ctx.props.render ? ctx.props.render( ctx.props.scope) : "";
}
};
</script>
Table.vue
<template>
<div>
<el-table :data="tableData" style="width: 100%"
:stripe="stripe" :border="border" :size="size"
v-loading="loading"
@selection-change="handleSelectionChange"
>
<!-- 是否支持复选 -->
<el-table-column v-if="isSelection" width="55" type="selection" />
<el-table-column
:prop="item.param"
:label="item.label"
v-for="(item, index) in tableColumns"
:key="index"
:sortable="item.sortable"
:width="item.width"
>
<template slot-scope="scope">
<div v-if="item.render2">
<Render
:scope='scope.row'
:render="item.render2"
>
</Render>
</div>
<slot v-else-if="item.slotName" :name="item.slotName" :row2="scope.row"></slot>
<span v-else>{{scope.row[item.param]}}</span>
</template>
</el-table-column>
<!-- 操作 -->
<el-table-column v-if="tableOperation.label" :label="tableOperation.label">
<template slot-scope="scope">
<slot :name="tableOperation.param" :scope="scope">
<el-button
size="small"
v-for="(item, index) in tableOperation.btnList"
:key="index"
@click="handleClick(scope.row, item.type)">
{{item.label}}
</el-button>
</slot>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import Render from "@/components/Render";
export default {
name: "Table",
props: {
tableColumns: {
type: Array,
required: true,
default: () => {
return []
}
},
tableData: {
type: Array,
required: true,
default: () => {
return []
}
},
tableOperation: {
type: Object,
default: () => {
return {}
}
},
stripe: {
type: Boolean,
default: true
},
border: {
type: Boolean,
default: true
},
size: {
type: String,
default: 'small'
},
loading: {
type: Boolean,
default: false
},
isSelection: {
type: Boolean,
default: false,
}
},
components:{
Render,
},
data() {
return {
h:'',
}
},
methods: {
handleClick(row, type) {
this.$emit('handleClick', row, type)
},
handleSelectionChange(val) {
this.$emit('handleSelectionChange', val)
}
}
使用Table组件
//html
<Table
:tableData="tableData"
:isSelection="true"
:tableColumns="tableColumns"
:tableOperation="tableOperation"
@handleClick="handleClick"
@handleSelectionChange="handleSelectionChange"
>
<template #infoInput="scope">
<el-input v-model="scope.row2.info"></el-input>
</template>
</Table>
// data & methods
tableData: [
{
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
age: "1",
progress:50,
info:'好好学习',
},
{
date: "2016-05-04",
name: "王小虎",
address: "上海市普陀区金沙江路 1517 弄",
age: "0",
progress:60,
info:'天天向上',
},
{
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄",
age: "1",
progress:70,
info:'为人名服务',
},
{
date: "2016-05-03",
name: "王小虎",
address: "上海市普陀区金沙江路 1516 弄",
age: "1",
progress:80,
info:'为人名服务2',
},
],
tableColumns: [
{
param: "date",
label: "日期",
width: "100",
},
{
param: "name",
label: "姓名",
width: "100",
},
{
param: "address",
label: "地址",
},
{
param: "age",
label: "性别",
render2: (row) => {
return (
<el-radio-group v-model={row.age}>
<el-radio label={"0"}>男</el-radio>
<el-radio label={"1"}>女</el-radio>
</el-radio-group>
);
},
},
{
param:'progress',
label:'进度',
render2:(row)=>{
return(
<el-progress percentage={row.progress}></el-progress>
)
}
},{
param:'info',
label:'信息',
slotName:'infoInput',
}
],
tableOperation: {
label: "操作",
btnList: [
{
label: "删除",
type: "warning",
param: "del",
type: "del",
},
{
label: "新增",
type: "primary",
param: "add",
type: "add",
},
],
},
handleClick(val, type) {
console.log("val1", val);
console.log("type", type);
},
handleSelectionChange(val) {
console.log("val2", val);
},