123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- <template>
- <a-space>
- <a-button @click="onToggleLoading">切换加载</a-button>
- <a-button @click="onToggleDisabled">切换禁用</a-button>
- </a-space>
- <JVxeTable
- ref="tableRef"
- stripe
- toolbar
- rowNumber
- rowSelection
- rowExpand
- resizable
- asyncRemove
- clickSelectRow
- :maxHeight="480"
- :checkboxConfig="{ range: true }"
- :disabledRows="{ input: ['text--16', 'text--18'] }"
- :loading="loading"
- :disabled="disabled"
- :columns="columns"
- :dataSource="dataSource"
- @remove="onJVxeRemove"
- >
- <template #toolbarSuffix>
- <a-button @click="handleTableCheck">表单验证</a-button>
- <a-tooltip placement="top" title="获取值,忽略表单验证" :autoAdjustOverflow="true">
- <a-button @click="onGetData">获取数据</a-button>
- </a-tooltip>
- <a-tooltip placement="top" title="模拟加载1000条数据" :autoAdjustOverflow="true">
- <a-button @click="handleTableSet">设置值</a-button>
- </a-tooltip>
- <a-button @click="onGetSelData">获取选中数据</a-button>
- <a-button @click="onClearSel">清空选中</a-button>
- <a-button @click="onDelFirst">删除第一行数据</a-button>
- <a-button @click="onDelSel">删除选中数据</a-button>
- </template>
- <template #expandContent="props">
- <div style="padding: 20px">
- <span>Hello! My name is: {{ props.row.input }}!</span>
- </div>
- </template>
- <template #myAction="props">
- <a @click="onLookRow(props)">查看</a>
- <a-divider type="vertical" />
- <Popconfirm title="确定删除吗?" @confirm="onDeleteRow(props)">
- <a>删除</a>
- </Popconfirm>
- </template>
- </JVxeTable>
- </template>
- <script lang="ts" setup>
- import { ref } from 'vue';
- // noinspection ES6UnusedImports
- import { Popconfirm } from 'ant-design-vue';
- import { JVxeTypes, JVxeColumn, JVxeTableInstance } from '/@/components/jeecg/JVxeTable/types';
- import { useMessage } from '/@/hooks/web/useMessage';
- import { random } from 'lodash-es';
- import { buildUUID } from '/@/utils/uuid';
- import dayjs from 'dayjs';
- import { pushIfNotExist } from '/@/utils/common/compUtils';
- const { createMessage } = useMessage();
- const tableRef = ref<JVxeTableInstance>();
- const loading = ref(false);
- const disabled = ref(false);
- const columns = ref<JVxeColumn[]>([
- {
- title: 'ID',
- key: 'id',
- type: JVxeTypes.hidden,
- },
- {
- title: '不可编辑',
- key: 'noEdit',
- type: JVxeTypes.normal,
- width: 180,
- defaultValue: 'noEdit-new',
- },
- {
- title: '单行文本',
- key: 'input',
- type: JVxeTypes.input,
- width: 180,
- defaultValue: '',
- placeholder: '请输入${title}',
- validateRules: [
- {
- required: true, // 必填
- message: '请输入${title}', // 显示的文本
- },
- {
- pattern: /^[a-z|A-Z][a-z|A-Z\d_-]*$/, // 正则
- message: '必须以字母开头,可包含数字、下划线、横杠',
- },
- {
- unique: true,
- message: '${title}不能重复',
- },
- {
- handler({ cellValue, row, column }, callback, target) {
- // cellValue 当前校验的值
- // callback(flag, message) 方法必须执行且只能执行一次
- // flag = 是否通过了校验,不填写或者填写 null 代表不进行任何操作
- // message = 提示的类型,默认使用配置的 message
- // target 行编辑的实例对象
- if (cellValue === 'abc') {
- callback(false, '${title}不能是abc'); // false = 未通过校验
- } else {
- callback(true); // true = 通过验证
- }
- },
- message: '${title}默认提示',
- },
- ],
- },
- {
- title: '多行文本',
- key: 'textarea',
- type: JVxeTypes.textarea,
- width: 200,
- },
- {
- title: '数字',
- key: 'number',
- type: JVxeTypes.inputNumber,
- width: 80,
- defaultValue: 32,
- // 【统计列】sum = 求和、average = 平均值
- statistics: ['sum', 'average'],
- },
- {
- title: '下拉框',
- key: 'select',
- type: JVxeTypes.select,
- width: 180,
- // 下拉选项
- options: [
- { title: 'String', value: 'string' },
- { title: 'Integer', value: 'int' },
- { title: 'Double', value: 'double' },
- { title: 'Boolean', value: 'boolean' },
- ],
- // allowInput: true,
- allowSearch: true,
- placeholder: '请选择',
- },
- {
- title: '下拉框_字典',
- key: 'select_dict',
- type: JVxeTypes.select,
- width: 180,
- options: [],
- dictCode: 'sex',
- placeholder: '请选择',
- },
- {
- title: '下拉框_多选',
- key: 'select_multiple',
- type: JVxeTypes.selectMultiple,
- width: 205,
- options: [
- { title: 'String', value: 'string' },
- { title: 'Integer', value: 'int' },
- { title: 'Double', value: 'double' },
- { title: 'Boolean', value: 'boolean' },
- ],
- defaultValue: ['int', 'boolean'], // 多个默认项
- // defaultValue: 'string,double,int', // 也可使用这种方式
- placeholder: '多选',
- },
- {
- title: '下拉框_搜索',
- key: 'select_search',
- type: JVxeTypes.selectSearch,
- width: 180,
- options: [
- { title: 'String', value: 'string' },
- { title: 'Integer', value: 'int' },
- { title: 'Double', value: 'double' },
- { title: 'Boolean', value: 'boolean' },
- ],
- },
- {
- title: '日期时间',
- key: 'datetime',
- type: JVxeTypes.datetime,
- width: 200,
- defaultValue: '2019-04-30 14:52:22',
- placeholder: '请选择',
- },
- {
- title: '时间',
- key: 'time',
- type: JVxeTypes.time,
- width: 200,
- defaultValue: '14:52:22',
- placeholder: '请选择',
- },
- {
- title: '复选框',
- key: 'checkbox',
- type: JVxeTypes.checkbox,
- width: 100,
- customValue: ['Y', 'N'], // true ,false
- defaultChecked: false,
- },
- {
- title: '操作',
- key: 'action',
- type: JVxeTypes.slot,
- fixed: 'right',
- minWidth: 100,
- align: 'center',
- slotName: 'myAction',
- },
- ]);
- const dataSource = ref<any[]>([]);
- /* 随机生成数据 */
- function randomPage(current, pageSize, isLoading = false) {
- if (isLoading) {
- loading.value = true;
- }
- let randomDatetime = () => {
- let time = random(1000, 9999999999999);
- return dayjs(new Date(time)).format('YYYY-MM-DD HH:mm:ss');
- };
- let limit = (current - 1) * pageSize;
- let options = ['string', 'int', 'double', 'boolean'];
- let begin = Date.now();
- let values: any[] = [];
- for (let i = 0; i < pageSize; i++) {
- values.push({
- id: buildUUID(),
- noEdit: `noEdit-${limit + i + 1}`,
- input: `text-${limit + i + 1}`,
- textarea: `textarea-${limit + i + 1}`,
- number: random(0, 233),
- select: options[random(0, 3)],
- select_dict: random(1, 2).toString(),
- select_multiple: (() => {
- let length = random(1, 4);
- let arr = [];
- for (let j = 0; j < length; j++) {
- pushIfNotExist(arr, options[random(0, 3)]);
- }
- return arr.join(',');
- })(),
- select_search: options[random(0, 3)],
- datetime: randomDatetime(),
- checkbox: ['Y', 'N'][random(0, 1)],
- });
- }
- dataSource.value = values;
- let end = Date.now();
- let diff = end - begin;
- if (isLoading && diff < pageSize) {
- setTimeout(() => (loading.value = false), pageSize - diff);
- }
- }
- randomPage(0, 20, true);
- function onLookRow(props) {
- createMessage.success('请在控制台查看输出');
- // 参数介绍:
- // props.value 当前单元格的值
- // props.row 当前行的数据
- // props.rowId 当前行ID
- // props.rowIndex 当前行下标
- // props.column 当前列的配置
- // props.columnIndex 当前列下标
- // props.$table vxe实例,可以调用vxe内置方法
- // props.target JVXE实例,可以调用JVXE内置方法
- // props.caseId JVXE实例唯一ID
- // props.scrolling 是否正在滚动
- // props.triggerChange 触发change事件,用于更改slot的值
- console.log('查看: ', { props });
- }
- async function onDeleteRow(props) {
- // 调用删除方法
- const res = await tableRef.value?.removeRows(props.row);
- if (res && res.rows.length > 0) {
- createMessage.success('删除成功');
- }
- }
- function handleValueChange(event) {
- console.log('handleValueChange.event: ', event);
- }
- /** 表单验证 */
- function handleTableCheck() {
- tableRef.value!.validateTable().then((errMap) => {
- if (errMap) {
- console.log('表单验证未通过:', { errMap });
- createMessage.error('验证未通过,请在控制台查看详细');
- } else {
- createMessage.success('验证通过');
- }
- });
- }
- /** 获取值,忽略表单验证 */
- function onGetData() {
- const values = tableRef.value!.getTableData();
- console.log('获取值:', { values });
- createMessage.success('获取值成功,请看控制台输出');
- }
- /** 模拟加载1000条数据 */
- function handleTableSet() {
- randomPage(1, 1000, true);
- }
- function onDelFirst() {
- const xTable = tableRef.value!.getXTable();
- const record = xTable.getTableData().fullData[0];
- tableRef.value!.removeRows(record);
- }
- function onDelSel() {
- const xTable = tableRef.value!.getXTable();
- xTable.removeCheckboxRow();
- }
- function onGetSelData() {
- createMessage.info('请看控制台');
- console.log(tableRef.value!.getSelectionData());
- }
- function onClearSel() {
- tableRef.value!.clearSelection();
- }
- function onToggleLoading() {
- loading.value = !loading.value;
- }
- function onToggleDisabled() {
- disabled.value = !disabled.value;
- }
- function doDelete(deleteRows) {
- return new Promise((resolve) => {
- let rowId = deleteRows.map((row) => row.id);
- console.log('删除 rowId: ', rowId);
- setTimeout(() => resolve(true), 1500);
- });
- }
- /** 异步删除示例 */
- async function onJVxeRemove(event) {
- const hideLoading = createMessage.loading('删除中…', 0);
- try {
- // 1. 向后台传递 event.deleteRows 以删除
- let flag = await doDelete(event.deleteRows);
- if (flag) {
- // 注:如果启用了表格的 loading 状态,则必须先停止再删除,否则会导致无法从表格上删除数据
- // 2. 调用 event.confirmRemove 方法确认删除成功
- await tableRef.value!.removeSelection();
- // await event.confirmRemove()
- createMessage.success('删除成功!');
- } else {
- // 3. 若删除失败,不调用 event.confirmRemove() 方法就不会删除数据
- createMessage.warn('删除失败!');
- }
- } finally {
- hideLoading();
- }
- }
- </script>
|