前端项目el-cascader下拉项中因为数据权限变化导致显示未id

思路

  • 展示的时候展示对应的中文(需要后端返回 name value 以及一个判断当前数据不在权限内 的false状态)
  • 展示文字 value 需要由原来id 变为name
  • 输入框聚焦的时候值不变化的时候 数据不变
  • 重新选了数据以后 保留数据权限内的+自己新选的
  • 因为时间原因我上传了整个代码 有空我会精简下代码的
 <el-form @submit.native.prevent ref="form" :model="obj" :rules="rules">
        <el-form-item>
          <baseCascader :ref="obj.id" :config="config" @change="change" v-model="ids" @visible-change="confirm" />
        </el-form-item>
      </el-form>

+ config
 se() {
      se({
        selectType: 'TREE'
      }).then((res) => {
        this.options = getOptions(res.data.selectors)
        console.log(this.obj)
        this.config = {
          propChildren: 'childList',
          propLabel: 'value',
          propValue: 'id',
          multiple: true,
          checkStrictly: false,
          emitPath: false,
          filterable: false,
          placeholder: '请选择' + this.obj.instanceName,
          size: 'small',
          disabled: this.isDisabled,
          options: this.options,
          value: this.obj.value // 数据发生变化的时候获取name展示
        }
        this.$nextTick(() => {
             // 自动展开下拉框
            if (this.type !== 'stage') this.$refs[this.obj.id].toggleDropDownVisible()
        
        })
      })
    },

baseCascader 组件

<template>
  <div>
    <Cascader
      :value="range ? bindValue : valueName"
      ref="cascader_0"
      :append-to-body="true"
      :placeholder="config.placeholder"
      :key="cascaderKey"
      :options="config.options || config.option"
      :props="{
        children: config.propChildren || 'children',
        label: config.propLabel || 'label',
        value: config.propValue || 'value',
        expandTrigger: 'click',
        multiple: config.multiple,
        checkStrictly: config.checkStrictly || false,
        emitPath: config.emitPath || false
      }"
      @change="(val) => cascaderChange(val, `cascader_0`)"
      @visible-change="visibleChange"
      :popper-class="`cascader-900 ${popperClass}`"
      :class="['cascader-dept', config.class]"
      :disabled="config.disabled"
      :show-all-levels="config.showAllLevels || false"
      collapse-tags
      filterable
      :size="config.size || 'medium'"
      clearable
    >
      <template slot-scope="{ node, data }">
        <el-tooltip
          :content="data[config.propLabel || 'label']"
          :popper-options="{ boundariesElement: 'body', removeOnDestroy: true }"
          :disabled="!showTooltip"
          placement="top-end"
        >
          <span ref="childs" class="ellipsis" style="width: 100%" @mouseenter="ellipsisMouseenter">{{
            data[config.propLabel || 'label']
          }}</span>
        </el-tooltip>
      </template>
    </Cascader>
  </div>
</template>

<script>
import { mapState } from 'vuex'
 // Cascader  会写到下个代码中
import Cascader from '@/components/cascader.vue'
export default {
  name: 'BaseCascader',
  model: {
    prop: 'bindValue',
    event: ['change']
  },
  props: {
    bindValue: {
      type: [Number, String, Array],
      default: () => []
    },
    config: Object,
    unWatchCascaderKey: Boolean,
    popperClass: String
  },
  components: {
    Cascader
  },
  computed: {
    ...mapState(['authorizationStatus', 'configStatus'])
  },
  data() {
    return {
      showTooltip: false, // 级联溢出悬浮提示
      cascaderKey: 1,
      range: true,
      valueName: ''
    }
  },
  // 解决: Error in callback for watcher "options": "TypeError: Cannot read property 'level' of null"
  watch: {
    'config.options': {
      handler() {
        if (this.unWatchCascaderKey) return
        this.cascaderKey++
      }
    },
    'config.value': {
      handler(val) {
        /**
         * 1、回显来源数据:结构化表单数据、普通字符串、数组
         * 类型:  ⑴ { range:true, value:'', name:''}
         *       ⑵ [{ range:true, value:'', name:''}]
         *       ⑶ ['1234']
         *       ⑷ '1234'
         * 处理方式,统一转成id集合的数组形式
         */
        let res
        if (val) {
          // ⑴
          if (typeof val == 'object') res = [val]
          // ⑵⑶
          if (Array.isArray(val)) res = val
          // ⑴⑵
          if (Array.isArray(res) && res.some((item) => typeof item == 'object')) {
            this.range = res.every((item) => item.range)
            const nameArr = res?.map((o) => (o.range ? o.value : o.name))
            this.valueName = this.config.multiple ? nameArr : nameArr.join(',')
          } else {
            this.valueName = ''
          }
        }
      },
      immediate: true,
      deep: true
    }
  },

  methods: {
    checkedNodes() {
      return this.$refs.cascader_0.checkedNodes
    },
    toggleDropDownVisible() {
      this.$refs.cascader_0.toggleDropDownVisible()
    },
    cascaderChange(val, refName) {
      // 修改model中的值
      this.$emit('change', val)
      // 选中快捷搜索项不初始化面板,防止无法选中或取消的情况
      if (this.$refs[refName].filterable) {
        return
      }
      // 防止选中节点时,偶尔会切换到初始面板
      if (['personSingle', 'personMulti'].includes(this.config.instanceType) && this.$refs[refName]) {
        const activePath = this.$refs[refName].panel.activePath
        this.$refs[refName].panel.initStore()
        this.$refs[refName].panel.activePath = activePath
        this.$refs[refName].panel.syncMenuState()
      }
    },
    // 解决: 级联选择器多次点击导致页面奔溃问题
    visibleChange(e) {
      this.$nextTick(() => {
        const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]')
        Array.from($el).map((item) => item.removeAttribute('aria-owns'))
      })
      this.$emit('visible-change', e, this.bindValue)
    },
    // 文字过长显示tootip
    ellipsisMouseenter(e) {
      const { target } = e
      if (target.scrollWidth > target.offsetWidth) {
        this.showTooltip = true
        return
      }
      this.showTooltip = false
    }
  }
}
</script>


在这里插入代码片
在这里插入代码片

你可能感兴趣的:(前端)