说明

基于el-table封装的表单

可选参数

isPopover为false为表单,为true则为Select选择器,选择的内容为表单内容

      // 定义接收的属性
export interface ISelectConfig<T = any> {
  // 宽度
  width?: string;
  // 占位符
  placeholder?: string;
  // popover组件属性
  popover?: Partial<Omit<PopoverProps, "visible" | "v-model:visible">>;
  // 列表的网络请求函数(需返回promise)
  indexAction: (_queryParams: T) => Promise<any>;
  // 主键名(跨页选择必填,默认为id)
  pk?: string;
  // 多选
  multiple?: boolean;
  // 表单项
  formItems: Array<{
    // 组件类型(如input,select等)
    type?: "input" | "select" | "tree-select" | "date-picker";
    // 标签文本
    label: string;
    // 键名
    prop: string;
    // 组件属性
    attrs?: IObject;
    // 初始值
    initialValue?: any;
    // 可选项(适用于select组件)
    options?: { label: string; value: any }[];
  }>;
  // 列选项
  tableColumns: Array<{
    type?: "default" | "selection" | "index" | "expand";
    label?: string;
    prop?: string;
    width?: string | number;
    [key: string]: any;
  }>;
}

const props = withDefaults(
    defineProps<{
      selectConfig: ISelectConfig;
      isPopover?: boolean; // 属性控制弹出框行为
    }>(),
    {
      isPopover: false //为false为表单,为true则为Select选择器
    }
);

// 自定义事件
const emit = defineEmits<{
  confirmClick: [selection: any[]];
}>();
    

使用示例

select.ts

      import UserAPI from "@/api/system/user.api"; //自己的api接口
import type { ISelectConfig } from "liyao-vue-common";

const selectConfig: ISelectConfig = {
  pk: "id",
  width: "70%",
  placeholder: "请选择用户",
  formItems: [
    {
      type: "input",
      label: "关键字",
      prop: "keywords",
      attrs: {
        placeholder: "用户名/昵称/手机号",
        clearable: true,
        style: {
          width: "200px",
        },
      },
    },
    {
      type: "tree-select",
      label: "部门",
      prop: "deptId",
      attrs: {
        placeholder: "请选择",
        data: [
          {
            value: 1,
            label: "有来技术",
            children: [
              {
                value: 2,
                label: "研发部门",
              },
              {
                value: 3,
                label: "测试部门",
              },
            ],
          },
        ],
        filterable: true,
        "check-strictly": true,
        "render-after-expand": false,
        clearable: true,
        style: {
          width: "150px",
        },
      },
    },
    {
      type: "select",
      label: "状态",
      prop: "status",
      attrs: {
        placeholder: "全部",
        clearable: true,
        style: {
          width: "100px",
        },
      },
      options: [
        { label: "启用", value: 1 },
        { label: "禁用", value: 0 },
      ],
    },
    {
      type: "date-picker",
      label: "创建时间",
      prop: "createAt",
      attrs: {
        type: "daterange",
        "range-separator": "~",
        "start-placeholder": "开始时间",
        "end-placeholder": "截止时间",
        "value-format": "YYYY-MM-DD",
        style: {
          width: "240px",
        },
      },
    },
  ],
  indexAction: function (params) {
    if ("createAt" in params) {
      const createAt = params.createAt as string[];
      if (createAt?.length > 1) {
        params.startTime = createAt[0];
        params.endTime = createAt[1];
      }
      delete params.createAt;
    }
    return UserAPI.getPage(params);
  },
  tableColumns: [
    { type: "selection", width: 50, align: "center" },
    { label: "编号", align: "center", prop: "id", width: 100 },
    { label: "用户名", align: "center", prop: "username" },
    { label: "用户昵称", align: "center", prop: "nickname", width: 120 },
    {
      label: "性别",
      align: "center",
      prop: "gender",
      width: 100,
      templet: "custom",
      slotName: "gender",
    },
    { label: "部门", align: "center", prop: "deptName", width: 120 },
    { label: "手机号码", align: "center", prop: "mobile", width: 120 },
    {
      label: "状态",
      align: "center",
      prop: "status",
      templet: "custom",
      slotName: "status",
    },
    { label: "创建时间", align: "center", prop: "createTime", width: 180 },
  ],
};

export default selectConfig;
    

table.vue

      <script setup lang="ts">
import selectConfig from "./select";

interface IUser {
  id: number;
  username: string;
  nickname: string;
  mobile: string;
  gender: string;
  avatar: string;
  email: string | null;
  status: number;
  deptName: string;
  roleNames: string;
  createTime: string;
}
const selectedUser = ref<IUser>();
function handleConfirm(data: IUser[]) {
  selectedUser.value = data[0];
}

</script>

<template>
  <div class="app-container">
    <table-select :select-config="selectConfig" @confirm-click="handleConfirm">
      <template #status="scope">
        <el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
          {{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
        </el-tag>
      </template>
      <template #gender="scope">
        <DictLabel v-model="scope.row.gender" code="gender" />
      </template>
    </table-select>
  </div>
</template>
    

声明

作者: liyao

版权:本博客所有文章除特别声明外,均采用CCBY-NC-SA4.O许可协议。转载请注明!

最后更新于 2025-09-30 20:31 history