el-select 搜索无选项时 请求接口添加输入的值
实现思路:在搜索方法中把输入的值储存起来,然后通过搜索为空的插槽显示需要添加的值,点击添加的时候请求添加选项接口
如果数据量少的话可以直接本地搜索,在为空的情况下添加所需的值,然后在添加成功后重新请求一次全部值
- <div class="flex">
- <el-select class="w250" v-model="state.brand.id" placeholder="请选择" clearable
- filterable :filter-method="handleQuery" @change="tagHandler">
- <el-option v-for="item in state.tableData" :key="item.id"
- :label="item.displayName" :value="item.id">
- el-option>
- // 搜索为空时的插槽
- <template #empty>
- <div class="add-item">
- <span class="add-item-value" @click="addBrand">
- <el-icon><Plus />el-icon>添加
- <span class="searchValue">{{ state.searchValue }}span>
- span>
- div>
- template>
- el-select>
- div>
- <script setup lang="ts">
- import { reactive, onMounted } from 'vue';
- const state = reactive({
- // 品牌的数据结构
- brand: {
- id: undefined,
- displayName: '',
- },
- // 全部的选项
- tableData: [] as any,
- // 存放输入的值
- searchValue: '',
- });
-
- onMounted(() => {
- // 初始请求一次全部选项
- handleQuery('');
- });
-
- // 选择以后清空选择框的输入值
- const tagHandler = () => {
- state.searchValue = '';
- };
-
- // 输入值开始搜索
- const handleQuery = async (e: any) => {
- // 把输入的值存起来,页面显示需要用
- state.searchValue = e;
- let res = await getAPI(ProductExtApi);
- state.tableData = res.data.result?.items ?? [];
- };
-
-
- // 添加品牌
- const addBrand = async () => {
- // 请求添加接口
- let res = await getAPI(BrandApi)({
- displayName: state.searchValue,
- });
-
- // 接口返回ID 赋值到我们自定义的数据上面
- state.brand = {
- id: res.data.result ?? 0,
- displayName: state.searchValue,
- };
-
- // 添加完执行一次搜索
- if (res.data.code == 200) handleQuery(state.searchValue);
- };
-
- // 组件初始化的时候判断选项里有没这个值,没有的话手动push进去
- const init = (brand: any) => {
- if (brand) {
- if (!state.tableData.find((el: any) => el.id == brand.id)) {
- state.tableData.push(brand);
- }
- state.brand = brand;
- }
- };
-
- script>
-
- <style lang="scss" scoped>
-
- .add-item {
- padding: 10px;
- font-size: 14px;
-
- .add-item-value {
- cursor: pointer;
- }
-
- i {
- vertical-align: text-top;
- margin-right: 5px;
- }
-
- .searchValue {
- color: var(--el-color-primary);
- margin-left: 5px;
- }
- }style>