645 字
3 分钟
el-select和el-cascader多选数据格式修改为字符串
2025-01-12

为什么要修改多选数据格式#

在使用element-ui的el-select和el-cascader组件时,多选数据格式是数组,而后端的实际需求是数组中的每个元素是逗号隔开的字符串,而不是对象。在使用中就需要转换数据类型,接收后端数据时时把字符串转为数组,在发送数据时,又把数组转为字符串。十分繁琐而且随意修改数据类型是很不提倡的行为。于是就想着修改组件的数据类型,使数据类型可以自定义。原本是要修改element-ui的源码并提交,但是发现element-ui已经很久不维护了,于是就只扩展element-ui的功能,而不修改原有代码。

el-select#

el-select组件的multiple属性是默认为false的,所以默认情况下是单选,如果需要多选,需要设置multiple属性为true。新建以下自定义组件str-select并全局注册,使用时直接使用str-select组件即可,组件的所有属性不变。

<template>
    <div>
      <el-select
        :value="internalValue"
        @change="handleChange"
        v-bind="filteredAttrs"
        v-on="filteredListeners"
        ref="select"
        :multiple="isMultiple"
      >
        <template v-for="(slotFn, name) in $scopedSlots" :slot="name" slot-scope="slotData">
          <slot :name="name" v-bind="slotData"></slot>
        </template>
      </el-select>
    </div>
  </template>
  
  <script>
  export default {
    name: "StrSelect",
    inheritAttrs: false,
    props: {
      value: {
        type: String,
        default: "",
      },
      multiple: {
        type: Boolean,
        default: false,
      },
    },
    data() {
      return {
        internalValue: this.multiple ? [] : "",
      };
    },
    computed: {
      filteredAttrs() {
        const { value, multiple, ...restAttrs } = this.$attrs;
        return restAttrs;
      },
      filteredListeners() {
        const { input, change, ...restListeners } = this.$listeners;
        return restListeners;
      },
      isMultiple() {
        return this.multiple;
      },
    },
    watch: {
      value: {
        immediate: true,
        handler(newValue) {
          if (this.isMultiple) {
            this.internalValue = newValue ? newValue.split(",").map((item) => item.trim()) : [];
          } else {
            this.internalValue = newValue || "";
          }
        },
      },
      internalValue: {
        handler(newValue) {
          if (this.isMultiple) {
            this.$emit("input", newValue.join(","));
          } else {
            this.$emit("input", newValue);
          }
        },
      },
    },
    methods: {
      handleChange(newValue) {
        this.internalValue = newValue;
        if (this.isMultiple) {
          this.$emit("change", newValue.join(","));
        } else {
          this.$emit("change", newValue);
        }
      },
      blur() {
        this.$refs.select.blur();
      },
      focus() {
        return this.$refs.select.focus;
      },
    },
  };
  </script>
  
  <style scoped>
  </style>
  

el-cascader#

el-cascader组件默认就返回数组。新建以下自定义组件str-cascader并全局注册,使用时直接使用el-cascader组件即可,除了emitPath以外,组件的所有属性不变,目前的str-cascader只支持emitPath为 false。

<template>
    <div>
      <el-cascader
        :value="internalArray"
        @change="handleChange"
        v-bind="filteredAttrs"
        v-on="filteredListeners"
        ref="cascader"
      >
      <template v-for="(slotFn, name) in $scopedSlots" :slot="name" slot-scope="slotData">
        <slot :name="name" v-bind="slotData"></slot>
      </template>
      </el-cascader>
    </div>
  </template>
  
  <script>
  export default {
    name: 'StrCascader',
    inheritAttrs: false,
    props: {
      value: {
        type: String,
        default: ''
      }
    },
    data() {
      return {
        internalArray: []
      };
    },
    computed: {
      filteredAttrs() {
        const { value, ...restAttrs } = this.$attrs;
        return restAttrs;
      },
      filteredListeners() {
        const { input,change, ...restListeners } = this.$listeners;
        return restListeners;
      }
    },
    watch: {
      value: {
        immediate: true,
        handler(newValue) {
          if (newValue) {
            this.internalArray = newValue.split(',').map(item => item.trim());
          } else {
            this.internalArray = [];
          }
        }
      },
      internalArray: {
        handler(newValue) {
          console.log(newValue,"newValue22");
          
          this.$emit('input', newValue.join(','));
        }
      }
    },
    methods: {
      handleChange(newValue) {
        this.internalArray = newValue;
        console.log(newValue,"newValue11");
        this.$emit('change', newValue.join(',')); 
      },
      getCheckedNodes(){
        return this.$refs.cascader.getCheckedNodes()
      },
      clearCheckedNodes(){
        return this.$refs.cascader.$refs.panel.clearCheckedNodes()
      },
    }
  };
  </script>
  
  <style scoped>
  </style>
  
el-select和el-cascader多选数据格式修改为字符串
https://xiyu.pro/posts/39/
作者
席宇
发布于
2025-01-12
许可协议
CC BY-NC-SA 4.0