vue3 基于Ant DesignVue Select Table封装下拉选择表格组件(2025-01-07 TAntdSelectTable组件键盘向上/下滚动条根据移动的选择区域而滚动)

2025-01-07 TAntdSelectTable组件键盘向上/下滚动条根据移动的选择区域而滚动

在这里插入图片描述

一、最终效果

在这里插入图片描述

二、代码示例

<t-antd-select-table
  ref="tantdselecttable"
  selectWidth="40%"
  v-model="state.selectVal"
  :table="state.table"
  :columns="state.table.columns"
  :scroll="{ x: 2000, y: 400 }"
  isShowPagination
  :keywords="{ label: 'materialName', value: 'materialCode' }"
  @checked-change="checkedChange"
  @change="tablePaginationChange"
  placeholder="antd下拉选择表格"
></t-antd-select-table>

三、配置参数(Attributes)继承 a-table 及 a-select 属性

参数说明类型默认值
v-model绑定值 keywords.labelArray-
table表格数据对象Object{}
—data展示下拉数据源Array[]
—pagination配合 isShowPagination,其配置继承 a-tableArray[]
columns表格列的配置描述,具体项AntDesignVue 文档Array[]
keywords关键字配置Object
------label选项的标签String‘label’
------value选项的值((value-key 配置) )String‘value’
rowSelection列表项是否可选择–具体查看 AntDesignVue 文档Object-
isKeyup单选是否开启键盘事件(上下选择高亮,回车选中)Booleanfalse
isShowPagination是否开启分页Booleanfalse
mode是否多选(配置’multiple’)默认单选String-
defaultSelectVal设置第一页默认选中项–keywords.value 值Array-
selectWidthselect 宽度 (string 设置百分比,number 设置 px)String/Number100%
tableWidthtable 宽度Number550
preserveSelectedRowKeys当数据被删除时仍然保留选项的 key (多选翻页选中功能)Booleanfalse
isShowSelectBtn是否显示选择按钮Booleanfalse
btnSetBind选择按钮属性设置{ btnTxt: "选择", modalTxt: "选择",size: "middle"}Object-
modalSetBind弹窗属性设置 { modalTxt: "选择", cancelText: "取消",okText: "确定",width: 700}Object-
inputSetBind弹窗搜索配置 { searchTxt: "关键词", inputWidth: "40%",allowClear: true}Object-
disabledPorp禁用的属性String-
disabledValue禁用的值String/Number-

2-1、columns 配置参数(Attributes)继承 a-table columns 属性

参数说明类型默认值
align设置列的对齐方式left /right /centerleft
colSpan表头列合并,设置为 0 时,不渲染number-
customCell设置单元格属性Function(record, rowIndex, column)-
customFilterDropdown启用 v-slot:customFilterDropdown,优先级低于 filterDropdownbooleanfalse
customHeaderCell设置头部单元格属性Function(column)-
customRender生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引Function({text, record, index, column}) {}-
dataIndex列数据在数据项中对应的路径,支持通过数组查询嵌套路径string / string[]-
defaultFilteredValue默认筛选值string[]-
defaultSortOrder默认排序顺序 ascenddescend -
ellipsis超过宽度将自动省略 设置为 true 或 { showTitle?: boolean } 时,表格布局将变成 tableLayout=“fixed”。boolean / { showTitle?: boolean }false
filterDropdown可以自定义筛选菜单,此函数只负责渲染图层,需要自行编写各种交互VNode-
filterDropdownVisible用于控制自定义筛选菜单是否可见boolean-
filtered标识数据是否经过过滤,筛选图标会高亮booleanfalse
filteredValue筛选的受控属性,外界可用此控制列的筛选状态,值为已筛选的 value 数组string[]-
filterIcon自定义 filter 图标。VNode / ({filtered: boolean, column: Column}) => vNodefalse
filterMode指定筛选菜单的用户界面‘menu’ /‘tree’‘menu’
filterMultiple是否多选booleantrue
filters表头的筛选菜单项object[]-
filterSearch筛选菜单项是否可搜索Booleanfalse
fixed列是否固定,可选 true(等效于 left) ‘left’ ‘right’boolean/stringfalse
keyVue 需要的 key,如果已经设置了唯一的 dataIndex,可以忽略这个属性string-
maxWidth拖动列最大宽度,会受到表格自动调整分配宽度影响number-
minWidth拖动列最小宽度,会受到表格自动调整分配宽度影响number50
resizable是否可拖动调整宽度,此时 width 必须是 number 类型boolean-
responsive响应式 breakpoint 配置列表。未设置则始终可见。Breakpoint[]-
showSorterTooltip表头显示下一次排序的 tooltip 提示, 覆盖 table 中 showSorterTooltipboolean /Tooltip propstrue
sortDirections支持的排序方式,取值为 ‘ascend’ ‘descend’Array[‘ascend’, ‘descend’]
sorter排序函数,本地排序使用一个函数(参考 Array.sort 的 compareFunction),需要服务端排序可设为 trueFunction/boolean-
sortOrder排序的受控属性,外界可用此控制列的排序,可设置为 ‘ascend’ ‘descend’ falseboolean/string-
title列头显示文字string-
width列宽度string/number-
onFilter本地模式下,确定筛选的运行函数, 使用 template 或 jsx 时作为 filter 事件使用Function-
onFilterDropdownVisibleChange自定义筛选菜单可见变化时调用,使用 template 或 jsx 时作为 filterDropdownVisibleChange 事件使用function(visible) {}-

2-2、a-pagination 配置参数(Attributes)继承 a-pagination属性(分页配置)

参数说明类型默认值
current(v-model)当前页数number-
defaultPageSize默认的每页条数number10
disabled禁用分页boolean-
hideOnSinglePage只有一页时是否隐藏分页器booleanfalse
itemRender用于自定义页码的结构,可用于优化 SEO({page, type: ‘page’ / ‘prev’ /‘next’, originalElement}) => vNode / v-slot-
pageSize(v-model)每页条数number-
pageSizeOptions指定每页可以显示多少条string[][‘10’, ‘20’, ‘30’, ‘40’]
responsive当 size 未指定时,根据屏幕宽度自动调整尺寸boolean-
showLessItems是否显示较少页面内容booleanfalse
showQuickJumper是否可以快速跳转至某页booleanfalse
showSizeChanger是否展示 pageSize 切换器,当 total 大于 50 时默认为 trueboolean-
showTotal用于显示数据总量和当前数据顺序Function(total, range)-
simple当添加该属性时,显示为简单分页boolean-
size当为「small」时,是小尺寸分页string“”
total数据总数number0

2-3、rowSelection 配置参数(Attributes)继承 a-table rowSelection 属性

参数说明类型默认值
checkStrictlycheckable 状态下节点选择完全受控(父子数据选中状态不再关联)booleantrue
columnTitle自定义列表选择框标题string/VNode-
columnWidth自定义列表选择框宽度string/number-
fixed把选择框列固定在左边boolean-
getCheckboxProps选择框的默认属性配置Function(record)-
hideDefaultSelections去掉『全选』『反选』两个默认选项booleanfalse
hideSelectAll隐藏全选勾选框与自定义选择项booleanfalse
preserveSelectedRowKeys当数据被删除时仍然保留选项的 keyboolean-
selectedRowKeys指定选中项的 key 数组,需要和 onChange 进行配合string[][]
selections自定义选择项 配置项, 设为 true 时使用默认选择项object[] / booleantrue
type多选/单选,checkbox or radiostringcheckbox
onChange选中项发生变化时的回调Function(selectedRowKeys, selectedRows)-
onSelect用户手动选择/取消选择某列的回调Function(record, selected, selectedRows, nativeEvent)-
onSelectAll用户手动选择/取消选择所有列的回调Function(selected, selectedRows, changeRows)-
onSelectInvert用户手动选择反选的回调Function(selectedRows)-
onSelectNone用户清空选择的回调function()-

四、事件(events)继承 a-table 及 a-select 事件

事件名说明回调参数
checkedChange选中项事件返回选中项的 keywords.value 集合与选中的项集合

五、方法(a-select—Methods)

方法名说明回调参数
focus使 input 获取焦点-
blur使 input 失去焦点,并隐藏下拉框-
openSelectDropdown显示下拉框-

六、 源码

<template>
  <div class="t-antd-select-table">
    <a-select
      ref="selectRef"
      v-model:value="childSelectedValue"
      popupClassName="t_antd_select_dropdown"
      :style="`width:${typeof selectWidth === 'number' ? `${selectWidth}px` : `${selectWidth}`}`"
      :mode="mode"
      :open="open"
      v-bind="selectAttr"
      :value-key="keywords.value"
      :filterOption="false"
      @search="filterMethodHandle"
      @dropdown-visible-change="visibleChange"
      @deselect="removeTag"
      @clear="clear"
      @input-key-down="selectKeyup"
    >
      <template #notFoundContent>
        <div class="t-table-select__table" :style="{ width: `${tableWidth}px` }">
          <slot name="search"></slot>
          <a-table
            ref="selectTable"
            :data-source="state.tableData"
            :columns="columns"
            bordered
            :row-key="getRowKey"
            :row-class-name="getRowClass"
            :pagination="isShowPagination && table.pagination"
            :row-selection="
              rowSelection || {
                selectedRowKeys: state.selectedRowKeys,
                onChange: onSelectChange,
                onSelectNone: onSelectNone,
                getCheckboxProps: getCheckboxProps,
                type: mode === 'multiple' ? 'checkbox' : 'radio'
              }
            "
            :customRow="rowClick"
            v-bind="$attrs"
          >
            <template #[item]="scope" v-for="item in slotsArr">
              <slot :name="item" :scope="scope" v-bind="scope || {}"></slot>
            </template>
            <slot name="footer"></slot>
          </a-table>
          <slot />
        </div>
      </template>
    </a-select>
    <a-button v-if="isShowSelectBtn" @click="selectBtnClick" v-bind="btnBind">{{ btnBind.btnTxt }}</a-button>
    <a-modal
      v-model:open="openModal"
      wrapClassName="t_select_modal"
      v-bind="modalBind"
      :title="modalBind.modalTxt"
      @ok="handleOk"
    >
      <div class="modal_search">
        <div class="search_label">{{ inputBind.searchTxt }}:</div>
        <a-input
          :placeholder="`请输入${inputBind.searchTxt}`"
          v-bind="inputBind"
          :style="{ width: inputBind.inputWidth }"
          v-model:value="searchModalValue"
          @change="searchModalChange"
        >
          <template #[item]="scope" v-for="item in slotsArr">
            <slot :name="item" :scope="scope" v-bind="scope || {}"></slot>
          </template>
        </a-input>
      </div>
      <a-table
        ref="selectTable"
        :data-source="state.tableData"
        :columns="columns"
        bordered
        :row-key="getRowKey"
        :row-class-name="getRowClass"
        :pagination="isShowPagination && table.pagination"
        :row-selection="
          rowSelection || {
            selectedRowKeys: state.selectedRowKeys,
            onChange: onSelectChange,
            onSelectNone: onSelectNone,
            getCheckboxProps: getCheckboxProps,
            preserveSelectedRowKeys: preserveSelectedRowKeys,
            type: mode === 'multiple' ? 'checkbox' : 'radio'
          }
        "
        :customRow="rowClick"
        v-bind="$attrs"
      >
        <template #[item]="scope" v-for="item in slotsArr">
          <slot :name="item" :scope="scope" v-bind="scope || {}"></slot>
        </template>
        <slot></slot>
      </a-table>
      <template #[item]="scope" v-for="item in slotsArr">
        <slot :name="item" :scope="scope" v-bind="scope || {}"></slot>
      </template>
    </a-modal>
  </div>
</template>
<script lang="ts">
export default {
  name: "TAntdSelectTable"
};
</script>
<script setup lang="ts">
import { computed, useAttrs, ref, watch, reactive, onMounted, useSlots } from "vue";
const props = defineProps({
  modelValue: {
    type: [String, Number, Array]
  },
  // table所需数据
  table: {
    type: Object,
    default: () => {
      return {};
    }
  },
  // 表头数据
  columns: {
    type: Array as unknown as any[],
    default: () => []
  },
  // 是否开启点击整行选中
  isRowClick: {
    type: Boolean,
    default: true
  },

  // 列表项是否可选择
  rowSelection: {
    type: Object
  },
  // 是否显示分页
  isShowPagination: {
    type: Boolean,
    default: false
  },
  // 下拉数据指向的label/value
  keywords: {
    type: Object,
    default: () => {
      return {
        label: "label",
        value: "value"
      };
    }
  },
  // 多选 'multiple'
  mode: {
    type: String
  },
  // 单选是否开启键盘事件
  isKeyup: {
    type: Boolean,
    default: false
  },
  // select宽度
  selectWidth: {
    type: [String, Number],
    default: "100%"
  },
  // table宽度
  tableWidth: {
    type: Number,
    default: 550
  },
  // 设置默认选中项--keywords.value值
  defaultSelectVal: {
    type: Array as unknown as any[]
  },
  // 当数据被删除时仍然保留选项的 key
  preserveSelectedRowKeys: {
    type: Boolean,
    default: false
  },
  // 是否显示选择按钮
  isShowSelectBtn: {
    type: Boolean,
    default: false
  },
  // 选择按钮属性设置
  btnSetBind: {
    type: Object,
    default: () => {}
  },
  // 弹窗属性设置
  modalSetBind: {
    type: Object,
    default: () => {}
  },
  // 弹窗搜索配置
  inputSetBind: {
    type: Object,
    default: () => {}
  },
  // 禁用的属性
  disabledPorp: {
    type: String
  },
  // 禁用的值
  disabledValue: {
    type: [String, Number]
  }
});

const selectAttr = computed(() => {
  return {
    allowClear: true,
    showSearch: true,
    dropdownMatchSelectWidth: false,
    ...useAttrs()
  };
});
// 选择按钮配置
const btnBind = computed(() => {
  const btnSetBind = { btnTxt: "选择", modalTxt: "选择", ...props.btnSetBind };
  return { size: "middle", ...btnSetBind };
});
// 弹窗搜索配置
const inputBind = computed(() => {
  const inputSetBind = { searchTxt: "关键词", inputWidth: "40%", ...props.inputSetBind };
  return { allowClear: true, ...inputSetBind };
});
// 选择弹窗配置
const modalBind = computed(() => {
  const modalSetBind = { modalTxt: "选择", ...props.modalSetBind };
  return { cancelText: "取消", okText: "确定", width: 700, ...modalSetBind };
});
const slots = useSlots();
const slotsArr = Object.keys(slots);
const attrs: any = useAttrs();
// 是否显示选择table弹窗
const openModal = ref(false);
// 弹窗搜索输入框值
const searchModalValue = ref("");

const isDefaultSelectVal = ref(true); // 是否已经重新选择了
const open = ref(false);
const nowIndex = ref(-1);
const state: any = reactive({
  defaultSelectValue: props.defaultSelectVal, // 默认选中
  tableData: props.table.data, // table数据
  activeTableRow: {}, // 键盘上下键选中项
  // 选中KEY
  selectedRowKeys: [] as (string | number)[],
  // 选中行
  selectedRows: [],
  rowClickSelected: props.isRowClick // 是否点击行选中
});
// 获取ref
const selectRef = ref<HTMLElement | any>(null);
const selectTable = ref<HTMLElement | any>(null);
// 抛出事件
const emits = defineEmits(["checkedChange", "update:modelValue"]);
watch(
  () => props.table.data,
  val => {
    state.tableData = val;
  },
  { deep: true }
);
watch(
  () => props.defaultSelectVal,
  val => {
    // console.log("defaultSelectValue--watch", val);
    state.defaultSelectValue = val;
    if (val && isDefaultSelectVal.value) {
      defaultSelect(val);
    }
  },
  { deep: true }
);
// v-model方式
const childSelectedValue = computed({
  get() {
    return props.modelValue;
  },
  set(val) {
    // console.log("v-model简写", val);
    emits("update:modelValue", val);
  }
});
onMounted(() => {
  // 设置默认选中项
  if (state.defaultSelectValue && isDefaultSelectVal.value) {
    // console.log("state.defaultSelectValue--", state.defaultSelectValue);
    defaultSelect(state.defaultSelectValue);
  }
  // 开启禁用模式,不支持点击整行选中
  if (props.disabledPorp && props.disabledValue) {
    state.rowClickSelected = false;
  }
});
// 单选or 多选
const onSelectChange = (selectedRowKeys: any, selectedRows: any) => {
  setTimeout(() => {
    // console.log("选择", selectedRowKeys, selectedRows);
    state.selectedRowKeys = selectedRowKeys;
    state.selectedRows = selectedRows;
    isDefaultSelectVal.value = false;
    if (state.selectedRowKeys.length > 0 && state.selectedRows.length > 0) {
      if (props.mode === "multiple") {
        childSelectedValue.value =
          state.selectedRows.length > 0 && state.selectedRows.map((item: { [x: string]: any }) => item[props.keywords.label]);
      } else {
        // console.log("单选--onSelectChange", state.selectedRows, state.selectedRowKeys);
        state.activeTableRow = state.selectedRows[0];
        childSelectedValue.value = state.selectedRows[0][props.keywords.label];
        blur();
      }
    } else {
      childSelectedValue.value = undefined;
    }
    emits("checkedChange", state.selectedRowKeys, state.selectedRows);
  }, 10);
};
// 复选框禁用
const getCheckboxProps = (record: any) => ({
  disabled: props.disabledPorp && record[props.disabledPorp] === props.disabledValue
});
const rowClick = (record: { [x: string]: any }) => {
  return {
    // 鼠标单击行
    onClick: () => {
      // console.log("鼠标单击行");
      if (props.mode !== "multiple") {
        if (!state.rowClickSelected) return;
        // 单选
        const keys = [];
        const items = [];
        keys.push(record[props.keywords.value]);
        items.push(record);
        onSelectChange(keys, items);
      } else {
        if (!state.rowClickSelected) return;
        // 多选
        const indexRow = state.selectedRowKeys.indexOf(record[props.keywords.value]);
        indexRow === -1 ? state.selectedRowKeys.push(record[props.keywords.value]) : state.selectedRowKeys.splice(indexRow, 1);
        if (indexRow === -1) {
          state.selectedRows.push(record);
        } else {
          state.selectedRows.splice(indexRow, 1);
        }
        onSelectChange(state.selectedRowKeys, state.selectedRows);
      }
    },
    // 鼠标双击行
    onDblclick: () => {
      handleOk();
    }
  };
};
// 单选键盘事件
const selectKeyup = (e: { keyCode: any }) => {
  if (props.mode !== "multiple" && props.isKeyup && state.tableData.length > 0) {
    const { keyCode } = e;
    const nextIndex = keyCode === 40 ? nowIndex.value + 1 : keyCode === 38 ? nowIndex.value - 1 : nowIndex.value;
    const activeTableRow = state.tableData[nextIndex] || state.tableData[0];

    switch (keyCode) {
      case 40: // 下键
      case 38: // 上键
        nowIndex.value = nextIndex;
        state.activeTableRow = activeTableRow;
        // 键盘向上/下滚动条根据移动的选择区域而滚动
        const headerHeight = selectTable.value.$el.querySelectorAll(".ant-table-header")[0]?.clientHeight || 0;
        const attrsMaxHeight = attrs.scroll.y || 0;
        const maxHeight = attrsMaxHeight ? attrsMaxHeight - headerHeight : 0;
        const height = 55 * (nextIndex + 3);
        const scrollTop = height > maxHeight ? height - maxHeight : 0;
        const scrollContainer = selectTable.value.$el.querySelector(".ant-table-body");
        if (scrollContainer) {
          scrollContainer.scrollTop = scrollTop;
        }
        break;
      case 13: // 回车
        if (activeTableRow) {
          const keys = [activeTableRow[props.keywords.value]];
          const items = [activeTableRow];
          onSelectChange(keys, items);
        }
        break;
    }
  }
};
// 动态添加类
const getRowClass = (record: any) => {
  // console.log("record--", state.activeTableRow);
  return state.activeTableRow && state.activeTableRow[props.keywords.value] === record[props.keywords.value] && props.isKeyup
    ? "active-selected-row"
    : "";
};
// 默认选中(且只能默认选中第一页的数据)
const defaultSelect = (defaultSelectVal: any[]) => {
  if (props.mode === "multiple") {
    setTimeout(() => {
      if (defaultSelectVal.length > 0) {
        let multipleList: any = [];
        let selectedRowKeys: any = [];
        let selectedRows: any = [];
        defaultSelectVal.map((val: any) => {
          state.tableData.forEach((row: any) => {
            if (val === row[props.keywords.value]) {
              multipleList.push(row);
            }
          });
        });
        multipleList.forEach((row: { [x: string]: any }) => {
          state.tableData.forEach((item: { [x: string]: any }) => {
            if (item[props.keywords.value] === row[props.keywords.value]) {
              selectedRowKeys.push(item[props.keywords.value]);
              selectedRows.push(item);
            }
          });
        });
        state.selectedRowKeys = selectedRowKeys;
        state.selectedRows = selectedRows;
        // console.log("多选默认", selectedRowKeys, selectedRows);
        childSelectedValue.value =
          state.selectedRows.length > 0 && state.selectedRows.map((item: { [x: string]: any }) => item[props.keywords.label]);
        // console.log("childSelectedValue.value", childSelectedValue.value);
      } else {
        childSelectedValue.value = undefined;
      }
    }, 0);
  } else {
    setTimeout(() => {
      if (defaultSelectVal.length > 0) {
        state.tableData.map((val: { [x: string]: any }) => {
          if (val[props.keywords.value] === defaultSelectVal[0]) {
            state.selectedRowKeys = defaultSelectVal;
            state.selectedRows = [val];
          }
        });
        childSelectedValue.value = state.selectedRows[0] && state.selectedRows[0][props.keywords.label];
      } else {
        childSelectedValue.value = undefined;
      }
    }, 20);
  }
};
// RowKey配置
const getRowKey = (row: { [x: string]: any }) => {
  return row[props.keywords.value];
};
// 弹窗table搜索过滤
const searchModalChange = (_e: any) => {
  // console.log("searchModalChange", e.target.value, searchModalValue.value);
  filterMethodHandle(searchModalValue.value);
};
// 搜索过滤
const filterMethodHandle = (input: string) => {
  setTimeout(() => {
    const tableData = JSON.parse(JSON.stringify(props.table?.data));
    if (tableData && tableData.length > 0) {
      if (!(props.mode === "multiple")) {
        if (input) {
          state.selectedRowKeys = [];
        } else {
          tableData.map((item: { [x: string]: any }) => {
            if (item[props.keywords.value] === (state.selectedRows[0] && state.selectedRows[0][props.keywords.value])) {
              state.selectedRowKeys = [item[props.keywords.value]];
            }
          });
        }
      }
      state.tableData = tableData.filter((item: { [x: string]: string | any[] }) => {
        if (item[props.keywords.label].includes(input)) {
          return item;
        }
      });
      // 解决选中后,在过滤后,没有选中问题
      if (childSelectedValue.value) {
        state.activeTableRow = state.tableData.filter((item: { [x: string]: string | number | unknown[] | undefined }) => {
          return item[props.keywords.label] === childSelectedValue.value;
        })[0];
        state.selectedRows = state.tableData.filter((item: { [x: string]: string | number | unknown[] | undefined }) => {
          return item[props.keywords.label] === childSelectedValue.value;
        });
        state.selectedRowKeys = state.selectedRows.length > 0 && [state.selectedRows[0][props.keywords.value]];
        state.tableData = tableData.filter((item: { [x: string]: string | any[] }) => {
          if (item[props.keywords.label].includes(input)) {
            return item;
          }
        });
      }
    }
  }, 0);
};

// 表格显示隐藏回调
const visibleChange = (visible: boolean) => {
  // console.log("表格显示隐藏回调", visible);
  open.value = visible;
  if (visible) {
    if (props.defaultSelectVal && isDefaultSelectVal.value) {
      defaultSelect(props.defaultSelectVal);
    }
  } else {
    // findLabel();
    filterMethodHandle("");
  }
};

// tags删除后回调
const removeTag = (tag: any) => {
  const row = state.tableData.find((item: { [x: string]: any }) => item[props.keywords.label] === tag);
  if (row) {
    const indexRow = state.selectedRowKeys.indexOf(row[props.keywords.value]);
    indexRow === -1 ? state.selectedRowKeys.push(row[props.keywords.value]) : state.selectedRowKeys.splice(indexRow, 1);
    if (indexRow === -1) {
      state.selectedRows.push(row);
    } else {
      state.selectedRows.splice(indexRow, 1);
    }
    onSelectChange(state.selectedRowKeys, state.selectedRows);
  }
};
// 多选清空
const onSelectNone = () => {
  nextTick(() => {
    state.selectedRowKeys = [];
    state.selectedRows = [];
    state.activeTableRow = {};
    childSelectedValue.value = [];
  });
};
// 清空后的回调
const clear = () => {
  if (props.mode === "multiple") {
    onSelectNone();
  } else {
    console.log("单选");
    emits("checkedChange", {}, null); // 取消勾选就把回传数据清除
    onSelectNone();
  }
};
// 触发select隐藏
const blur = () => {
  selectRef.value.blur();
};
// 触发select显示
const focus = () => {
  selectRef.value.focus();
};
// 打开select下拉框
const openSelectDropdown = () => {
  open.value = true;
};
// 点击选择按钮
const selectBtnClick = () => {
  console.log("点击选择按钮");
  openModal.value = true;
};
// 弹窗点击确定
const handleOk = () => {
  // console.log("弹窗点击确定");
  searchModalValue.value = "";
  openModal.value = false;
  filterMethodHandle(""); // 关闭弹窗后刷新表格
};

// 暴露方法出去
defineExpose({ focus, blur, openSelectDropdown, clear, state, childSelectedValue });
</script>

<style lang="scss">
.t-antd-select-table {
  .ant-btn {
    margin-left: 2px;
  }
}
.t_antd_select_dropdown {
  min-width: auto !important;
  .t-table-select__table {
    padding: 10px;

    .ant-table-body,
    .ant-table-header {
      margin: 0;
    }
    .ant-table-body {
      .ant-table-tbody {
        .ant-table-row {
          cursor: pointer;
        }
        .ant-table-row-selected,
        .active-selected-row {
          color: #409eff;
          background-color: #ecf5ff;
        }
      }
    }
  }
  .ant-pagination {
    flex-wrap: nowrap;
  }
}
.t_select_modal {
  .ant-modal-content {
    padding: 10px 20px;
    .ant-modal-body {
      padding: 10px 0;
      .modal_search {
        display: flex;
        align-items: center;
        margin-bottom: 10px;
        .search_label {
          width: fit-content;
        }
        .ant-input-affix-wrapper {
          margin-right: 10px;
        }
      }
      .ant-table-body {
        .ant-table-tbody {
          .ant-table-row {
            cursor: pointer;
          }
          .ant-table-row-selected,
          .active-selected-row {
            color: #409eff;
            background-color: #ecf5ff;
          }
        }
      }
    }
  }
}
</style>


七、在线预览目录

在这里插入图片描述

源码地址

gitHub组件地址

gitee码云组件地址

在线预览地址

相关文章

基于ElementUi或AntdUI再次封装基础组件文档


基于Element-plus再次封装基础组件文档(vue3+ts)

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wocwin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值