动态的控制表格列的展示,
- 可以勾选和取消某一列的显示
- 本地存储上一次的配置
- 表格内容支持通过slot自定义内容
例子1
<script setup>
import { reactive, ref, watch } from "vue";
import one from "./components/one.vue";
import One from "./components/one.vue";
const tableData = [
{
id: 1,
age: "2016-05-03",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
{
id: 2,
age: "2016-05-02",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
{
id: 3,
age: "2016-05-04",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
{
id: 4,
age: "2016-05-01",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
];
const config = {
name: {
label: "name",
prop: "name",
canHidde: false,
},
age: {
label: "age",
prop: "age",
canHidde: false,
},
address: {
label: "address",
prop: "address",
canHidde: false,
redner: One,
},
id: {
label: "id",
prop: "id",
canHidde: true,
},
};
let state = reactive({});
if (localStorage.getItem("state")) {
//JDON.parse()解析时可能会出现解析错误的情况,要使用try catch包裹
try {
// reactive不能直接复制整个对个,可以重新复制reactive
state = reactive(JSON.parse(localStorage.getItem("state")));
} catch (e) {
console.log(e);
}
} else {
Object.keys(config).forEach((key) => {
state[key] = true;
});
}
const setState = (state) => {
localStorage.setItem("state", JSON.stringify(state));
};
watch(state, (val) => {
setState(val);
});
</script>
<template>
<div>
<div v-for="item in Object.keys(state)">
<div>
<span>{{ config[item].label }}</span>
<el-checkbox
v-model="state[item]"
:disabled="config[item].canHidde"
></el-checkbox>
</div>
</div>
<el-table :data="tableData" style="width: 100%">
<template v-for="item in Object.keys(state)" :key="item">
<!---v-bind可以快速绑定多个变量-->
<el-table-column v-bind="config[item]" v-if="state[item]">
<template #header>
<div>
<span>{{ config[item].label }}</span>
<el-checkbox
v-model="state[item]"
:disabled="config[item].canHidde"
></el-checkbox>
</div>
</template>
<template v-if="config[item].redner" #default="scoped">
<component :is="config[item]?.redner" :scoped="scoped"></component>
</template>
</el-table-column>
</template>
</el-table>
</div>
</template>
<style scoped></style>
例子2 ,插槽使用 h函数渲染
模板中的插值语法 {{ }} 的作用是:把表达式的值转换成字符串,插入到 HTML 中。
h() 返回一个 VNode 对象, 让 Vue 把一个 VNode 对象 转成字符串。Vue 内部会尝试 JSON.stringify(vnode),但 VNode 对象中包含循环引用(如 vnode.component.vnode 指回自己),所以就会报错:
<component :is="...">
不仅可以切换组件,还可以直接渲染 VNode
<script setup>
import { reactive, ref, watch, h } from "vue";
const config = {
name: {
label: "name",
prop: "name",
canHidde: false,
},
age: {
label: "age",
prop: "age",
canHidde: false,
},
address: {
label: "address",
prop: "address",
canHidde: false,
render: (scoped) => {
return h(
"div",
{
style: {
color: "red",
},
},
scoped.row.address
);
},
},
id: {
label: "id",
prop: "id",
canHidde: true,
},
};
</script>
<template>
<div>
<el-table :data="tableData" style="width: 100%">
<template v-for="item in Object.keys(state)" :key="item">
<el-table-column v-bind="config[item]" v-if="state[item]">
<template #header>
<div>
<span>{{ config[item].label }}</span>
<el-checkbox
v-model="state[item]"
:disabled="config[item].canHidde"
></el-checkbox>
</div>
</template>
<template v-if="config[item].render" #default="scoped">
<!--{{config[item].render(scoped)}}直接这样使用会报错-->
<component :is="config[item].render(scoped)" />
</template>
</el-table-column>
</template>
</el-table>
</div>
</template>