思路
- 展示的时候展示对应的中文(需要后端返回 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>
在这里插入代码片
在这里插入代码片