vue+element 下拉框选择加搜索并且列表选项带图片

子组件代码:

<template>

  <!-- 单选下拉框 -->

  <el-select

    v-model.trim="selectValue"

    filterable

    clearable

    :placeholder="placeText"

    :filter-method="filterMethod"

    :loading="loading"

    @clear="clearSub"

    @focus="focusSub"

    @change="changeSubCoin"

    class="subSelect"

    ref="subSelect"

    v-if="selectType != 4"

  >

    <el-option

      v-for="(item, index) in selectOptions"

      :key="index"

      :label="item.subName"

      :value="item.subId"

    >

      <img :src="getImgUrl(item.icon)" v-if="selectType != 4" />

      <span>{{ item.subName ? item.subName : item.name }}</span>

    </el-option>

  </el-select>

  <!-- 多选下拉框 -->

  <el-select

    v-model.trim="multipleSelectValue"

    filterable

    clearable

    :placeholder="placeText"

    :filter-method="filterMethod"

    :loading="loading"

    multiple

    collapse-tags

    @clear="clearSub"

    @focus="focusSub"

    @remove-tag="removeTag"

    @change="searchTableList"

    class="subSelect1"

    ref="subSelect1"

    v-else

  >

    <el-option

      v-for="(item, index) in multipleSelectOptions"

      :key="index"

      :label="item.name"

      :value="item.name"

    >

    </el-option>

  </el-select>

</template>

<script>

import {

  accountSearch,

  querySelectionList,

} from "@/api/account.js";

export default {

  props: {

    selectType: {

      type: Number,

      default: 1,

    },

    accountId: {

      type: String,

      default: "",

    },

    searchType: {

      // 0 :去向  1:来源

      type: Number,

      default: 0,

    },

    placeholderText: {

      type: String,

      default: "",

    }

  },

  data() {

    return {

      loading: false,

      selectOptions: [], // 单选下拉框列表选项

      selectValue: "", // 单选下拉框值

      selectName: "", // 单选下拉框名

      placeText: "请选择发放账户",

      multipleSelectValue: [], // 多选下拉框列表选项

      multipleSelectOptions: [], // 多选下拉框值

    };

  },

  mounted() {

    if (this.selectType === 1) {

      this.accountSearchList("");

    } else {

      this.getSelectionList(this.accountId, "", this.searchType);

      if (this.searchType == 0) {

        this.placeText = "请选择去向";

      } else {

        this.placeText = "请选择来源";

      }

    }

  },

  methods: {

    // 获取下拉框图片路径

    getImgUrl(img) {

      return require("@/assets/images/" + img); // 本地图片

    },

    // 发放虚拟币下拉选项支持模糊搜索匹配功能

    accountSearchList(params) {

      let param = {

        queryParam: params,

      };

      accountSearch(param).then((response) => {

        let res = response.data;

        if (res.code == 200) {

          this.selectOptions = res.data;

          sessionStorage.setItem("selectQuery", "");

        }

      });

    },

    // 账户明细-来源去向下拉选择框获取

    getSelectionList(accountId, params, type) {

      accountId = this.accountId

        ? this.accountId

        : sessionStorage.getItem("accountId");

      params = "";

      type = this.searchType;

      querySelectionList(accountId, params, type).then((response) => {

        let res = response.data;

        if (res.code == 200) {

          this.multipleSelectOptions = res.data;

        }

      });

    },

    filterMethod(query) {

      this.selectOptions = [];

      this.loading = true;

      this.getRemote(query);

    },

    getRemote: _.debounce(async function (query) {

      let query1 = sessionStorage.setItem("selectQuery", query);

      if (query !== "") {

        if (query != query1) {

          let param = {

            queryParam: query,

          };

          if (this.selectType === 1) {

            this.loading = false;

            let res = await accountSearch(param);

            this.selectOptions = res.data.data;

          } else if (this.selectType === 4) {

            this.loading = false;

            let res = await querySelectionList(

              this.accountId

                ? this.accountId

                : sessionStorage.getItem("accountId"),

              query,

              this.searchType

            );

            this.multipleSelectOptions = res.data.data;

          }

        }

      } else {

        this.clearSub();

      }

    }, 500),

    // 清空下拉框数据时触发

    clearSub() {

      this.loading = false;

      if (this.selectType !== 4) {

        sessionStorage.setItem("selectQuery", "");

        this.selectValue = "";

        this.selectName = "";

        let arr = [this.selectValue, this.selectName];

        this.$emit("getQuery", arr);

        this.placeText = "请选择发放账户";

        if (this.selectType === 1) {

          this.accountSearchList("");

        }

      } else {

       if (this.multipleSelectValue && this.multipleSelectValue.length > 0) {

        this.$emit("getParams", this.multipleSelectValue);

       } else {

         if (this.searchType == 0) {

          this.placeText = "请选择去向";

        } else {

          this.placeText = "请选择来源";

        }

        this.multipleSelectValue = [];

        this.$emit("getParams", this.multipleSelectValue);

        this.getSelectionList(

          this.accountId ? this.accountId : sessionStorage.getItem("accountId"),

          "",

          this.searchType

        );

       }

      }

    },

    // 聚焦时触发

    focusSub() {

      let query = sessionStorage.getItem("selectQuery");

       if (this.multipleSelectValue && this.multipleSelectValue.length > 0) {

        this.$emit("getParams", this.multipleSelectValue);

       } else {

         if (this.searchType == 0) {

          this.placeText = "请选择去向";

        } else {

          this.placeText = "请选择来源";

        }

        this.multipleSelectValue = [];

        this.$emit("getParams", this.multipleSelectValue);

        this.getSelectionList(

          this.accountId ? this.accountId : sessionStorage.getItem("accountId"),

          "",

          this.searchType

        );

       }

      if (this.selectValue && query != "") {

        if (this.selectType !== 4) {

          this.selectValue = "";

          this.selectName = "";

          let arr = [this.selectValue, this.selectName];

          this.$emit("getQuery", arr);

          this.accountSearchList("");

        }

      } else {

        if (query) {

          if (this.selectType === 1) {

            this.accountSearchList("");

            this.placeText = "请选择发放账户";

          }

        }

      }

    },

    // 多选移除标签时触发

    removeTag() {

      if (this.multipleSelectValue && this.multipleSelectValue.length == 0) {

         if (this.searchType == 0) {

          this.placeText = "请选择去向";

        } else {

          this.placeText = "请选择来源";

        }

        this.multipleSelectValue = [];

        this.$emit("getParams", this.multipleSelectValue);

        this.getSelectionList(

          this.accountId ? this.accountId : sessionStorage.getItem("accountId"),

          "",

          this.searchType

        );

       }

    },

    // 切换子账户

    changeSubCoin(e) {

      this.selectValue = e;

      sessionStorage.setItem("selectQuery", "");

      this.selectOptions.forEach((item) => {

        if (item.subId == e) {

          this.selectName = item.subName;

        }

        if (item.id == e) {

          this.selectName = item.name;

          let subTagType = item.type;

          sessionStorage.setItem("subTagType", subTagType);

          this.$emit("getSubTagType", subTagType);

        }

      });

      let arr = [this.selectValue, this.selectName];

      this.$emit("getQuery", arr);

    },

    searchTableList(e) {

      this.multipleSelectValue = e;

      this.$emit("getParams", this.multipleSelectValue);

    },

  },

};

</script>

<style scoped>

.el-select-dropdown__item {

  display: flex;

  align-items: center;

}

img {

  display: inline-block;

  width: 70px;

  height: 24px;

  margin-right: 10px;

}

</style>

<style lang="scss" scoped>

.subSelect {

  width: 240px;

}

.subSelect1 {

  width: 260px;

  /deep/.el-select__tags-text { // 解决下拉框文本过长溢出

    display: inline-block;

    max-width: 150px;

    overflow: hidden;

    white-space: nowrap;

    text-overflow: ellipsis;

  }

  /deep/.el-tag__close.el-icon-close {

    top: -7px;

  }

  /deep/ .el-input__suffix {

    height: 40px !important;

  }

}

</style>

单选框父组件代码:

<!-- 搜索下拉组件 -->

<template>

<div>

<select-search

    :selectType="1"

     @getQuery="getQuery"

     ref="subSelect"

></select-search>

</div>

</tempalte>

import SelectSearch from "@/components/selectSearch/index.vue";

export default {

  components: {

    SelectSearch

  },

  data() {

    return {

      accountId: "", // 账户id

      subValue: "", // 子账户值

      subName: "", // 子账户名

    };

  },

  methods: {

    getQuery(value) {

      this.subValue = value[0];

      this.subName = value[1];

    },

}

多选框父组件代码:

<!-- 搜索下拉组件 -->

<template>

<div>

<select-search

    :selectType="4"

    :placeholderText="placeholderText1"

     :accountId="accountId"

     :searchType="0"

      @getParams="getdirection"

      ref="subSelect"

 ></select-search>

</div>

</tempalte>

import SelectSearch from "@/components/selectSearch/index.vue";

export default {

  components: {

    SelectSearch

  },

  data() {

    return {

  direction: [],

      placeholderText1: "请选择去向",

      accountId: "",

    };

  },

created() {

    this.accountId = sessionStorage.getItem("accountId");

  },

  methods: {

    getdirection(value) {

      this.direction = value;

    }

    },

}

  • 23
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个基于VueElement组件库的虚拟列表下拉框实现。在这个下拉框中,当列表项数量非常多时,只会渲染可视区域的部分,从而提高性能。 ```html <template> <el-select v-model="selected" placeholder="请选择" filterable remote :remote-method="loadOptions"> <template v-slot:default> <el-option v-for="item in visibleOptions" :key="item.value" :label="item.label" :value="item.value"></el-option> <el-option v-if="isLastPage" :key="'loading'" :label="'载中...'" disabled></el-option> </template> </el-select> </template> <script> export default { data() { return { options: [], // 所有选项 visibleOptions: [], // 可见选项 selected: undefined, // 当前选中的值 pageSize: 10, // 每页显示的选项数量 currentPage: 1, // 当前页码 isLastPage: false // 是否已经载完所有选项 }; }, methods: { async loadOptions(query) { // 模拟异步载数据 await new Promise(resolve => setTimeout(resolve, 1000)); // 这里可以根据query参数从服务器获取数据 const data = Array.from({ length: 10000 }, (_, i) => ({ label: `选项${i + 1}`, value: i + 1 })); // 如果没有更多数据了,则标记为最后一页 if (data.length < this.pageSize) { this.isLastPage = true; } // 将新数据合并到原有数据中 this.options = this.options.concat(data); // 更新可见选项 this.updateVisibleOptions(query); }, updateVisibleOptions(query) { const start = (this.currentPage - 1) * this.pageSize; const end = start + this.pageSize; this.visibleOptions = this.options.slice(start, end); // 如果没有匹配的选项,则跳转到第一页 if (query && this.visibleOptions.every(item => !item.label.includes(query))) { this.currentPage = 1; this.updateVisibleOptions(query); } } }, watch: { currentPage() { // 每次切换页码时更新可见选项 this.updateVisibleOptions(); } } }; </script> ``` 在这个实现中,我们使用了`el-select`组件来实现下拉框,设置了`filterable`和`remote`属性来启用搜索和异步载功能。每当用户输入查询关键字时,`loadOptions`方法就会被调用,该方法会模拟异步载数据,并将新数据合并到`options`列表中。同时,根据当前页码和每页显示的选项数量,计算出可见选项的范围,并将其赋值给`visibleOptions`属性。如果没有匹配的选项,则跳转到第一页。如果已经载完所有选项,则将`isLastPage`属性标记为`true`,以便在可见选项列表中显示“载中...”的提示。用户每次滚动列表时,会触发`loadOptions`方法,从而实现虚拟滚动的效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值