Эх сурвалжийг харах

perf: Form Table Search Descriptions 支持嵌套赋值

kailong321200875 1 жил өмнө
parent
commit
46ddf62d2d

+ 35 - 0
mock/department/index.ts

@@ -101,5 +101,40 @@ export default [
         }
       }
     }
+  },
+  // 保存接口
+  {
+    url: '/department/user/save',
+    method: 'post',
+    timeout: 1000,
+    response: () => {
+      return {
+        data: {
+          code: code,
+          data: 'success'
+        }
+      }
+    }
+  },
+  // 删除接口
+  {
+    url: '/department/user/delete',
+    method: 'post',
+    response: ({ body }) => {
+      const ids = body.ids
+      if (!ids) {
+        return {
+          code: '500',
+          message: '请选择需要删除的数据'
+        }
+      } else {
+        return {
+          data: {
+            code: code,
+            data: 'success'
+          }
+        }
+      }
+    }
   }
 ] as MockMethod[]

+ 8 - 0
src/api/department/index.ts

@@ -8,3 +8,11 @@ export const getDepartmentApi = () => {
 export const getUserByIdApi = (params: DepartmentUserParams) => {
   return request.get<DepartmentUserResponse>({ url: '/department/users', params })
 }
+
+export const deleteUserByIdApi = (ids: string[] | number[]) => {
+  return request.post({ url: '/department/user/delete', data: { ids } })
+}
+
+export const saveUserApi = (data: any) => {
+  return request.post({ url: '/department/user/save', data })
+}

+ 1 - 0
src/api/department/types.ts

@@ -23,6 +23,7 @@ export interface DepartmentUserItem {
   email: string
   createTime: string
   role: string
+  department: DepartmentItem
 }
 
 export interface DepartmentUserResponse {

+ 2 - 1
src/components/Descriptions/src/Descriptions.vue

@@ -6,6 +6,7 @@ import { ref, unref, PropType, computed, defineComponent } from 'vue'
 import { useAppStore } from '@/store/modules/app'
 import { DescriptionsSchema } from './types'
 import { Icon } from '@/components/Icon'
+import { get } from 'lodash-es'
 
 const appStore = useAppStore()
 
@@ -114,7 +115,7 @@ export default defineComponent({
                             default: () =>
                               item.slots?.default
                                 ? item.slots?.default(props.data)
-                                : props.data[item.field]
+                                : get(props.data, item.field)
                           }}
                         </ElDescriptionsItem>
                       )

+ 11 - 1
src/components/Form/src/Form.vue

@@ -318,9 +318,19 @@ export default defineComponent({
             }
 
             const Comp = () => {
+              // 如果field是多层路径,需要转换成对象
+              const fields = item.field.split('.')
+              // 循环fields,绑定v-model
+              const vModel = fields.reduce((prev, next, index) => {
+                if (index === 0) {
+                  return formModel.value[next]
+                }
+                return prev[next]
+              }, {})
+
               return (
                 <Com
-                  vModel={formModel.value[item.field]}
+                  vModel={vModel}
                   ref={(el: any) => setComponentRefMap(el, item.field)}
                   {...(autoSetPlaceholder && setTextPlaceholder(item))}
                   {...setComponentProps(item)}

+ 5 - 3
src/components/Form/src/helper/index.ts

@@ -2,6 +2,7 @@ import { useI18n } from '@/hooks/web/useI18n'
 import { PlaceholderModel, FormSchema, ComponentNameEnum, ColProps } from '../types'
 import { isFunction } from '@/utils/is'
 import { firstUpperCase, humpToDash } from '@/utils'
+import { set, get } from 'lodash-es'
 
 const { t } = useI18n()
 
@@ -143,13 +144,14 @@ export const setItemComponentSlots = (slotsProps: Recordable = {}): Recordable =
 export const initModel = (schema: FormSchema[], formModel: Recordable) => {
   const model: Recordable = { ...formModel }
   schema.map((v) => {
-    // 如果是hidden,就删除对应的值
     if (v.remove) {
       delete model[v.field]
     } else if (v.component && v.component !== 'Divider') {
-      const hasField = Reflect.has(model, v.field)
+      // const hasField = Reflect.has(model, v.field)
+      const hasField = get(model, v.field)
       // 如果先前已经有值存在,则不进行重新赋值,而是采用现有的值
-      model[v.field] = hasField ? model[v.field] : v.value !== void 0 ? v.value : undefined
+      set(model, v.field, hasField ? get(model, v.field) : v.value !== void 0 ? v.value : undefined)
+      // model[v.field] = hasField ? model[v.field] : v.value !== void 0 ? v.value : undefined
     }
   })
   return model

+ 2 - 8
src/components/Icon/src/Icon.vue

@@ -19,8 +19,6 @@ const props = defineProps({
   hoverColor: propTypes.string
 })
 
-const emit = defineEmits(['click'])
-
 const isLocal = computed(() => props.icon.startsWith('svg-icon:'))
 
 const symbolId = computed(() => {
@@ -34,14 +32,10 @@ const getIconifyStyle = computed(() => {
     color
   }
 })
-
-const iconClick = () => {
-  emit('click')
-}
 </script>
 
 <template>
-  <ElIcon :class="prefixCls" :size="size" :color="color" @click="iconClick">
+  <ElIcon :class="prefixCls" :size="size" :color="color">
     <svg v-if="isLocal" aria-hidden="true">
       <use :xlink:href="symbolId" />
     </svg>
@@ -57,7 +51,7 @@ const iconClick = () => {
 .iconify {
   &:hover {
     :deep(svg) {
-      color: v-bind(hoverColor) !important;
+      color: v-bind(hovercolor) !important;
     }
   }
 }

+ 7 - 7
src/components/Table/src/Table.vue

@@ -11,7 +11,7 @@ import { defineComponent, PropType, ref, computed, unref, watch, onMounted } fro
 import { propTypes } from '@/utils/propTypes'
 import { setIndex } from './helper'
 import type { TableProps, TableColumn, Pagination, TableSetProps } from './types'
-import { set } from 'lodash-es'
+import { set, get } from 'lodash-es'
 import { CSSProperties } from 'vue'
 import { getSlot } from '@/utils/tsxHelper'
 import TableActions from './components/TableActions.vue'
@@ -364,10 +364,10 @@ export default defineComponent({
               : props?.slots?.default
               ? props.slots.default(args)
               : v?.formatter
-              ? v?.formatter?.(data.row, data.column, data.row[v.field], data.$index)
+              ? v?.formatter?.(data.row, data.column, get(data.row, v.field), data.$index)
               : isImageUrl
-              ? renderPreview(data.row[v.field])
-              : data.row[v.field]
+              ? renderPreview(get(data.row, v.field))
+              : get(data.row, v.field)
           }
         }
         if (props?.slots?.header) {
@@ -461,10 +461,10 @@ export default defineComponent({
                 : props?.slots?.default
                 ? props.slots.default(args)
                 : v?.formatter
-                ? v?.formatter?.(data.row, data.column, data.row[v.field], data.$index)
+                ? v?.formatter?.(data.row, data.column, get(data.row, v.field), data.$index)
                 : isImageUrl
-                ? renderPreview(data.row[v.field])
-                : data.row[v.field]
+                ? renderPreview(get(data.row, v.field))
+                : get(data.row, v.field)
             }
           }
           if (props?.slots?.header) {

+ 7 - 6
src/components/Table/src/components/TableActions.vue

@@ -62,12 +62,13 @@ export default defineComponent({
       <>
         <div class="text-right h-28px flex items-center justify-end">
           <ElTooltip content={t('common.refresh')} placement="top">
-            <Icon
-              icon="ant-design:sync-outlined"
-              class="cursor-pointer"
-              hover-color="var(--el-color-primary)"
-              onClick={refresh}
-            />
+            <span onClick={refresh}>
+              <Icon
+                icon="ant-design:sync-outlined"
+                class="cursor-pointer"
+                hover-color="var(--el-color-primary)"
+              />
+            </span>
           </ElTooltip>
 
           <ElTooltip content={t('common.size')} placement="top">

+ 20 - 20
src/hooks/web/useCrudSchemas.ts

@@ -13,23 +13,23 @@ export type CrudSchema = Omit<TableColumn, 'children'> & {
 }
 
 interface CrudSearchParams extends Omit<FormSchema, 'field'> {
-  // 是否显示在查询项
-  show?: boolean
+  // 是否隐藏在查询项
+  hidden?: boolean
 }
 
 interface CrudTableParams extends Omit<TableColumn, 'field'> {
-  // 是否显示表头
-  show?: boolean
+  // 是否隐藏表头
+  hidden?: boolean
 }
 
 interface CrudFormParams extends Omit<FormSchema, 'field'> {
-  // 是否显示表单项
-  show?: boolean
+  // 是否隐藏表单项
+  hidden?: boolean
 }
 
 interface CrudDescriptionsParams extends Omit<DescriptionsSchema, 'field'> {
-  // 是否显示表单项
-  show?: boolean
+  // 是否隐藏表单项
+  hidden?: boolean
 }
 
 interface AllSchemas {
@@ -78,17 +78,17 @@ const filterSearchSchema = (crudSchema: CrudSchema[]): FormSchema[] => {
 
   for (let i = 0; i < length; i++) {
     const schemaItem = crudSchema[i]
-    // 判断是否显示
-    if (schemaItem?.search?.show) {
+    // 判断是否隐藏
+    if (!schemaItem?.search?.hidden) {
       const searchSchemaItem = {
-        component: schemaItem.search.component,
+        component: schemaItem?.search?.component || 'Input',
         ...schemaItem.search,
         field: schemaItem.field,
         label: schemaItem.label
       }
 
       // 删除不必要的字段
-      delete searchSchemaItem.show
+      delete searchSchemaItem.hidden
 
       searchSchema.push(searchSchemaItem)
     }
@@ -101,7 +101,7 @@ const filterSearchSchema = (crudSchema: CrudSchema[]): FormSchema[] => {
 const filterTableSchema = (crudSchema: CrudSchema[]): TableColumn[] => {
   const tableColumns = treeMap<CrudSchema>(crudSchema, {
     conversion: (schema: CrudSchema) => {
-      if (schema?.table?.show !== false) {
+      if (!schema?.table?.hidden) {
         return {
           ...schema.table,
           ...schema
@@ -126,17 +126,17 @@ const filterFormSchema = (crudSchema: CrudSchema[]): FormSchema[] => {
 
   for (let i = 0; i < length; i++) {
     const formItem = crudSchema[i]
-    // 判断是否显示
-    if (formItem?.form?.show) {
+    // 判断是否隐藏
+    if (!formItem?.form?.hidden) {
       const formSchemaItem = {
-        component: formItem.form.component,
+        component: formItem?.form?.component || 'Input',
         ...formItem.form,
         field: formItem.field,
         label: formItem.label
       }
 
       // 删除不必要的字段
-      delete formSchemaItem.show
+      delete formSchemaItem.hidden
 
       formSchema.push(formSchemaItem)
     }
@@ -150,8 +150,8 @@ const filterDescriptionsSchema = (crudSchema: CrudSchema[]): DescriptionsSchema[
   const descriptionsSchema: FormSchema[] = []
 
   eachTree(crudSchema, (schemaItem: CrudSchema) => {
-    // 判断是否显示
-    if (schemaItem?.detail?.show !== false) {
+    // 判断是否隐藏
+    if (!schemaItem?.detail?.hidden) {
       const descriptionsSchemaItem = {
         ...schemaItem.detail,
         field: schemaItem.field,
@@ -159,7 +159,7 @@ const filterDescriptionsSchema = (crudSchema: CrudSchema[]): DescriptionsSchema[
       }
 
       // 删除不必要的字段
-      delete descriptionsSchemaItem.show
+      delete descriptionsSchemaItem.hidden
 
       descriptionsSchema.push(descriptionsSchemaItem)
     }

+ 3 - 1
src/locales/en.ts

@@ -494,7 +494,9 @@ export default {
     searchDepartment: 'Search department',
     account: 'Account',
     email: 'Email',
-    createTime: 'Create time'
+    createTime: 'Create time',
+    // 所属部门
+    department: 'Department'
   },
   inputPasswordDemo: {
     title: 'InputPassword',

+ 3 - 1
src/locales/zh-CN.ts

@@ -486,7 +486,9 @@ export default {
     searchDepartment: '搜索部门',
     account: '账号',
     email: '邮箱',
-    createTime: '创建时间'
+    createTime: '创建时间',
+    // 所属部门
+    department: '所属部门'
   },
   inputPasswordDemo: {
     title: '密码输入框',

+ 226 - 47
src/views/Authorization/User.vue

@@ -1,14 +1,17 @@
 <script setup lang="tsx">
 import { ContentWrap } from '@/components/ContentWrap'
 import { useI18n } from '@/hooks/web/useI18n'
-import { Table, TableColumn } from '@/components/Table'
-import { ref, unref, nextTick, watch } from 'vue'
+import { Table } from '@/components/Table'
+import { ref, unref, nextTick, watch, reactive } from 'vue'
 import { ElButton, ElTree, ElInput, ElDivider } from 'element-plus'
-import { getDepartmentApi, getUserByIdApi } from '@/api/department'
+import { getDepartmentApi, getUserByIdApi, saveUserApi, deleteUserByIdApi } from '@/api/department'
 import type { DepartmentItem, DepartmentUserItem } from '@/api/department/types'
 import { useTable } from '@/hooks/web/useTable'
 import { Search } from '@/components/Search'
-import { FormSchema } from '@/components/Form'
+import Write from './components/Write.vue'
+import Detail from './components/Detail.vue'
+import { Dialog } from '@/components/Dialog'
+import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
 
 const { t } = useI18n()
 
@@ -25,16 +28,46 @@ const { tableRegister, tableState, tableMethods } = useTable({
       list: res.data.list || [],
       total: res.data.total || 0
     }
+  },
+  fetchDelApi: async () => {
+    const res = await deleteUserByIdApi(unref(ids))
+    return !!res
   }
 })
 const { total, loading, dataList, pageSize, currentPage } = tableState
-const { getList } = tableMethods
+const { getList, getElTableExpose, delList } = tableMethods
 
-const columns: TableColumn[] = [
+const crudSchemas = reactive<CrudSchema[]>([
+  {
+    field: 'selection',
+    search: {
+      hidden: true
+    },
+    form: {
+      hidden: true
+    },
+    detail: {
+      hidden: true
+    },
+    table: {
+      type: 'selection'
+    }
+  },
   {
     field: 'index',
     label: t('userDemo.index'),
-    type: 'index'
+    form: {
+      hidden: true
+    },
+    search: {
+      hidden: true
+    },
+    detail: {
+      hidden: true
+    },
+    table: {
+      type: 'index'
+    }
   },
   {
     field: 'username',
@@ -44,45 +77,100 @@ const columns: TableColumn[] = [
     field: 'account',
     label: t('userDemo.account')
   },
+  {
+    field: 'department.id',
+    label: t('userDemo.department'),
+    detail: {
+      slots: {
+        default: (data: DepartmentUserItem) => {
+          return <>{data.department.departmentName}</>
+        }
+      }
+    },
+    search: {
+      hidden: true
+    },
+    form: {
+      component: 'TreeSelect',
+      componentProps: {
+        nodeKey: 'id',
+        props: {
+          label: 'departmentName'
+        }
+      },
+      optionApi: async () => {
+        const res = await getDepartmentApi()
+        return res.data.list
+      }
+    },
+    table: {
+      type: 'index'
+    }
+  },
   {
     field: 'role',
-    label: t('userDemo.role')
+    label: t('userDemo.role'),
+    search: {
+      hidden: true
+    }
   },
   {
     field: 'email',
-    label: t('userDemo.email')
+    label: t('userDemo.email'),
+    form: {
+      component: 'Input'
+    },
+    search: {
+      hidden: true
+    }
   },
   {
     field: 'createTime',
-    label: t('userDemo.createTime')
+    label: t('userDemo.createTime'),
+    form: {
+      component: 'Input'
+    },
+    search: {
+      hidden: true
+    }
   },
   {
     field: 'action',
     label: t('userDemo.action'),
-    slots: {
-      default: (data) => {
-        return (
-          <ElButton type="primary" onClick={() => actionFn(data[0].row)}>
-            {t('tableDemo.action')}
-          </ElButton>
-        )
+    form: {
+      hidden: true
+    },
+    detail: {
+      hidden: true
+    },
+    search: {
+      hidden: true
+    },
+    table: {
+      width: 240,
+      slots: {
+        default: (data: any) => {
+          const row = data[0].row as DepartmentUserItem
+          return (
+            <>
+              <ElButton type="primary" onClick={() => action(row, 'edit')}>
+                {t('exampleDemo.edit')}
+              </ElButton>
+              <ElButton type="success" onClick={() => action(row, 'detail')}>
+                {t('exampleDemo.detail')}
+              </ElButton>
+              <ElButton type="danger" onClick={() => delData(row)}>
+                {t('exampleDemo.del')}
+              </ElButton>
+            </>
+          )
+        }
       }
     }
   }
-]
+])
 
-const searchSchema: FormSchema[] = [
-  {
-    field: 'username',
-    label: t('userDemo.username'),
-    component: 'Input'
-  },
-  {
-    field: 'account',
-    label: t('userDemo.account'),
-    component: 'Input'
-  }
-]
+const { allSchemas } = useCrudSchemas(crudSchemas)
 
 const searchParams = ref({})
 const setSearchParams = (params: any) => {
@@ -91,10 +179,6 @@ const setSearchParams = (params: any) => {
   getList()
 }
 
-const actionFn = (data: DepartmentUserItem) => {
-  console.log(data)
-}
-
 const treeEl = ref<typeof ElTree>()
 
 const currentNodeKey = ref('')
@@ -128,6 +212,65 @@ const filterNode = (value: string, data: DepartmentItem) => {
   if (!value) return true
   return data.departmentName.includes(value)
 }
+
+const dialogVisible = ref(false)
+const dialogTitle = ref('')
+
+const currentRow = ref<DepartmentUserItem>()
+const actionType = ref('')
+
+const AddAction = () => {
+  dialogTitle.value = t('exampleDemo.add')
+  currentRow.value = undefined
+  dialogVisible.value = true
+  actionType.value = ''
+}
+
+const delLoading = ref(false)
+const ids = ref<string[]>([])
+
+const delData = async (row?: DepartmentUserItem) => {
+  const elTableExpose = await getElTableExpose()
+  ids.value = row
+    ? [row.id]
+    : elTableExpose?.getSelectionRows().map((v: DepartmentUserItem) => v.id) || []
+  delLoading.value = true
+
+  await delList(unref(ids).length).finally(() => {
+    delLoading.value = false
+  })
+}
+
+const action = (row: DepartmentUserItem, type: string) => {
+  dialogTitle.value = t(type === 'edit' ? 'exampleDemo.edit' : 'exampleDemo.detail')
+  actionType.value = type
+  currentRow.value = { ...row, department: unref(treeEl)?.getCurrentNode() || {} }
+  dialogVisible.value = true
+}
+
+const writeRef = ref<ComponentRef<typeof Write>>()
+
+const saveLoading = ref(false)
+
+const save = async () => {
+  const write = unref(writeRef)
+  const formData = await write?.submit()
+  if (formData) {
+    saveLoading.value = true
+    try {
+      const res = await saveUserApi(formData)
+      if (res) {
+        currentPage.value = 1
+        getList()
+      }
+    } catch (error) {
+      console.log(error)
+    } finally {
+      saveLoading.value = false
+      dialogVisible.value = false
+    }
+  }
+}
 </script>
 
 <template>
@@ -157,20 +300,56 @@ const filterNode = (value: string, data: DepartmentItem) => {
       />
     </ContentWrap>
     <ContentWrap class="flex-[3] ml-20px">
-      <Search :schema="searchSchema" @reset="setSearchParams" @search="setSearchParams" />
-      <div>
-        <Table
-          v-model:current-page="currentPage"
-          v-model:page-size="pageSize"
-          :columns="columns"
-          :data="dataList"
-          :loading="loading"
-          @register="tableRegister"
-          :pagination="{
-            total
-          }"
-        />
+      <Search
+        :schema="allSchemas.searchSchema"
+        @reset="setSearchParams"
+        @search="setSearchParams"
+      />
+
+      <div class="mb-10px">
+        <ElButton type="primary" @click="AddAction">{{ t('exampleDemo.add') }}</ElButton>
+        <ElButton :loading="delLoading" type="danger" @click="delData()">
+          {{ t('exampleDemo.del') }}
+        </ElButton>
       </div>
+      <Table
+        v-model:current-page="currentPage"
+        v-model:page-size="pageSize"
+        :columns="allSchemas.tableColumns"
+        :data="dataList"
+        :loading="loading"
+        @register="tableRegister"
+        :pagination="{
+          total
+        }"
+      />
     </ContentWrap>
+
+    <Dialog v-model="dialogVisible" :title="dialogTitle">
+      <Write
+        v-if="actionType !== 'detail'"
+        ref="writeRef"
+        :form-schema="allSchemas.formSchema"
+        :current-row="currentRow"
+      />
+
+      <Detail
+        v-if="actionType === 'detail'"
+        :detail-schema="allSchemas.detailSchema"
+        :current-row="currentRow"
+      />
+
+      <template #footer>
+        <ElButton
+          v-if="actionType !== 'detail'"
+          type="primary"
+          :loading="saveLoading"
+          @click="save"
+        >
+          {{ t('exampleDemo.save') }}
+        </ElButton>
+        <ElButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</ElButton>
+      </template>
+    </Dialog>
   </div>
 </template>

+ 20 - 0
src/views/Authorization/components/Detail.vue

@@ -0,0 +1,20 @@
+<script setup lang="ts">
+import { PropType } from 'vue'
+import { DepartmentUserItem } from '@/api/department/types'
+import { Descriptions, DescriptionsSchema } from '@/components/Descriptions'
+
+defineProps({
+  currentRow: {
+    type: Object as PropType<DepartmentUserItem>,
+    default: () => undefined
+  },
+  detailSchema: {
+    type: Array as PropType<DescriptionsSchema[]>,
+    default: () => []
+  }
+})
+</script>
+
+<template>
+  <Descriptions :schema="detailSchema" :data="currentRow || {}" />
+</template>

+ 62 - 0
src/views/Authorization/components/Write.vue

@@ -0,0 +1,62 @@
+<script setup lang="ts">
+import { Form, FormSchema } from '@/components/Form'
+import { useForm } from '@/hooks/web/useForm'
+import { PropType, reactive, watch } from 'vue'
+import { DepartmentUserItem } from '@/api/department/types'
+import { useValidator } from '@/hooks/web/useValidator'
+
+const { required } = useValidator()
+
+const props = defineProps({
+  currentRow: {
+    type: Object as PropType<DepartmentUserItem>,
+    default: () => undefined
+  },
+  formSchema: {
+    type: Array as PropType<FormSchema[]>,
+    default: () => []
+  }
+})
+
+const rules = reactive({
+  username: [required()],
+  account: [required()],
+  role: [required()],
+  email: [required()],
+  createTime: [required()]
+})
+
+const { formRegister, formMethods } = useForm()
+const { setValues, getFormData, getElFormExpose } = formMethods
+
+const submit = async () => {
+  const elForm = await getElFormExpose()
+  const valid = await elForm?.validate().catch((err) => {
+    console.log(err)
+  })
+  if (valid) {
+    const formData = getFormData()
+    return formData
+  }
+}
+
+watch(
+  () => props.currentRow,
+  (currentRow) => {
+    if (!currentRow) return
+    setValues(currentRow)
+  },
+  {
+    deep: true,
+    immediate: true
+  }
+)
+
+defineExpose({
+  submit
+})
+</script>
+
+<template>
+  <Form :rules="rules" @register="formRegister" :schema="formSchema" />
+</template>

+ 6 - 12
src/views/Example/Dialog/ExampleDialog.vue

@@ -48,10 +48,10 @@ const crudSchemas = reactive<CrudSchema[]>([
   {
     field: 'selection',
     form: {
-      show: false
+      hidden: true
     },
     detail: {
-      show: false
+      hidden: true
     },
     table: {
       type: 'selection'
@@ -62,21 +62,19 @@ const crudSchemas = reactive<CrudSchema[]>([
     label: t('tableDemo.index'),
     type: 'index',
     form: {
-      show: false
+      hidden: true
     },
     detail: {
-      show: false
+      hidden: true
     }
   },
   {
     field: 'title',
     label: t('tableDemo.title'),
     search: {
-      show: true,
       component: 'Input'
     },
     form: {
-      show: true,
       component: 'Input',
       colProps: {
         span: 24
@@ -94,7 +92,6 @@ const crudSchemas = reactive<CrudSchema[]>([
     field: 'display_time',
     label: t('tableDemo.displayTime'),
     form: {
-      show: true,
       component: 'DatePicker',
       componentProps: {
         type: 'datetime',
@@ -120,7 +117,6 @@ const crudSchemas = reactive<CrudSchema[]>([
       )
     },
     form: {
-      show: true,
       component: 'Select',
       componentProps: {
         style: {
@@ -166,7 +162,6 @@ const crudSchemas = reactive<CrudSchema[]>([
     field: 'pageviews',
     label: t('tableDemo.pageviews'),
     form: {
-      show: true,
       component: 'InputNumber',
       value: 0
     }
@@ -178,7 +173,6 @@ const crudSchemas = reactive<CrudSchema[]>([
       show: false
     },
     form: {
-      show: true,
       component: 'Editor',
       colProps: {
         span: 24
@@ -198,10 +192,10 @@ const crudSchemas = reactive<CrudSchema[]>([
     width: '260px',
     label: t('tableDemo.action'),
     form: {
-      show: false
+      hidden: true
     },
     detail: {
-      show: false
+      hidden: true
     },
     table: {
       slots: {

+ 1 - 21
src/views/Example/Dialog/components/Detail.vue

@@ -2,10 +2,6 @@
 import { PropType } from 'vue'
 import type { TableData } from '@/api/table/types'
 import { Descriptions, DescriptionsSchema } from '@/components/Descriptions'
-import { useI18n } from '@/hooks/web/useI18n'
-import { ElTag } from 'element-plus'
-
-const { t } = useI18n()
 
 defineProps({
   currentRow: {
@@ -20,21 +16,5 @@ defineProps({
 </script>
 
 <template>
-  <Descriptions :schema="detailSchema" :data="currentRow || {}">
-    <template #importance="{ row }: { row: TableData }">
-      <ElTag :type="row.importance === 1 ? 'success' : row.importance === 2 ? 'warning' : 'danger'">
-        {{
-          row.importance === 1
-            ? t('tableDemo.important')
-            : row.importance === 2
-            ? t('tableDemo.good')
-            : t('tableDemo.commonly')
-        }}
-      </ElTag>
-    </template>
-
-    <template #content="{ row }: { row: TableData }">
-      <div v-html="row.content"></div>
-    </template>
-  </Descriptions>
+  <Descriptions :schema="detailSchema" :data="currentRow || {}" />
 </template>

+ 7 - 13
src/views/Example/Page/ExamplePage.vue

@@ -65,10 +65,10 @@ const crudSchemas = reactive<CrudSchema[]>([
   {
     field: 'selection',
     form: {
-      show: false
+      hidden: true
     },
     detail: {
-      show: false
+      hidden: true
     },
     table: {
       type: 'selection'
@@ -79,21 +79,19 @@ const crudSchemas = reactive<CrudSchema[]>([
     label: t('tableDemo.index'),
     type: 'index',
     form: {
-      show: false
+      hidden: true
     },
     detail: {
-      show: false
+      hidden: true
     }
   },
   {
     field: 'title',
     label: t('tableDemo.title'),
     search: {
-      show: true,
       component: 'Input'
     },
     form: {
-      show: true,
       component: 'Input',
       colProps: {
         span: 24
@@ -111,7 +109,6 @@ const crudSchemas = reactive<CrudSchema[]>([
     field: 'display_time',
     label: t('tableDemo.displayTime'),
     form: {
-      show: true,
       component: 'DatePicker',
       componentProps: {
         type: 'datetime',
@@ -137,7 +134,6 @@ const crudSchemas = reactive<CrudSchema[]>([
       )
     },
     form: {
-      show: true,
       component: 'Select',
       componentProps: {
         style: {
@@ -164,7 +160,6 @@ const crudSchemas = reactive<CrudSchema[]>([
     field: 'pageviews',
     label: t('tableDemo.pageviews'),
     form: {
-      show: true,
       component: 'InputNumber',
       value: 0
     }
@@ -173,10 +168,9 @@ const crudSchemas = reactive<CrudSchema[]>([
     field: 'content',
     label: t('exampleDemo.content'),
     table: {
-      show: false
+      hidden: true
     },
     form: {
-      show: true,
       component: 'Editor',
       colProps: {
         span: 24
@@ -191,10 +185,10 @@ const crudSchemas = reactive<CrudSchema[]>([
     width: '260px',
     label: t('tableDemo.action'),
     form: {
-      show: false
+      hidden: true
     },
     detail: {
-      show: false
+      hidden: true
     },
     table: {
       slots: {

+ 1 - 17
src/views/Example/Page/components/Detail.vue

@@ -65,21 +65,5 @@ const schema = reactive<DescriptionsSchema[]>([
 </script>
 
 <template>
-  <Descriptions :schema="schema" :data="currentRow || {}">
-    <template #importance="{ row }: { row: TableData }">
-      <ElTag :type="row.importance === 1 ? 'success' : row.importance === 2 ? 'warning' : 'danger'">
-        {{
-          row.importance === 1
-            ? t('tableDemo.important')
-            : row.importance === 2
-            ? t('tableDemo.good')
-            : t('tableDemo.commonly')
-        }}
-      </ElTag>
-    </template>
-
-    <template #content="{ row }: { row: TableData }">
-      <div v-html="row.content"></div>
-    </template>
-  </Descriptions>
+  <Descriptions :schema="schema" :data="currentRow || {}" />
 </template>

+ 1 - 0
stylelint.config.js

@@ -17,6 +17,7 @@ module.exports = {
       }
     ],
     'media-query-no-invalid': null,
+    'function-no-unknown': null,
     'no-empty-source': null,
     'named-grid-areas-no-invalid': null,
     'unicode-bom': 'never',