feat: vxe/antd可编辑表格适配器 & 可编辑demo
This commit is contained in:
parent
97231de753
commit
c92d6a2b1d
@ -4,7 +4,6 @@ import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||
import { nextTick, onMounted } from 'vue';
|
||||
|
||||
import { JsonPreview } from '@vben/common-ui';
|
||||
import { getPopupContainer } from '@vben/utils';
|
||||
|
||||
import {
|
||||
Button,
|
||||
@ -18,6 +17,16 @@ import {
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
|
||||
/**
|
||||
* 与antdv集成 可以参考这里使用自定义插槽
|
||||
* https://vxetable.cn/other4/#/table/other/antd
|
||||
*/
|
||||
|
||||
const options = ['前端佬', '后端佬', '组长'].map((item) => ({
|
||||
label: item,
|
||||
value: item,
|
||||
}));
|
||||
|
||||
const gridOptions: VxeGridProps = {
|
||||
editConfig: {
|
||||
// 触发编辑的方式
|
||||
@ -32,12 +41,19 @@ const gridOptions: VxeGridProps = {
|
||||
},
|
||||
checkboxConfig: {},
|
||||
editRules: {
|
||||
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '请输入姓名' }],
|
||||
age: [
|
||||
{ required: true, message: '请输入年龄', trigger: 'blur' },
|
||||
{ min: 0, max: 200, message: '年龄必须为1-200' },
|
||||
{ required: true, message: '请输入年龄' },
|
||||
{ type: 'number', min: 0, max: 200, message: '年龄必须为1-200' },
|
||||
],
|
||||
job: [{ required: true, message: '请选择工作' }],
|
||||
phone: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入正确的手机号',
|
||||
pattern: /^1[3-9]\d{9}$/,
|
||||
},
|
||||
],
|
||||
job: [{ required: true, message: '请选择工作', trigger: 'blur' }],
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
@ -61,8 +77,16 @@ const gridOptions: VxeGridProps = {
|
||||
}
|
||||
return <span>{row.name}</span>;
|
||||
},
|
||||
edit: ({ row }) => {
|
||||
return <Input placeholder={'请输入'} v-model:value={row.name} />;
|
||||
edit: (props) => {
|
||||
const { row, $grid } = props;
|
||||
|
||||
return (
|
||||
<Input
|
||||
onChange={() => $grid?.updateStatus(props)}
|
||||
placeholder={'请输入'}
|
||||
v-model:value={row.name}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -78,10 +102,12 @@ const gridOptions: VxeGridProps = {
|
||||
}
|
||||
return <span>{row.age}</span>;
|
||||
},
|
||||
edit: ({ row }) => {
|
||||
edit: (props) => {
|
||||
const { row, $grid } = props;
|
||||
return (
|
||||
<InputNumber
|
||||
class="w-full"
|
||||
onChange={() => $grid?.updateStatus(props)}
|
||||
placeholder={'请输入'}
|
||||
v-model:value={row.age}
|
||||
/>
|
||||
@ -90,8 +116,8 @@ const gridOptions: VxeGridProps = {
|
||||
},
|
||||
},
|
||||
{
|
||||
field: '工作',
|
||||
title: 'job',
|
||||
field: 'job',
|
||||
title: '工作',
|
||||
align: 'left',
|
||||
editRender: {},
|
||||
slots: {
|
||||
@ -101,15 +127,14 @@ const gridOptions: VxeGridProps = {
|
||||
}
|
||||
return <span>{row.job}</span>;
|
||||
},
|
||||
edit: ({ row }) => {
|
||||
const options = ['前端佬', '后端佬', '组长'].map((item) => ({
|
||||
label: item,
|
||||
value: item,
|
||||
}));
|
||||
edit: (props) => {
|
||||
const { row, $grid } = props;
|
||||
|
||||
return (
|
||||
<Select
|
||||
allowClear={true}
|
||||
class="w-full"
|
||||
getPopupContainer={getPopupContainer}
|
||||
onChange={() => $grid?.updateStatus(props)}
|
||||
options={options}
|
||||
placeholder={'请选择'}
|
||||
v-model:value={row.job}
|
||||
@ -118,6 +143,31 @@ const gridOptions: VxeGridProps = {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'phone',
|
||||
title: '手机号',
|
||||
align: 'left',
|
||||
editRender: {},
|
||||
slots: {
|
||||
default: ({ row }) => {
|
||||
if (!row.phone) {
|
||||
return <span class="text-red-500">未填写</span>;
|
||||
}
|
||||
return <span>{row.phone}</span>;
|
||||
},
|
||||
edit: (props) => {
|
||||
const { row, $grid } = props;
|
||||
// 需要手动调用$grid?.updateStatus来更新校验状态
|
||||
return (
|
||||
<Input
|
||||
onChange={() => $grid?.updateStatus(props)}
|
||||
placeholder={'请输入'}
|
||||
v-model:value={row.phone}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
title: '操作',
|
||||
@ -136,18 +186,22 @@ const gridOptions: VxeGridProps = {
|
||||
},
|
||||
},
|
||||
],
|
||||
height: 'auto',
|
||||
// height: 500,
|
||||
keepSource: true,
|
||||
pagerConfig: {
|
||||
enabled: false,
|
||||
},
|
||||
proxyConfig: {
|
||||
enabled: false,
|
||||
enabled: true,
|
||||
},
|
||||
toolbarConfig: {
|
||||
enabled: false,
|
||||
},
|
||||
showOverflow: false,
|
||||
cellConfig: {
|
||||
// 保持高度 防止进入编辑模式会有一个撑开的效果
|
||||
height: 50,
|
||||
},
|
||||
};
|
||||
|
||||
const [BasicTable, tableApi] = useVbenVxeGrid({
|
||||
@ -160,16 +214,19 @@ onMounted(async () => {
|
||||
name: '张三',
|
||||
age: 18,
|
||||
job: '前端佬',
|
||||
phone: '',
|
||||
},
|
||||
{
|
||||
name: '李四',
|
||||
age: 19,
|
||||
job: '后端佬',
|
||||
phone: '',
|
||||
},
|
||||
{
|
||||
name: '王五',
|
||||
age: 20,
|
||||
job: '组长',
|
||||
phone: '',
|
||||
},
|
||||
];
|
||||
await nextTick();
|
||||
@ -187,6 +244,7 @@ async function handleRemove() {
|
||||
|
||||
async function handleValidate() {
|
||||
const result = await tableApi.grid.validate(true);
|
||||
console.log(result);
|
||||
if (result) {
|
||||
message.error('校验失败');
|
||||
} else {
|
||||
@ -210,20 +268,23 @@ function getData() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BasicTable>
|
||||
<template #toolbar-tools>
|
||||
<Space>
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<!--
|
||||
https://github.com/x-extends/vxe-table/issues/1752#issuecomment-1623165630
|
||||
因为编辑表格判断点击单元格之外的元素会取消编辑状态,此时需要事件拦截,
|
||||
vxe-table 提供了更加简单的方法,
|
||||
只需要在弹出框(不属于单元格之内的元素)添加class=vxe-table--ignore-clear 即可,
|
||||
以 element-plus el-select 为例,设置 popper-class 为 "vxe-table--ignore-clear" 可以解决。
|
||||
需要更高级拦截方法可以参考 https://vxetable.cn/#/table/interceptor/api。
|
||||
-->
|
||||
<Space class="vxe-table--ignore-clear">
|
||||
<a-button @click="getData">获取表格数据</a-button>
|
||||
<a-button @click="handleValidate">校验</a-button>
|
||||
<a-button danger @click="handleRemove"> 删除勾选 </a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
v-access:code="['system:config:add']"
|
||||
@click="handleAdd"
|
||||
>
|
||||
{{ $t('pages.common.add') }}
|
||||
</a-button>
|
||||
<a-button type="primary" @click="handleAdd"> 新增一行 </a-button>
|
||||
</Space>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
<BasicTable />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
"@vben/utils": "workspace:*",
|
||||
"@vueuse/core": "catalog:",
|
||||
"@vueuse/motion": "catalog:",
|
||||
"@vxe-ui/plugin-render-antd": "^4.0.18",
|
||||
"echarts": "catalog:",
|
||||
"vue": "catalog:",
|
||||
"vxe-pc-ui": "catalog:",
|
||||
|
||||
@ -6,6 +6,15 @@ import { usePreferences } from '@vben/preferences';
|
||||
|
||||
import { useVbenForm } from '@vben-core/form-ui';
|
||||
|
||||
/**
|
||||
* 该插件提供了在表格中渲染第三方组件,用于兼容 ant-design-vue 组件库
|
||||
*
|
||||
* 解决组件问题(如select浮层与失焦冲突)
|
||||
*
|
||||
* @see https://vxeui.com/other4/#/plugin-render-antd/start/full/npmInstall
|
||||
* @see https://vxetable.cn/other4/#/table/other/antd
|
||||
*/
|
||||
import VxeUIPluginRenderAntd from '@vxe-ui/plugin-render-antd';
|
||||
import {
|
||||
VxeButton,
|
||||
VxeCheckbox,
|
||||
@ -47,6 +56,8 @@ import {
|
||||
|
||||
import { extendsDefaultFormatter } from './extends';
|
||||
|
||||
import '@vxe-ui/plugin-render-antd/dist/style.css';
|
||||
|
||||
// 是否加载过
|
||||
let isInit = false;
|
||||
|
||||
@ -96,6 +107,7 @@ export function initVxeTable() {
|
||||
// VxeUI.component(VxeTextarea);
|
||||
VxeUI.component(VxeTooltip);
|
||||
VxeUI.component(VxeUpload);
|
||||
VxeUI.use(VxeUIPluginRenderAntd);
|
||||
|
||||
isInit = true;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user