Skip to content

目前查询条件有:

  • 文本框
  • 下拉框
  • 日期选择器
  • 级联选择器

然后就是加了一部分插槽

查询表单

vue
<template>
  <div>
    <!-- -->
    <QueryForm
      ref="queryFormRef"
      :columns="columns"
      :formatParams="formatParams"
      :showSearchReset="true"
      @onSearch="search"
      @onReset="reset">
        <template #searchIcon>
          <el-space>
            <el-icon>
              <Search />
            </el-icon>
            查询
          </el-space>
        </template>

        <template #resetIcon>
          <el-space>
            <el-icon>
              <Refresh />
            </el-icon>
            重置
          </el-space>
        </template>
      </QueryForm>

    <el-button type="primary" @click="getSelectValue">
      使查询项2的下拉框获取焦点
    </el-button>
  </div>
</template>

<script setup>
import { ref, h } from "vue";

// 查询表单实例
const queryFormRef = ref();

// 查询项2的下拉框选项
const query22Options = ref([
  {
    label: "选项1",
    value: "1",
  },
  {
    label: "选项2",
    value: "2",
  },
  {
    label: "选项3",
    value: "3",
  },
]);

const options = [
  {
    value: "guide",
    label: "Guide",
    children: [
      {
        value: "disciplines",
        label: "Disciplines",
        children: [
          {
            value: "consistency",
            label: "Consistency",
          },
          {
            value: "feedback",
            label: "Feedback",
          },
          {
            value: "efficiency",
            label: "Efficiency",
          },
          {
            value: "controllability",
            label: "Controllability",
          },
        ],
      },
      {
        value: "navigation",
        label: "Navigation",
        children: [
          {
            value: "side nav",
            label: "Side Navigation",
          },
          {
            value: "top nav",
            label: "Top Navigation",
          },
        ],
      },
    ],
  },
  {
    value: "component",
    label: "Component",
    children: [
      {
        value: "basic",
        label: "Basic",
        children: [
          {
            value: "layout",
            label: "Layout",
          },
          {
            value: "color",
            label: "Color",
          },
          {
            value: "typography",
            label: "Typography",
          },
          {
            value: "icon",
            label: "Icon",
          },
          {
            value: "button",
            label: "Button",
          },
        ],
      },
      {
        value: "form",
        label: "Form",
        children: [
          {
            value: "radio",
            label: "Radio",
          },
          {
            value: "checkbox",
            label: "Checkbox",
          },
          {
            value: "input",
            label: "Input",
          },
          {
            value: "input-number",
            label: "InputNumber",
          },
          {
            value: "select",
            label: "Select",
          },
          {
            value: "cascader",
            label: "Cascader",
          },
          {
            value: "switch",
            label: "Switch",
          },
          {
            value: "slider",
            label: "Slider",
          },
          {
            value: "time-picker",
            label: "TimePicker",
          },
          {
            value: "date-picker",
            label: "DatePicker",
          },
          {
            value: "datetime-picker",
            label: "DateTimePicker",
          },
          {
            value: "upload",
            label: "Upload",
          },
          {
            value: "rate",
            label: "Rate",
          },
          {
            value: "form",
            label: "Form",
          },
        ],
      },
      {
        value: "data",
        label: "Data",
        children: [
          {
            value: "table",
            label: "Table",
          },
          {
            value: "tag",
            label: "Tag",
          },
          {
            value: "progress",
            label: "Progress",
          },
          {
            value: "tree",
            label: "Tree",
          },
          {
            value: "pagination",
            label: "Pagination",
          },
          {
            value: "badge",
            label: "Badge",
          },
        ],
      },
      {
        value: "notice",
        label: "Notice",
        children: [
          {
            value: "alert",
            label: "Alert",
          },
          {
            value: "loading",
            label: "Loading",
          },
          {
            value: "message",
            label: "Message",
          },
          {
            value: "message-box",
            label: "MessageBox",
          },
          {
            value: "notification",
            label: "Notification",
          },
        ],
      },
      {
        value: "navigation",
        label: "Navigation",
        children: [
          {
            value: "menu",
            label: "Menu",
          },
          {
            value: "tabs",
            label: "Tabs",
          },
          {
            value: "breadcrumb",
            label: "Breadcrumb",
          },
          {
            value: "dropdown",
            label: "Dropdown",
          },
          {
            value: "steps",
            label: "Steps",
          },
        ],
      },
      {
        value: "others",
        label: "Others",
        children: [
          {
            value: "dialog",
            label: "Dialog",
          },
          {
            value: "tooltip",
            label: "Tooltip",
          },
          {
            value: "popover",
            label: "Popover",
          },
          {
            value: "card",
            label: "Card",
          },
          {
            value: "carousel",
            label: "Carousel",
          },
          {
            value: "collapse",
            label: "Collapse",
          },
        ],
      },
    ],
  },
  {
    value: "resource",
    label: "Resource",
    children: [
      {
        value: "axure",
        label: "Axure Components",
      },
      {
        value: "sketch",
        label: "Sketch Templates",
      },
      {
        value: "docs",
        label: "Design Documentation",
      },
    ],
  },
];

// 查询表单列配置
const columns = ref([
  {
    label: "查询项1",
    prop: "query11",
    comType: "input",
    slots: {
      prefix: () => h("div", {}, "插槽"),
    },
  },
  {
    label: "查询项3",
    prop: "query33",
    comType: "date",
    datePickerAttrs: {
      type: "datetimerange",
      valueFormat: "YYYY-MM-DD HH:mm:ss",
      format: "YYYY-MM-DD HH:mm:ss",
    },
    events: {
      change: (val) => {
        console.log(val);

        setTimeout(() => {
          query22Options.value.push({
            label: "选项4",
            value: "4",
          });
        }, 2000);
      },
    },
  },
  {
    label: "查询项2",
    prop: "query22",
    comType: "select",
    options: query22Options.value,
    selectAttrs: {
      filterable: true,
    },
    slots: {
      header: () => h("div", {}, "查询项2"),
    },
  },
  {
    label: "查询项4",
    prop: "query44",
    comType: "cascader",
    // slots: {
    //   default: (scope: { node: VNode; data: CascaderOption }) =>
    //     h("div", {}, [
    //       h("span", {}, scope.data.label),
    //       h("span", {}, scope.data.children?.length || ""),
    //     ]),

    //   header: () => h("div", {}, "查询项4"),

    //   footer: () => <div>{1}</div>,
    // },
    cascaderAttrs: {
      options,
    },
  },
]);

// 格式化查询参数
const formatParams = (params, type) => {
  if (type === "search") {
    if ((params.query33)?.length) {
      params.startTime = (params.query33)[0];
      params.endTime = (params.query33)[1];
    } else {
      delete params.startTime;
      delete params.endTime;
    }
  }

  if (type === "reset") {
    delete params.startTime;
    delete params.endTime;
  }

  return params;
};

// 查询
const search = (params) => {
  console.log("查询参数:", params);
};

// 重置
const reset = (params) => {
  console.log("重置参数:", params);
};

// 使指定的下拉框获得焦点
const getSelectValue = () => {
  const selectRef = queryFormRef.value?.getComponentRef("query22");
  if (selectRef) {
    console.log(selectRef);
    console.log(selectRef.focus());
  }
};
</script>

属性类型默认值描述
columnsArray[]查询表单列配置,查看QueryFormColumn说明
formatParamsFunction(params) => params格式化查询参数函数
setDefaultValuesFunction() => {}设置默认值函数
spanNumber6列数
showSearchResetBooleantrue是否显示查询重置按钮

QueryFormColumn说明

属性类型默认值描述
labelString""列标签
propString""列属性名
comTypeString可选值有:input,select,date, cascader组件类型
placeholderString""占位符
optionsArray[{ label: string, value: string }]下拉选项选项数组
optionAttrsObject{}下拉选项属性对象,与element-plus的下拉选项属性一致。查看
inputAttrsObject{}输入框属性对象,与element-plus的输入框属性一致。查看
selectAttrsObject{}下拉选择器属性对象,与element-plus的下拉选择器属性一致。查看
cascaderAttrsObject{}级联选择器属性对象,与element-plus的级联选择器属性一致。查看
datePickerAttrsObject{}日期选择器属性对象,与element-plus的日期选择器属性一致。查看
eventsObject{}组件的事件对象,上述示例中有
slotsObject{}组件的插槽对象,上述示例中有

事件名参数说明
onSearchparams: Object查询事件,参数为查询参数
onResetparams: Object重置事件,参数为重置参数

方法名参数返回值描述
search获取指定属性的组件实例
reset重置查询表单
getParamsObject获取查询参数
getComponentRefpropComponent获取指定属性的组件实例

typescript
type comType = "input" | "select" | "date" | "cascader";

export interface QueryFormColumn {
  label: string;
  prop: string;
  comType: comType;
  placeholder?: string;
  options?: {
    label: string;
    value: string;
  }[];
  inputAttrs?: Record<string, unknown>;
  selectAttrs?: Record<string, unknown>;
  optionAttrs?: Record<string, unknown>;
  events?: Record<string, unknown>;
  datePickerAttrs?: Record<string, unknown>;
  cascaderAttrs?: Record<string, unknown>;
  slots?: Record<string, (scope: unknown) => VNode | JSX.Element> | undefined;
}

export type QueryType = "search" | "reset";

export interface Props {
  columns: QueryFormColumn[];
  setDefaultValues?: (form: Record<string, unknown>) => void;
  formatParams?: (
    params: Record<string, unknown>,
    type?: QueryType,
  ) => Record<string, unknown>;
  span?: number;
  showSearchReset?: boolean;
}

export interface QueryFormExpose {
  /** 查询 */
  search: () => void;

  /** 重置 */
  reset: () => void;

  /** 获取参数 */
  getParams: () => Record<string, unknown>;

  /** 获取每一项的组件实例 @param prop 组件的prop */
  getComponentRef: (prop: string) => unknown;
}