vben admin配置详解(Table, Form)

vben这个后台管理系统的框架,基于ant-design-vue组件库封装了很多好用的组件,我们在日常开发中用的最多的就是Table, Form组件了。下面就简单介绍一下。

监听菜单折叠:

const { getCollapsed } = useMenuSetting();
  const isCollapsed = ref(false);
  watch(
    getCollapsed,
    (val) => {
      isCollapsed.value = val;
    },
    { immediate: true },
  );

获取当前语言类型

获取当前语言类型,然后做一些事情。比如设置不同的样式,调整UI。

import { useLocaleStoreWithOut } from '/@/store/modules/locale';
  // 获取当前语言
  const localeStore = useLocaleStoreWithOut();
  const locale = localeStore.getLocale;

  const localeClass = computed(() => {
    return locale === 'en' ? 'en-item mrb-15' : 'item mrb-15';
  });

或者这种

import { useLocale } from '/@/locales/useLocale';
  
  const { getAntdLocale } = useLocale();
  const locale = getAntdLocale.value.locale;
监听语言切换做UI处理
// 监听语言切换,修改ui
 
import { useLocaleStoreWithOut } from '/@/store/modules/locale';
// 获取当前语言
const localeStore = useLocaleStoreWithOut();
const locale = localeStore.getLocale;

export default function isEnLocale() {
  return locale === 'en';
}

权限设置

多个权限是或者的关系。

v-auth指令,指定唯一值。内部也是调用hasPermission去做判断的。不可以动态添加判断。
hasPermission动态添加去做判断。结合v-if, v-show做显示隐藏。

import { usePermission } from '/@/hooks/web/usePermission';
 const { hasPermission } = usePermission();
 
 if (!hasPermission(['xxx1', 'xxx2'])) {
      createMessage.info('暂无查看权限! ');
      return;
    }

开启页面缓存

链接

vben全局注册组件

input
layout
button-group
button (vben自己封装的) 组件名称a-button
preIcon,前置图标
postIcon后置图标 内部也提供默认插槽。

<a-button> <plus-outlined /> 新增 </a-button>

useTable返回的配置对象

// 设置加载loading
  setLoading,
  // 更改column.这里一般需要设置固定列时会用到. useAutoFixed. (默认index是默认固定的)
  // useAutoFixed('projectName', tableColumns, setColumns);
  // 设置表格列属性。
  setColumns,
  // 获取列属性。当前表格列配置的columns,并且增加一些默认值。
  getColumns,
  // 获取data数据。获取当前表格所有数据(不管是当前表格有没有展示)
  getDataSource,
  // 获取接口的原始数据。获取接口的返回值,返回啥格式就获取啥格式。
  getRawDataSource,
  // 重新出发接口请求.需要传递请求参数
  reload,
  // 获取分页信息
  getPaginationRef,
  // 设置页码 {count} 可以用于设置不使用分页的数据,我只想要设置总数据。用于dataSource,注意pageSize默认值是20。数据量超过20,就会自动分页,所以我们需要将pageSize设置大一点。
  setPagination,
  // 获取选中行列表。拿到当前选中的记录(所有的行数据),传递给后端。
  getSelectRows,
  // 获取选中行 rowKey。拿到所有的key就可以传递给后端做处理
  getSelectRowKeys,
  // 手动设置选中行
  setSelectedRowKeys,
  // 清空选中行
  clearSelectedRowKeys,
  // 设置表格参数。设置表格的任何配置
  setProps,
  // 重新计算表格高度 (暂时不知道有啥效果)
  redoHeight,
  // 设置表格数据 (这个可以用于设置给定dataSource更新数据)
  setTableData,
  // 根据 key 删除取消选中行。个人感觉没啥用。
  deleteSelectRowByKey,
  // 更新表格数据(单条数据单个值) 异步方法 (index: number, key: string, value: any) 指定哪个记录更新哪个字段值
  updateTableData,
  // 根据唯一的rowKey 动态删除指定行的数据.可用于不刷新整个表格而局部更新数据
  deleteTableDataRecord,
  // 可根据传入的 index 值决定插入数据行的位置,不传则是顺序插入,可用于不刷新整个表格而局部更新数据
  insertTableDataRecord,
  // 根据唯一的 rowKey 更新指定行的数据.可用于不刷新整个表格而局部更新数据
  updateTableDataRecord,
  // 获取勾选框信息 selectedRowKeys属性可以拿到选中行的key
  getRowSelection,
  // 如果开启了搜索区域。可以通过该函数获取表单对象函数进行操作
  getForm,
  // 设置是否显示分页
  setShowPagination,
  // 获取当前是否显示分页
  getShowPagination,
  // 展开树形表格
  expandAll,
  // 折叠树形表格
  collapseAll,

reload

参数类型

export interface FetchParams {
  searchInfo?: Recordable;
  page?: number;
  sortInfo?: Recordable;
  filterInfo?: Recordable;
}

searchInfo、filterInfo、sortInfo内容会被结构出来,放在同一层传递出去。目的是为了更好地区分吧。
在这里插入图片描述

updateTableData
(index: number, key: string, value: any)

更新表格数据(单条数据单个值) 异步方法指定哪个记录更新哪个字段值。

getForm
获取搜索区域对象,做一些操作比如表单校验。
在这里插入图片描述

BasicTableProps useTable 参数

export interface BasicTableProps<T = any> {
  // 是否可以点击行选中
  clickToRowSelect?: boolean;
  // 树形表格设置为true
  isTreeTable?: boolean;
  // 自定义排序方法
  sortFn?: (sortInfo: SorterResult) => any;
  // 自定义过滤方法(这个没用过)
  filterFn?: (data: Partial<Recordable<string[]>>) => any;
  // 取消表格的默认padding
  inset?: boolean;
  // 显示表格设置 (表头右侧区域操作栏)
  showTableSetting?: boolean;
  // 单独设置表格操作项
  tableSetting?: TableSetting;
  // 斑马纹
  striped?: boolean;
  // 是否自动生成key
  autoCreateKey?: boolean;
  // 计算合计行的方法
  summaryFunc?: (...arg: any) => Recordable[];
  // 自定义合计表格内容
  summaryData?: Recordable[];
  // 是否显示合计行
  showSummary?: boolean;
  // 是否可拖拽列
  canColDrag?: boolean;
  // 接口请求对象
  api?: (...arg: any) => Promise<any>;
  // 请求之前处理参数
  beforeFetch?: Fn;
  // 自定义处理接口返回参数
  afterFetch?: Fn;
  // 查询条件请求之前处理。这个是开启表单查询时生效
  handleSearchInfoFn?: Fn;
  // 接口请求配置,可以配置请求的字段和响应的字段名。
  fetchSetting?: Partial<FetchSetting>;
  // 立即请求接口
  immediate?: boolean;
  // 在开起搜索表单的时候,如果没有数据是否显示表格
  emptyDataIsShowTable?: boolean;
  // 额外的请求参数。该参数会合并到请求params
  searchInfo?: Recordable;
  // 默认的排序参数
  /**
   * {
        field: 'name',
        order: 'ascend',
      }
   */
  defSort?: Recordable;
  // 使用搜索表单
  useSearchForm?: boolean;
  // 表单配置
  formConfig?: Partial<FormProps>;
  // 列配置
  columns: BasicColumn[];
  // 是否显示序号列
  showIndexColumn?: boolean;
  // 序号列配置
  indexColumnProps?: BasicColumn;
  // 操作列配置
  /**
   * actionColumn: {
      width: 100,
      title: '操作',
      dataIndex: 'action',
    },
   */
  actionColumn?: BasicColumn;
  // 文本超过宽度是否显示省略号
  ellipsis?: boolean;
  // 是否可以自适应高度
  canResize?: boolean;
  // 自适应高度偏移, 计算结果-偏移量
  resizeHeightOffset?: number;

  // 切换页码是否重置勾选状态
  clearSelectOnPageChange?: boolean;
  // 设置主键属性 (好像没有效果)
  rowKey?: string | ((record: Recordable) => string);
  // 数据,不请求接口时,提供的数据列表
  dataSource?: Recordable[];
  // 标题右侧提示
  titleHelpMessage?: string | string[];
  // 表格最大高度,超出会显示滚动条
  maxHeight?: number;
  // 是否显示边框
  bordered?: boolean;
  // 分页配置
  pagination?: PaginationProps | boolean;
  // loading加载
  loading?: boolean;

  /**
   * The column contains children to display
   * @default 'children'
   * @type string | string[]
   */
  childrenColumnName?: string;

  /**
   * Override default table elements
   * @type object
   */
  components?: object;

  /**
   * Expand all rows initially
   * @default false
   * @type boolean
   */
  defaultExpandAllRows?: boolean;

  /**
   * Initial expanded row keys
   * @type string[]
   */
  defaultExpandedRowKeys?: string[];

  /**
   * Current expanded row keys
   * @type string[]
   */
  expandedRowKeys?: string[];

  /**
   * Expanded container render for each row
   * @type Function
   */
  expandedRowRender?: (record?: ExpandedRowRenderRecord<T>) => VNodeChild | JSX.Element;

  /**
   * Customize row expand Icon.
   * @type Function | VNodeChild
   */
  expandIcon?: Function | VNodeChild | JSX.Element;

  /**
   * Whether to expand row by clicking anywhere in the whole row
   * @default false
   * @type boolean
   */
  expandRowByClick?: boolean;

  /**
   * The index of `expandIcon` which column will be inserted when `expandIconAsCell` is false. default 0
   */
  expandIconColumnIndex?: number;

  /**
   * Table footer renderer
   * @type Function | VNodeChild
   */
  footer?: Function | VNodeChild | JSX.Element;

  /**
   * Indent size in pixels of tree data
   * @default 15
   * @type number
   */
  indentSize?: number;

  /**
   * i18n text including filter, sort, empty text, etc
   * @default { filterConfirm: 'Ok', filterReset: 'Reset', emptyText: 'No Data' }
   * @type object
   */
  locale?: object;

  /**
   * Row's className
   * @type Function
   */
  rowClassName?: (record: TableCustomRecord<T>, index: number) => string;

  /**
   * Row selection config
   * @type object
   */
  rowSelection?: TableRowSelection;

  /**
   * Set horizontal or vertical scrolling, can also be used to specify the width and height of the scroll area.
   * It is recommended to set a number for x, if you want to set it to true,
   * you need to add style .ant-table td { white-space: nowrap; }.
   * @type object
   */
  scroll?: { x?: number | true; y?: number };

  /**
   * Whether to show table header
   * @default true
   * @type boolean
   */
  showHeader?: boolean;

  /**
   * Size of table
   * @default 'default'
   * @type string
   */
  size?: SizeType;

  /**
   * Table title renderer
   * @type Function | ScopedSlot
   */
  title?: VNodeChild | JSX.Element | string | ((data: Recordable) => string);

  /**
   * Set props on per header row
   * @type Function
   */
  customHeaderRow?: (column: ColumnProps, index: number) => object;

  /**
   * Set props on per row
   * @type Function
   */
  customRow?: (record: T, index: number) => object;

  /**
   * `table-layout` attribute of table element
   * `fixed` when header/columns are fixed, or using `column.ellipsis`
   *
   * @see https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout
   * @version 1.5.0
   */
  tableLayout?: 'auto' | 'fixed' | string;

  /**
   * the render container of dropdowns in table
   * @param triggerNode
   * @version 1.5.0
   */
  getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;

  /**
   * Data can be changed again before rendering.
   * The default configuration of general user empty data.
   * You can configured globally through [ConfigProvider](https://antdv.com/components/config-provider-cn/)
   *
   * @version 1.5.4
   */
  transformCellText?: Function;

  /**
   * Callback executed before editable cell submit value, not for row-editor
   *
   * The cell will not submit data while callback return false
   */
  beforeEditSubmit?: (data: {
    record: Recordable;
    index: number;
    key: string | number;
    value: any;
  }) => Promise<any>;

  /**
   * Callback executed when pagination, filters or sorter is changed
   * @param pagination
   * @param filters
   * @param sorter
   * @param currentDataSource
   */
  onChange?: (pagination: any, filters: any, sorter: any, extra: any) => void;

  /**
   * Callback executed when the row expand icon is clicked
   *
   * @param expanded
   * @param record
   */
  onExpand?: (expande: boolean, record: T) => void;

  /**
   * Callback executed when the expanded rows change
   * @param expandedRows
   */
  onExpandedRowsChange?: (expandedRows: string[] | number[]) => void;

  onColumnsChange?: (data: ColumnChangeParam[]) => void;
}

sortFn 排序

export interface SorterResult {
  column: ColumnProps;
  order: SortOrder;
  field: string;
  columnKey: string;
}

// 参数可以拿到对应字段的一些内容
sortFn(sortInfo: SorterResult) {
  const sortMap = {
    inviteBidTime: 'invite_bid_time',
    openBidTime: 'open_bid_time',
  };

  const { order, columnKey } = sortInfo;
  return {
    field: sortMap[columnKey],
    order,
  };
},

单元格列属性还需要配置

sorter: true,
sortDirections: ['descend', 'ascend'],

tableSetting
单独设置表格操作项。在showTableSetting设置为true时生效。

export interface TableSetting {
  redo?: boolean;
  size?: boolean;
  setting?: boolean;
  fullScreen?: boolean;
}


showTableSetting: true,
tableSetting: {
  redo: true,
  setting: false,
},

api

defSort, sortFn, pageSize, page等等参会被作为请求参数。
/**
 *
 * 会将defSort, pageSize, page传入,作为默认值
 */
api: (params) => {
  console.log('============', params);
  return demoListApi(params);
},

在这里插入图片描述

beforeFetch 处理请求数据

// 处理请求数据
beforeFetch(params) {
  console.log('params', params);
},

afterFetch 处理响应数据

// 处理响应数据
afterFetch(params) {
  console.log('params====响应', params);
},

pagination 分页
可以用于设置不使用分页的数据,我只想要设置总数据。用于dataSource,注意pageSize默认值是20。数据量超过20,就会自动分页,所以我们需要将pageSize设置大一点。
在这里插入图片描述

export interface PaginationProps {
  /**
   * total number of data items
   * @default 0
   * @type number
   */
  total?: number;

  /**
   * default initial page number
   * @default 1
   * @type number
   */
  defaultCurrent?: number;

  /**
   * current page number
   * @type number
   */
  current?: number;

  /**
   * default number of data items per page
   * @default 10
   * @type number
   */
  defaultPageSize?: number;

  /**
   * number of data items per page
   * @type number
   */
  pageSize?: number;

  /**
   * Whether to hide pager on single page
   * @default false
   * @type boolean
   */
  hideOnSinglePage?: boolean;

  /**
   * determine whether pageSize can be changed
   * @default false
   * @type boolean
   */
  showSizeChanger?: boolean;

  /**
   * specify the sizeChanger options
   * @default ['10', '20', '30', '40']
   * @type string[]
   */
  pageSizeOptions?: string[];

  /**
   * determine whether you can jump to pages directly
   * @default false
   * @type boolean
   */
  showQuickJumper?: boolean | object;

  /**
   * to display the total number and range
   * @type Function
   */
  showTotal?: (total: number, range: [number, number]) => any;

  /**
   * specify the size of Pagination, can be set to small
   * @default ''
   * @type string
   */
  size?: string;

  /**
   * whether to setting simple mode
   * @type boolean
   */
  simple?: boolean;

  /**
   * to customize item innerHTML
   * @type Function
   */
  itemRender?: (props: PaginationRenderProps) => VNodeChild | JSX.Element;
}

BasicColumn 列配置

export interface BasicColumn extends ColumnProps {
  children?: BasicColumn[];
  filters?: {
    text: string;
    value: string;
    children?:
      | unknown[]
      | (((props: Record<string, unknown>) => unknown[]) & (() => unknown[]) & (() => unknown[]));
  }[];

  // 当前列展示的类型
  flag?: 'INDEX' | 'DEFAULT' | 'CHECKBOX' | 'RADIO' | 'ACTION';
  customTitle?: VueNode;

  slots?: Recordable;

  // Whether to hide the column by default, it can be displayed in the column configuration
  // 隐藏列
  defaultHidden?: boolean;

  // Help text for table column header
  // 表头右侧移入的提示文字
  helpMessage?: string | string[];

  // 格式化,例如时间格式化。可以拿到当前单元格或者行的记录
  format?: CellFormat;

  // Editable
  // 是否开启单元格编辑
  edit?: boolean;
  // 是否开启行编辑
  editRow?: boolean;
  // 是否默认处于编辑状态
  editable?: boolean;
  // 编辑组件 。默认是input
  editComponent?: ComponentType;
  // 编辑是组件需要的props,例如ApiSelect组件需要options,所以就需要传递api参数,请求数据然后传递
  editComponentProps?: Recordable;
  // 编辑项的验证规则
  /**
   * {
        required: true,
        validator: async (rule, value) => {
          if (!value) {
            return Promise.reject('请输入xxx');
          }
          if (value && value.length > 100) {
            return Promise.reject('最大不能超过100个字');
          }
          return Promise.resolve();
        },
        trigger: 'change',
      },
   */
  editRule?: boolean | ((text: string, record: Recordable) => Promise<string>);
  // 对应单元格值枚举 没啥用
  editValueMap?: (value: any) => string;
  // 开启editRow后,依旧没有效果。
  onEditRow?: () => void;
  // 权限编码控制是否显示
  auth?: RoleEnum | RoleEnum[] | string | string[];
  // 业务控制是否显示。动态控制显隐
  ifShow?: boolean | ((column: BasicColumn) => boolean);
}

export interface ColumnProps<T> {
  /**
   * specify how content is aligned
   * @default 'left'
   * @type string
   */
  align?: 'left' | 'right' | 'center';

  /**
   * ellipsize cell content, not working with sorter and filters for now.
   * tableLayout would be fixed when ellipsis is true.
   * @default false
   * @type boolean
   */
  ellipsis?: boolean;

  /**
   * Span of this column's title
   * 表头合并
   * @type number
   */
  colSpan?: number;

  /**
   * Display field of the data record, could be set like a.b.c
   *
   * 列数据在数据项中对应的 key,支持 a.b.c 的嵌套写法
   *
   * @type string
   */
  dataIndex?: string;

  /**
   * Default filtered values
   * @type string[]
   */
  defaultFilteredValue?: string[];

  /**
   * Default order of sorted values: 'ascend' 'descend' null
   *
   * 默认排序规则
   *
   *  @type string
   */
  defaultSortOrder?: SortOrder;

  /**
   * Customized filter overlay
   * @type any (slot)
   */
  filterDropdown?:
    | VNodeChild
    | JSX.Element
    | ((props: FilterDropdownProps) => VNodeChild | JSX.Element);

  /**
   * Whether filterDropdown is visible
   * @type boolean
   */
  filterDropdownVisible?: boolean;

  /**
   * Whether the dataSource is filtered
   * @default false
   * @type boolean
   */
  filtered?: boolean;

  /**
   * Controlled filtered value, filter icon will highlight
   * @type string[]
   */
  filteredValue?: string[];

  /**
   * Customized filter icon
   * @default false
   * @type any
   */
  filterIcon?: boolean | VNodeChild | JSX.Element;

  /**
   * Whether multiple filters can be selected
   * @default true
   * @type boolean
   */
  filterMultiple?: boolean;

  /**
   * Filter menu config
   * @type object[]
   */
  filters?: ColumnFilterItem[];

  /**
   * Set column to be fixed: true(same as left) 'left' 'right'
   *
   * 列是否固定,可选 true(等效于 left) 'left' 'right'
   * @default false
   * @type boolean | string
   */
  fixed?: boolean | 'left' | 'right';

  /**
   * Unique key of this column, you can ignore this prop if you've set a unique dataIndex
   * vue绑定的key 如果已经设置了唯一的 dataIndex,可以忽略这个属性
   * @type string
   */
  key?: string;

  /**
   * Renderer of the table cell. The return value should be a VNode, or an object for colSpan/rowSpan config
   *
   * 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return 里面可以设置表格行/列合并,可参考 demo 表格行/列合并
   *
   * @type Function | ScopedSlot
   */
  customRender?: CustomRenderFunction<T> | VNodeChild | JSX.Element;

  /**
   * Sort function for local sort, see Array.sort's compareFunction. If you need sort buttons only, set to true
   *
   * 开启排序
   * @type boolean | Function
   */
  sorter?: boolean | Function;

  /**
   * Order of sorted values: 'ascend' 'descend' false
   * @type boolean | string
   */
  sortOrder?: boolean | SortOrder;

  /**
   * supported sort way, could be 'ascend', 'descend'
   * @default ['ascend', 'descend']
   * @type string[]
   */
  sortDirections?: SortOrder[];

  /**
   * Title of this column
   * @type any (string | slot)
   */
  title?: VNodeChild | JSX.Element;

  /**
   * Width of this column
   * @type string | number
   */
  width?: string | number;

  /**
   * Set props on per cell
   * 设置单元格属性 格式化单元格数据(并不是,没啥效果)
   * @type Function
   */
  customCell?: (record: T, rowIndex: number) => object;

  /**
   * Set props on per header cell
   * 设置表头属性 外层设计的会覆盖customHeaderCell返回的
   * @type object
   */
  customHeaderCell?: (column: ColumnProps<T>) => object;

  /**
   * Callback executed when the confirm filter button is clicked, Use as a filter event when using template or jsx
   * @type Function
   */
  onFilter?: (value: any, record: T) => boolean;

  /**
   * Callback executed when filterDropdownVisible is changed, Use as a filterDropdownVisible event when using template or jsx
   * @type Function
   */
  onFilterDropdownVisibleChange?: (visible: boolean) => void;

  /**
   * When using columns, you can setting this property to configure the properties that support the slot,
   * such as slots: { filterIcon: 'XXX'}
   * {
   *  title?: string;
      filterIcon?: string;
      filterDropdown?: string;
      customRender?: string;
      [key: string]: string | undefined;
   * }
   
   一般使用customRender设置插槽名称即可。
   * @type object
   */
  slots?: Recordable<string>;
}

format

可以拿到当前单元格和行的记录,做一些处理。
export type CellFormat =
  | string
  | ((text: string, record: Recordable, index: number) => string | number)
  | Map<string | number, any>;
  
// 格式化,例如时间格式化
format?: CellFormat;

format(text) {
  return text ? dayjs(text).format('YYYY-MM-DD') : '';
},

basicTable插槽

在这里插入图片描述

useForm返回的配置对象

// 主要是统一更改对应的表单props
  setProps,
  // 通过请求接口数据,来回显对应的数据。这里主要使用到表单编辑等
  setFieldsValue,
  // 更新schema,可以一次性更新多个schemaItem
  updateSchema,
  // 滚动到对应字段位置。暂时未发现有啥用
  scrollToField,
  // 他这个还是需要传入重置的schame,实际感觉可以使用updateSchame代替
  resetSchema,
  // 清空校验信息,包括表单的验证错误提示
  clearValidate,
  // 重置表单数据,包括验证错误提示也会消失
  resetFields,
  // 根据 field 删除 Schema
  removeSchemaByFiled,
  // 获取表单数据 (注意: 只会获取填写的字段,删除空值字段)
  getFieldsValue,
  // 插入到指定 filed 后面,如果没传指定 field,则插入到最后,当 first = true 时插入到第一个位置 (没啥用)
  appendSchemaByField,
  //  const res = await validateFields(['field1']); 指定对应的filed进行表单验证。如果不指定,name将验证所有表单项。如果传入一个空数组,那么表单校验将会被忽略。直接通过。
  validateFields,
  // 整体表单校验。测试发现和validateFields一样的效果
  validate,
  // 提交表单。内部集成了表单校验
  submit,

useForm 参数

export interface FormProps {
  // 表单展示方式
  layout?: 'vertical' | 'inline' | 'horizontal';
  // 表单绑定的数据对象
  model?: Recordable;
  // The width of all items in the entire form
  labelWidth?: number | string;
  //alignment
  labelAlign?: 'left' | 'right';
  //Row configuration for the entire form
  rowProps?: RowProps;
  // Submit form on reset
  // 重置时是否提交表单。触发表单对象的submit事件,如果绑定了submit事件。
  submitOnReset?: boolean;
  // label整体配置。column配置的内容会覆盖formProps中的配置
  labelCol?: Partial<ColEx>;
  // wrapper整体配置
  wrapperCol?: Partial<ColEx>;

  // General row style
  baseRowStyle?: CSSProperties;

  // 配置所有选子项的 ColProps,不需要逐个配置,子项也可单独配置优先与全局
  baseColProps?: Partial<ColEx>;

  // 表单项配置列表
  schemas?: FormSchema[];
  // 额外传递到子组件的参数 values
  mergeDynamicData?: Recordable;
  // 紧凑类型表单,减少 margin-bottom
  compact?: boolean;
  // 空白行格,可以是数值或者 col 对象 数
  emptySpan?: number | Partial<ColEx>;
  // 向颞部组件传递size值
  size?: 'default' | 'small' | 'large';
  // 禁用全部表单
  disabled?: boolean;
  // 用于将表单内时间区域的应设成 2 个字段 (用于时间区间选择,传递给后端开始和结束时间)
  /**
   * fieldMapToTime: [
    // datetime为时间组件在表单内的字段,startTime,endTime为转化后的开始时间与结束时间
    // 'YYYY-MM-DD'为时间格式,参考moment
    ['datetime', ['startTime', 'endTime'], 'YYYY-MM-DD'],
    // 支持多个字段
    ['datetime1', ['startTime1', 'endTime1'], 'YYYY-MM-DD HH:mm:ss'],
    提交后获取表单数据就会有startTime,endTime字段
  ],
   */
  fieldMapToTime?: FieldMapToTime;
  // 自动设置表单内组件的 placeholder,自定义组件需自行实现
  autoSetPlaceHolder?: boolean;
  // 在input中输入时按回车自动提交
  autoSubmitOnEnter?: boolean;
  // 如果表单项有校验,会自动生成校验信息,该参数控制是否将字段中文名字拼接到自动生成的信息后方
  rulesMessageJoinLabel?: boolean;
  // 是否显示收起展开按钮。 提交按钮旁边的
  showAdvancedButton?: boolean;
  // 是否聚焦第一个输入框,只在第一个表单项为 input 的时候作用
  autoFocusFirstItem?: boolean;
  // 如果 showAdvancedButton 为 true,超过指定行数行默认折叠
  autoAdvancedLine?: number;
  // 折叠时始终保持显示的行数
  alwaysShowLines?: number;
  // 是否显示操作按钮(重置/提交) 如果设置为false时,展开隐藏的表单项将不会显示
  showActionButtonGroup?: boolean;

  // 重置按钮的配置项 {text}
  resetButtonOptions?: Partial<ButtonProps>;

  // 确认按钮配置见下方
  submitButtonOptions?: Partial<ButtonProps>;

  // 操作(footer-action)按钮外层 Col 组件配置,如果开启 showAdvancedButton,则不用设置
  actionColOptions?: Partial<ColEx>;

  // 是否显示重置按钮
  showResetButton?: boolean;
  // 是否显示提交按钮
  showSubmitButton?: boolean;

  // 自定义重置按钮逻辑
  resetFunc?: () => Promise<void>;
  submitFunc?: () => Promise<void>;
  transformDateFunc?: (date: any) => string;
  colon?: boolean;
}

labelCol

export interface ColEx {
  style?: any;
  /**
   * raster number of cells to occupy, 0 corresponds to display: none
   * @default none (0)
   * @type ColSpanType
   */
  span?: ColSpanType;

  /**
   * raster order, used in flex layout mode
   * @default 0
   * @type ColSpanType
   */
  order?: ColSpanType;

  /**
   * the layout fill of flex
   * @default none
   * @type ColSpanType
   */
  flex?: ColSpanType;

  /**
   * the number of cells to offset Col from the left
   * @default 0
   * @type ColSpanType
   */
  offset?: ColSpanType;

  /**
   * the number of cells that raster is moved to the right
   * @default 0
   * @type ColSpanType
   */
  push?: ColSpanType;

  /**
   * the number of cells that raster is moved to the left
   * @default 0
   * @type ColSpanType
   */
  pull?: ColSpanType;

  /**
   * <576px and also default setting, could be a span value or an object containing above props
   * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
   */
  xs?: { span: ColSpanType; offset: ColSpanType } | ColSpanType;

  /**
   * ≥576px, could be a span value or an object containing above props
   * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
   */
  sm?: { span: ColSpanType; offset: ColSpanType } | ColSpanType;

  /**
   * ≥768px, could be a span value or an object containing above props
   * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
   */
  md?: { span: ColSpanType; offset: ColSpanType } | ColSpanType;

  /**
   * ≥992px, could be a span value or an object containing above props
   * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
   */
  lg?: { span: ColSpanType; offset: ColSpanType } | ColSpanType;

  /**
   * ≥1200px, could be a span value or an object containing above props
   * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
   */
  xl?: { span: ColSpanType; offset: ColSpanType } | ColSpanType;

  /**
   * ≥1600px, could be a span value or an object containing above props
   * @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
   */
  xxl?: { span: ColSpanType; offset: ColSpanType } | ColSpanType;
}

按钮相关操作
submitButtonOptions, submitFunc,如果有不需要提交和重置的功能,而是需要其他按钮的功能,我们就可以定义按钮文本并实现对应的逻辑。一个障眼法 也可以使用插槽。

// 重置按钮的配置项 {text}
  resetButtonOptions?: Partial<ButtonProps>;

  // 确认按钮配置
  submitButtonOptions?: Partial<ButtonProps>;

  // 操作(footer-action)按钮外层 Col 组件配置,如果开启 showAdvancedButton,则不用设置
  actionColOptions?: Partial<ColEx>;

  // 是否显示重置按钮
  showResetButton?: boolean;
  // 是否显示提交按钮
  showSubmitButton?: boolean;

  // 自定义重置按钮逻辑
  resetFunc?: () => Promise<void>;
  submitFunc?: () => Promise<void>;

插槽
ormFooter 表单底部区域
formHeader 表单顶部区域
resetBefore 重置按钮前
submitBefore 提交按钮前
advanceBefore 展开按钮前
advanceAfter 展开按钮后

表单项配置列表 SchemaForm

export interface FormSchema {
  // 表单项字段
  field: string;
  // 表单更新事件名称, 默认是change。 感觉没啥用
  changeEvent?: string;
  // 下拉数组项内value实际值的字段 默认是value
  // 一般使用在 componentProps 中请求options做字段值映射,还有 labelField
  /**
   * componentProps({ formModel }) {
      return {
        showSearch: true,
        api: queryCountryCode,
        labelField: 'cn',
        valueField: 'id',
        onChange: (_) => {
          formModel.province = null;
          // formModel.city = null;
        },
      };
    },
   */
  valueField?: string;
  // 表单项label名称
  label: string | VNode;
  // 二级标签名灰色
  subLabel?: string;
  // info提示信息
  helpMessage?:
    | string
    | string[]
    | ((renderCallbackParams: RenderCallbackParams) => string | string[]);
  // 标签名右侧温馨提示组件 props
  helpComponentProps?: Partial<HelpComponentProps>;
  // 将覆盖统一设置的 labelWidth
  labelWidth?: string | number;
  // 禁用 form 全局设置的 labelWidth,自己手动设置 labelCol 和 wrapperCol。 (全局props不是没有labelWidth属性吗???)
  disabledLabelWidth?: boolean;
  // 渲染的组件类型
  component: ComponentType;
  // 所渲染组件的props
  /**
   * component: 'ApiSelect',
    componentProps(props) {
      return {
        showSearchcomponentProps: true,
        labelField: 'productName',
        valueField: 'productCode',
        resultField: 'results',

        api: (params) =>
          fetchProductPage(
            Object.assign(params, {
              pageReq: {
                pageSize: 500,
                pageNo: 1,
              },
            }),
          ),

        onChange(val, options) {
          // options是请求接口的原始数据
          props.formModel.productModel = options.productModel;
          props.formModel.productType = options.productType;
        },
      };
    },
   */
  componentProps?:
    | ((opt: {
        schema: FormSchema;
        tableAction: TableActionType;
        formActionType: FormActionType;
        formModel: Recordable;
      }) => Recordable)
    | object;
  // 必填
  required?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean);
  // 组件后面的内容
  suffix?: string | number | ((values: RenderCallbackParams) => string | number);

  // 表单项验证规则
  /**
   * rules: [
      {
        required: true,
        validator: async (rule, value) => {
          if (!value) {
            return Promise.reject('请输入xxx');
          }
          if (value && value.length > 100) {
            return Promise.reject('最大不能超过100个字');
          }
          return Promise.resolve();
        },
        trigger: 'change',
      },
    ],
   */
  rules?: Rule[];
  // 校验信息是否加入 label 默认是false
  rulesMessageJoinLabel?: boolean;

  // Reference formModelItem
  itemProps?: Partial<FormItem>;

  // col configuration outside formModelItem
  colProps?: Partial<ColEx>;

  // 默认值
  defaultValue?: any;
  isAdvanced?: boolean;

  // Matching details components
  span?: number;
  // 动态判断当前组件是否显示,js 控制,会删除 dom 相当于v-if
  ifShow?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean);
  // 动态判断当前组件是否显示,css 控制 (display: none),不会删除 dom 相当于v-show
  show?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean);

  // 自定义渲染内容 ,渲染组件在form-item中
  render?: (renderCallbackParams: RenderCallbackParams) => VNode | VNode[] | string;

  // 自定义渲染组件(需要自行包含 formItem)他的意思是渲染列组件。一个表单项,需要在外层包裹着formItem,因为他不会主动加上formItem
  renderColContent?: (renderCallbackParams: RenderCallbackParams) => VNode | VNode[] | string;

  // 自定义渲染组内部的 slot (这个不知道啥用)
  renderComponentContent?:
    | ((renderCallbackParams: RenderCallbackParams) => any)
    | VNode
    | VNode[]
    | string;

  // 定义插槽名称,可以在basic-form中使用该插槽定制内容。可以拿到当前列props配置 Custom slot, in from-item
  slot?: string;

  // 相当于renderColContent, 但是他是在模板中使用插槽定义内容 Custom slot, similar to renderColContent
  colSlot?: string;
  // 是否禁用表单项
  dynamicDisabled?: boolean | ((renderCallbackParams: RenderCallbackParams) => boolean);
  // 动态判断当前组件校验规则
  dynamicRules?: (renderCallbackParams: RenderCallbackParams) => Rule[];
}

ifShow
做一些表单值联动隐藏表单项处理。

ifShow(payload) {
    // 通过payload.model.[value]去判断
}

ifShow(payload) {
  if (payload.model.type === '1') {
    return true;
  } else {
    return false;
  }
},

componentProps 所渲染的组件的 props

  1. 当值为对象类型时,该对象将作为component所对应组件的的 props 传入组件。就是ant-design-vue中组件对应的props。

  2. 当值为一个函数时候参数是一个对象有 4 个属性。但是一般使用formModel, schema就可以了。做变动联动处理就可以使用到。
    schema: 表单的整个 schemas
    formActionType: 操作表单的函数。与 useForm 返回的操作函数一致
    formModel: 表单的双向绑定对象,这个值是响应式的。所以可以方便处理很多操作
    tableAction: 操作表格的函数,与 useTable 返回的操作函数一致。注意该参数只在表格内开启搜索表单的时候有值,其余情况为null。

component: 'ApiSelect',
componentProps(props) {
  return {
    showSearchcomponentProps: true,
    labelField: 'productName',
    valueField: 'productCode',
    resultField: 'results',

    api: (params) =>
      fetchProductPage(
        Object.assign(params, {
          pageReq: {
            pageSize: 500,
            pageNo: 1,
          },
        }),
      ),

    onChange(val, options) {
      // options是请求接口的原始数据
      props.formModel.productModel = options.productModel;
      props.formModel.productType = options.productType;
    },
  };
}
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值