likes
comments
collection
share

二次封装element组件下拉框实现添加下拉框选项

作者站长头像
站长
· 阅读数 19

二次封装element组件下拉框实现添加下拉框选项

组件功能

  • 在开发项目时,产品提了新需求,需要在下拉框的地方增加一个添加选项然后发送请求,在数据库里把新数据加入字典中。

遇到的问题:

  • 最初的思路是希望在下拉框里写一个添加选项按钮,点击添加选项按钮,按钮变成输入框,然后输入需要添加的选择项,输入框失焦发送请求,可后面发现失焦发请求,有那么些不合适,就使用了下面这个方案即:
  • 点击添加选项,弹出对话框,在对话框的输入框内填写内容,点击确定,然后发送请求

效果演示:

二次封装element组件下拉框实现添加下拉框选项

下面是组件内容,因为涉及到接口(传递参数),所以内部传值可以自己根据字段定制

<template>
  <el-select
    v-model="labels"
    :multiple="false"
    :placeholder="`请选择${order}`"
    ref="template"
    :disabled="disabledSelect"
    clearable
    @visible-change="(v) => visibleChange(v, 'template')"
  >
    <el-option
      v-for="(item, index) in labelslist"
      :key="index"
      :label="item[label]"
      :value="item[val]"
    >
      {{ item[label] }}
      <!-- <span style="float: left" class="span-style">{{ item.value }}</span> -->
      <span style="float: right" class="span-style"></span>
      <div class="flag" @click="showShipTemplate(item.code, true)"></div>
    </el-option>
  </el-select>
</template>
<script>
export default {
  name: "selectAdd",
  props: {
    // 最开始的下拉列表数据
    labelslist: {
      type: Array,
      default: [],
    },
    // 新增选项的接口
    api: {
      type: Function,
      default: () => {},
    },
    // 新增选项的字段
    // query: {
    //   type: String,
    //   default: "stationName",
    // },
    // 下拉框label绑定显示的字段名
    label: {
      type: String,
      default: "label",
    },
    // 下拉框label绑定数据的字段名
    val: {
      type: String,
      default: "value",
    },
    // 下拉框的名字
    order: {
      type: String,
      default: "选项",
    },
    // 外部绑定的下拉框的数据
    formVla: {
      type: String,
      default: "",
    },
    // 发送请求,需要携带的其他参数
    paramsObj:{
      type:Object,
      default:()=>{}
    },
    // 是否禁用下拉框
    disabledSelect: {
      type: Boolean,
      default: false,
    },
    // 添加选项的按钮是否在最上方
    isUp:{
      type:Boolean,
      default:true
    },
  },
  data() {
    return {
      // labelslist: [],
      labels: "",
      params: {},
    };
  },
  created() {
    this.labels = this.formVla;
  },
  methods: {
    getData(api) {

      this.params[this.label] = this.labels;

      if(this.paramsObj) this.params = {...this.params,...this.paramsObj}
      // console.log(this.params, "_____________23141234");
      return new Promise(() => {
        api(this.params)
          .then((res) => {
            if (res.code === "000000") {
              this.$message.success("新增成功!");
              this.$emit("getQueryStationList",true);
            }
          })
          .catch(() => {
            this.$message.error("数据加载失败!");
          });
      });
    },
    // 添加商品标签
    showShipTemplate() {
      this.$prompt(`请输入新的${this.order}`, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
      }).then(({ value }) => {
        this.labels = value;
        this.getData(this.api);
      });
    },
    visibleChange(visible, refName) {
      this.$nextTick(() => {
        if (visible) {
          const ref = this.$refs[refName];
          let popper = ref.$refs.popper;
          if (popper.$el) popper = popper.$el;
          if (
            !Array.from(popper.children).some(
              (v) => v.className === "el-template-menu__list"
            )
          ) {
            const el = document.createElement("ul");
            el.className = "el-template-menu__list";
            el.style =
              "border-bottom:2px solid rgb(219 225 241); padding:0; color:rgb(64 158 255);font-size: 13px;margin: 0px;text-align: center; ";
            el.innerHTML = `<li class="el-cascader-node text-center" style="height:36px;line-height: 36px;">
            <span class="el-cascader-node__label"><i class="font-blue el-icon-plus"></i>添加${this.order}</span>
            </li>`;
            // console.log(popper.childNode,'sssssssssssssss')
            // console.log(popper.children[0], "231111111111");
            // console.log(popper, "popper");
            if(this.isUp){
               popper.insertBefore(el, popper.children[0]);
             }else{
               popper.appendChild(el);
             }
            el.onclick = () => {
              this.showShipTemplate(null, false);
            };
          }
        }
      });
    },

},
}; </script>
        // 模板内使用
      <SelectAdd :labelslist="selectList" >
      </SelectAdd>
       selectList: [
        {
          value: "1",
          label: "小红",
        },
        {
          value: "2",
          label: "小明",
        },
        {
          value: "3",
          label: "小李",
        },
        {
          value: "4",
          label: "小张",
        },
        {
          value: "5",
          label: "小刘",
        },
      ],

其本质原理使用在下拉框最前面加上了一个按钮(按钮位置也可以控制,isUp参数默认最上方)

注意事项:

  • getQueryStationList这个函数是组件在发送请求新增成功之后,通知父组件需要做一些操作的事件
  • prop内接收的参数,type为String的,父组件在使用此组件时不需要加:,因为加:传递的变量,不加传递的直接就是字符串( <SelectAdd :labelslist="selectList" val="value" label="label" > </SelectAdd>)

具体其他的参数及用处都在代码块写备注了!!!