神仙都没用 68cd190481 发布 8.0
2025-02-19 11:41:01 +08:00

2117 lines
36 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
description: cl-table 组件示例
globs: *.tsx, *.ts, *.vue
---
## 起步 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>base</el-tag>
<span>起步</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/base.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="起步" width="80%">
<!--【很重要】需要包含在 cl-crud 组件内 -->
<cl-crud ref="Crud">
<cl-row>
<!-- 参数文档查看https://element-plus.org/zh-CN/component/table.html#table-%E5%B1%9E%E6%80%A7 -->
<cl-table ref="Table" stripe></cl-table>
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
// 测试数据,移步到 cl-crud 例子查看
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
// 是否自动计算表格高度,表格高度等于减去上区域和下区域的高度
//【很重要】在弹窗或者上级不确定高度中,设置 autoHeight: false避免显示异常。也可以手动设置最大高度 maxHeight: 500
autoHeight: false,
// 右键菜单,移步到右键菜单示例中查看
contextMenu: ['refresh'],
// 列配置,点击 columns 查看描述
// 更多配置查看 el-table-column 文档https://element-plus.org/zh-CN/component/table.html#table-column-%E5%B1%9E%E6%80%A7
columns: [
{
// 是否为多选框操作列
type: 'selection'
// 是否为序号列
// type: "index"
},
{
// 表头标题
label: '姓名',
// 绑定值
prop: 'name',
// 最小宽度
minWidth: 140
},
{
label: '手机号',
prop: 'phone',
minWidth: 140
},
{
label: '工作',
prop: 'occupation',
// 字典匹配,移步到字典示例中查看
dict: dict.get('occupation'),
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
// 是否排序desc, asc
sortable: 'desc'
}
]
});
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## 多级表头 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>children</el-tag>
<span>多级表头</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/children.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="多级表头" width="80%">
<cl-crud ref="Crud">
<cl-row>
<cl-table ref="Table" />
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
label: '用户信息',
prop: 'baseInfo',
minWidth: 250,
// 配置 children 参数
children: [
{
label: '姓名',
prop: 'name',
minWidth: 140
},
{
label: '手机号',
prop: 'phone',
minWidth: 140
}
]
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
]
});
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## 自定义列展示 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>column-custom</el-tag>
<span>自定义列展示</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/column-custom.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="自定义列展示" width="80%">
<cl-crud ref="Crud">
<cl-row>
<!--【很重要】组件配置,设置为 Table 的 columns也可以自定义 -->
<cl-column-custom :columns="Table?.columns" />
</cl-row>
<cl-row>
<cl-table ref="Table"></cl-table>
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
label: '姓名',
prop: 'name',
minWidth: 140
},
{
label: '手机号',
prop: 'phone',
minWidth: 140
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140
},
{
label: '状态',
prop: 'status',
dict: [
{
label: '启用',
value: 1,
type: 'success'
},
{
label: '禁用',
value: 0,
type: 'danger'
}
],
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
]
});
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## 组件渲染 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>component</el-tag>
<span>组件渲染</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/component/index.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="组件渲染" width="80%">
<cl-crud ref="Crud">
<cl-row>
<cl-table ref="Table"></cl-table>
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
import { ElMessage } from 'element-plus';
import UserInfo from './user-info.vue';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
type: 'selection'
},
{
label: '姓名',
prop: 'name',
minWidth: 140,
//【很重要】组件实例方式渲染
component: {
vm: UserInfo
}
},
{
label: '手机号',
prop: 'phone',
minWidth: 140,
//【很重要】组件名方式渲染
component: {
// 组件名,组件必须全局注册了
name: 'el-input',
// 传入参数
props: {
onChange(val) {
ElMessage.info(val);
}
}
}
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
]
});
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## user-info 示例
```vue
<template>
<div class="user-info">
<cl-avatar :size="36" />
<div class="det">
<p>{{ scope?.name }}</p>
</div>
</div>
</template>
<!-- name 必须填写且唯一 -->
<script setup lang="ts">
defineOptions({
name: 'user-info'
});
const props = defineProps({
prop: String, // 列配置的 prop
scope: null // 列数据
});
</script>
<style lang="scss" scoped>
.user-info {
display: flex;
align-items: center;
.det {
flex: 1;
margin-left: 10px;
text-align: left;
}
}
</style>
```
## 右键菜单 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>context-menu</el-tag>
<span>右键菜单</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/context-menu.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="右键菜单">
<cl-crud ref="Crud">
<cl-row>
<cl-table ref="Table"></cl-table>
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
<!-- 新增、编辑 -->
<cl-upsert ref="Upsert" />
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable, useUpsert } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
import { ElMessage } from 'element-plus';
import { EditPen, MoreFilled } from '@element-plus/icons-vue';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
// 右键菜单配置,为 [] 时则不显示内容
contextMenu: [
'refresh', // 刷新
'check', // 选择行
'edit', // 弹出编辑框
'delete', // 弹出删除提示
'info', // 弹出详情
'order-desc', // 使列倒序
'order-asc', // 使列升序
{
label: '禁用状态',
disabled: true
},
{
label: '带图标',
prefixIcon: EditPen,
suffixIcon: MoreFilled
},
{
label: '超出隐藏,看我有很多字非常多',
ellipsis: true
},
{
label: '多层级',
children: [
{
label: 'A',
children: [
{
label: 'A-1',
callback(done) {
ElMessage.success('点击了A-1');
done();
}
}
]
},
{
label: 'B'
},
{
label: 'C'
}
]
},
// row 行数据
// column 列属性
// event 事件对象
(row, column, event) => {
// 必须返回一个对象
return {
label: '自定义2',
callback(done) {
ElMessage.info('获取中');
setTimeout(() => {
ElMessage.success('Ta 是' + row.name);
// 关闭右键菜单,只有在用到 callback 方法时才需要
done();
}, 500);
}
};
}
],
columns: [
{
type: 'selection'
},
{
label: '姓名',
prop: 'name',
minWidth: 140
},
{
label: '手机号',
prop: 'phone',
minWidth: 140
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
]
});
// cl-upsert 配置,详细移步到 cl-upsert 示例查看
const Upsert = useUpsert({
items: [
{
label: '姓名',
prop: 'name',
component: {
name: 'el-input'
}
},
{
label: '手机号',
prop: 'phone',
component: {
name: 'el-input'
}
},
{
label: '工作',
prop: 'occupation',
component: {
name: 'cl-select',
props: {
tree: true,
checkStrictly: true,
options: dict.get('occupation')
}
}
}
]
});
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## 字典匹配 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>dict</el-tag>
<span>字典匹配</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/dict.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="字典匹配" width="80%">
<cl-crud ref="Crud">
<cl-row>
<cl-table ref="Table" />
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable } from '@cool-vue/crud';
import { computed, reactive, ref } from 'vue';
import { useDict } from '/$/dict';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
const options = reactive({
occupation: [] as { label: string; value: any }[]
});
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
label: '姓名',
prop: 'name',
minWidth: 140
},
{
label: '手机号',
prop: 'phone',
minWidth: 140
},
{
label: '工作',
prop: 'occupation',
//【很重要】字典匹配
// 使用字典模块的 get 方法绑定,菜单地址 /dict/list
dict: dict.get('occupation'),
// 是否使用不同颜色区分
dictColor: true,
minWidth: 140
},
{
label: '等级',
prop: 'occupation',
//【很重要】动态匹配列表的情况,使用 computed
dict: computed(() => options.occupation),
minWidth: 140
},
{
label: '状态',
prop: 'status',
// 自定义匹配列表
dict: [
{
label: '启用',
value: 1,
type: 'success'
},
{
label: '禁用',
value: 0,
type: 'danger'
}
],
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
]
});
const visible = ref(false);
function open() {
visible.value = true;
// 模拟接口获取数据
setTimeout(() => {
options.occupation = [
{
label: 'A',
value: 0
},
{
label: 'B',
value: 1
},
{
label: 'C',
value: 2
},
{
label: 'D',
value: 3
},
{
label: 'E',
value: 4
},
{
label: 'F',
value: 5
}
];
}, 1500);
}
</script>
```
## 数据格式化 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>formatter</el-tag>
<span>数据格式化</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/formatter.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="数据格式化" width="80%">
<cl-crud ref="Crud">
<cl-row>
<cl-table ref="Table" />
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-09-26</span>
</div>
</div>
</template>
<script setup lang="tsx">
import { useCrud, useTable } from '@cool-vue/crud';
import { ref } from 'vue';
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
label: '姓名',
prop: 'name',
minWidth: 140
},
{
label: '手机号',
prop: 'phone',
minWidth: 140,
formatter(row) {
return '📱' + row.phone;
}
},
{
label: '用户信息',
minWidth: 200,
// tsx 方式渲染
// 【很重要】使用 tsx 语法时script 的 lang 一定要设置为 tsx
formatter(row) {
// row 为当前行数据
return (
<el-row>
<cl-avatar size={30} />
<el-text style={{ marginLeft: '10px' }}>{row.name}</el-text>
</el-row>
);
}
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
]
});
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## 隐藏/显示 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>hidden</el-tag>
<span>隐藏/显示</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/hidden.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="隐藏/显示" width="80%">
<cl-crud ref="Crud">
<!--配置一个 tab -->
<el-tabs v-model="active">
<el-tab-pane label="员工" name="user"></el-tab-pane>
<el-tab-pane label="企业" name="company"></el-tab-pane>
</el-tabs>
<cl-row>
<!-- 使用方法 showColumn 显示 -->
<el-button @click="showColumn('account')">显示账号</el-button>
<!-- 使用方法 hideColumn 隐藏 -->
<el-button @click="hideColumn('account')">隐藏账号</el-button>
</cl-row>
<cl-row>
<cl-table ref="Table"></cl-table>
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable } from '@cool-vue/crud';
import { computed, ref } from 'vue';
import { useDict } from '/$/dict';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
// 测试数据,移步到 cl-crud 例子查看
service: 'test'
},
app => {
app.refresh();
}
);
const active = ref('user');
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
label: 'ID',
prop: 'id',
minWidth: 140,
//【很重要】配置 hidden 参数,格式为 boolean 或者 Vue.ComputedRef<boolean>
hidden: computed(() => {
return active.value != 'company';
})
},
{
label: '账号',
prop: 'account',
minWidth: 140,
hidden: true // 默认 false
},
{
label: '姓名',
prop: 'name',
minWidth: 140
},
{
label: '手机号',
prop: 'phone',
minWidth: 140
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
]
});
const visible = ref(false);
function open() {
visible.value = true;
}
function showColumn(prop: string) {
Table.value?.showColumn(prop);
}
function hideColumn(prop: string) {
Table.value?.hideColumn(prop);
}
</script>
```
## 操作栏 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>op</el-tag>
<span>操作栏</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/op.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="操作栏" width="80%">
<cl-crud ref="Crud">
<cl-row>
<cl-table ref="Table">
<!-- 插槽的渲染方式 #[component.name] -->
<template #slot-btns="{ scope }">
<el-button
@click="
() => {
ElMessage.info(scope.row.name);
}
"
>插槽按钮</el-button
>
</template>
</cl-table>
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
<!-- 新增、编辑 -->
<cl-upsert ref="Upsert" />
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable, useUpsert } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
import { ElMessage } from 'element-plus';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
label: '姓名',
prop: 'name',
minWidth: 140
},
{
label: '手机号',
prop: 'phone',
minWidth: 140
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
},
{
//【很重要】type 必须是 op
type: 'op',
width: 410, // 宽度
//【很重要】操作按钮配置edit 和 info 必须搭配 cl-upsert 实现
// edit 编辑,预先获取 service 的 info 接口数据,并带入 cl-upsert 的表单值中
// info 详情cl-upsert 内的组件全部传入 disabled 参数
// delete 删除,调用 service 的 delete 接口删除行数据
buttons: [
{
label: '编辑',
type: 'primary',
onClick({ scope }) {
ElMessage.info(scope.row.name);
}
},
{
label: '删除',
type: 'danger',
onClick({ scope }) {
ElMessage.info(scope.row.name);
}
},
{
label: '更多',
type: 'success',
children: [
{
label: '查看',
onClick({ scope }) {
ElMessage.info(scope.row.name);
}
},
{
label: '禁用',
onClick({ scope }) {
ElMessage.info(scope.row.name);
}
}
]
},
{
name: 'slot-btns'
}
]
}
]
});
// cl-upsert 配置,详细移步到 cl-upsert 示例查看
const Upsert = useUpsert({
items: [
{
label: '姓名',
prop: 'name',
component: {
name: 'el-input'
}
},
{
label: '手机号',
prop: 'phone',
component: {
name: 'el-input'
}
},
{
label: '工作',
prop: 'occupation',
component: {
name: 'cl-select',
props: {
tree: true, // 树形方式选择
checkStrictly: true, // 任意层级都能点
options: dict.get('occupation') // 使用字典数据
}
}
}
]
});
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## 插件的使用 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>plugin</el-tag>
<span>插件的使用</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/plugin/base.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="插件的使用" width="80%">
<cl-crud ref="Crud">
<cl-row>
<cl-table ref="Table" />
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="tsx">
import { useCrud, useTable } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
import { merge } from 'lodash-es';
import { defineComponent } from 'vue';
// 插件:列标签匹配,方便多个列表公用同一个组件
function setColumn(): ClTable.Plugin {
const columns = {
UserInfo: {
label: '用户信息',
minWidth: 200,
component: {
vm: defineComponent({
name: 'user-info',
props: {
scope: null
},
setup(props) {
return () => {
return (
<div>
<p>{props.scope.name}</p>
<p>{props.scope.phone}</p>
</div>
);
};
}
})
}
}
} as { [key: string]: DeepPartial<ClTable.Column> };
return ({ exposed }) => {
function deep(arr: ClTable.Column[]) {
arr.forEach(e => {
if (e.tag) {
merge(e, columns[e.tag]);
}
deep(e.children || []);
});
}
deep(exposed.columns);
};
}
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
type: 'selection'
},
{
tag: 'UserInfo'
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
],
//【很重要】配置插件
plugins: [setColumn()]
});
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## 行编辑 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>row-edit</el-tag>
<span>行编辑</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/plugin/row-edit.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="行编辑" width="80%">
<cl-crud ref="Crud">
<el-text class="mb-4" tag="p">点击姓名、手机号可以进行编辑</el-text>
<cl-row>
<cl-table ref="Table" />
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
import { Plugins } from '/#/crud';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
label: '姓名',
prop: 'name',
minWidth: 140,
// 【很重要】行编辑,默认 el-input
edit: true
},
{
label: '手机号',
prop: 'phone',
minWidth: 140,
// 【很重要】行编辑,开启、关闭
edit: {
enable: true
}
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140,
edit: {
enable: true,
// 【很重要】行编辑,组件配置
component: {
name: 'cl-select',
props: {
options: dict.get('occupation'),
tree: true
}
}
}
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc',
// 【很重要】行编辑,组件配置
edit: {
enable: true,
component: {
name: 'el-date-picker',
props: {
type: 'date',
valueFormat: 'YYYY-MM-DD'
}
}
}
},
{
type: 'op',
buttons: ['delete']
}
],
//【很重要】行编辑插件
plugins: [Plugins.Table.rowEdit()]
});
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## 表头搜索 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>search</el-tag>
<span>表头搜索</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/search.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="表头搜索" width="80%">
<cl-crud ref="Crud">
<cl-row>
<cl-table ref="Table" />
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="tsx">
import { useCrud, useTable } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
import { Plus } from '@element-plus/icons-vue';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
label: '姓名',
prop: 'name',
minWidth: 140,
//【很重要】搜索参数配置
search: {
isInput: false, // 默认false是否输入框模式
value: '', // 默认值
refreshOnChange: true, // 默认false搜索时刷新数据service 的 page 接口请求参数为 { page: 1, [绑定的prop]: 输入值 }
// 自定义渲染组件
component: {
name: 'el-input',
props: {
placeholder: '搜索姓名'
}
}
}
},
{
label: '手机号',
prop: 'phone',
minWidth: 140,
//【很重要】搜索参数配置
search: {
// 是否显示搜索图标
icon: () => <Plus />,
// 自定义渲染组件
component: {
name: 'el-input',
props: {
placeholder: '搜索手机号',
// 自定义 change 事件
onChange(val) {
Crud.value?.refresh({
page: 1,
phone: val
});
}
}
}
}
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140,
//【很重要】搜索参数配置
search: {
// 是否显示搜索图标
icon: () => <cl-svg name="icon-app" size={13} />,
// 自定义渲染组件
component: {
name: 'cl-select',
props: {
placeholder: '搜索工作',
options: dict.get('occupation')
}
}
}
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
]
});
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## 多选框数据 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>selection</el-tag>
<span>多选框数据</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/selection.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="多选框数据" width="80%">
<cl-crud ref="Crud">
<cl-row>
<el-button @click="selectRow">选中2行</el-button>
<el-button :disabled="Table?.selection.length == 0" @click="clear">
取消选择
</el-button>
</cl-row>
<cl-row>
<cl-table ref="Table" />
</cl-row>
<cl-row>
<el-text>已选 {{ Table?.selection.length }} 人</el-text>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh', 'check'],
columns: [
{
type: 'selection'
},
{
label: '姓名',
prop: 'name',
minWidth: 140
},
{
label: '手机号',
prop: 'phone',
minWidth: 140
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
]
});
function selectRow() {
const [a, b] = Table.value?.data || [];
// 选中2个
Table.value?.toggleRowSelection(a);
Table.value?.toggleRowSelection(b);
}
function clear() {
Table.value?.clearSelection();
}
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## 插槽的使用 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>slot</el-tag>
<span>插槽的使用</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/slot.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="插槽的使用" width="80%">
<cl-crud ref="Crud">
<cl-row>
<cl-table ref="Table">
<!--【很重要】必须与 prop 名保持一致格式column-[prop] -->
<template #column-name="{ scope }">
<cl-row type="flex" align="middle">
<cl-avatar :size="36" :style="{ marginRight: '10px' }" />
<el-text>{{ scope.row.name }}</el-text>
</cl-row>
</template>
<template #column-phone="{ scope }"> 📱{{ scope.row.phone }} </template>
</cl-table>
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
headerAlign: 'left',
label: '姓名',
prop: 'name',
minWidth: 140
},
{
label: '手机号',
prop: 'phone',
minWidth: 140
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
]
});
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## 合并行或列 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>span-method</el-tag>
<span>合并行或列</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/span-method.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="合并行或列" width="80%">
<cl-crud ref="Crud">
<cl-row>
<cl-table ref="Table" :span-method="onSpanMethod" />
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
label: '姓名',
prop: 'name',
minWidth: 140
},
{
label: '存款',
prop: 'wages',
minWidth: 140
},
{
label: '手机号',
prop: 'phone',
minWidth: 140
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
]
});
interface SpanMethodProps {
row: any;
column: any;
rowIndex: number;
columnIndex: number;
}
function onSpanMethod({ row, column, rowIndex, columnIndex }: SpanMethodProps) {
// 根据实际业务需求调整返回值 { rowspan, colspan }
if (columnIndex === 0) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1
};
} else {
return {
rowspan: 0,
colspan: 0
};
}
}
}
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```
## 表尾合计行 示例
```vue
<template>
<div class="scope">
<div class="h">
<el-tag size="small" effect="dark" disable-transitions>summary</el-tag>
<span>表尾合计行</span>
</div>
<div class="c">
<el-button @click="open">预览</el-button>
<demo-code :files="['table/summary.vue']" />
<!-- 自定义表格组件 -->
<cl-dialog v-model="visible" title="表尾合计行" width="80%">
<cl-crud ref="Crud">
<cl-row>
<cl-table ref="Table" show-summary :summary-method="getSummaries" />
</cl-row>
<cl-row>
<cl-flex1 />
<cl-pagination />
</cl-row>
</cl-crud>
</cl-dialog>
</div>
<div class="f">
<span class="date">2024-01-01</span>
</div>
</div>
</template>
<script setup lang="ts">
import { useCrud, useTable } from '@cool-vue/crud';
import { ref } from 'vue';
import { useDict } from '/$/dict';
const { dict } = useDict();
// cl-crud 配置
const Crud = useCrud(
{
service: 'test'
},
app => {
app.refresh();
}
);
// cl-table 配置
const Table = useTable({
autoHeight: false,
contextMenu: ['refresh'],
columns: [
{
label: '姓名',
prop: 'name',
minWidth: 140
},
{
label: '存款',
prop: 'wages',
minWidth: 140
},
{
label: '手机号',
prop: 'phone',
minWidth: 140
},
{
label: '工作',
prop: 'occupation',
dict: dict.get('occupation'),
minWidth: 140
},
{
label: '创建时间',
prop: 'createTime',
minWidth: 170,
sortable: 'desc'
}
]
});
function getSummaries() {
return ['合计', '$' + Table.value?.data.reduce((a, b) => a + b.wages, 0)];
}
const visible = ref(false);
function open() {
visible.value = true;
}
</script>
```