<template>
<div class="cascader">
<van-field v-model="fieldValue"
is-link
readonly
:label="label"
:required="required"
:rules="rules"
:placeholder="placeholder"
@click="show = true" />
<van-popup v-model="show"
round
position="bottom">
<van-cascader v-model="cascaderValue"
:title="label"
:options="options"
@change="selectChange"
active-color="#1989fa"
:field-names="fieldNames"
@close="show = false"
@finish="onFinish" />
</van-popup>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
default: () => ''
},
isCode: {
type: Boolean,
default: () => false
},
name: {
type: String,
default: () => '默认'
},
valueKey: {
type: String,
default: () => 'value'
},
labelKey: {
type: String,
default: () => 'label'
},
label: {
type: String,
default: () => '默认'
},
prop: {
type: String,
default: () => ''
},
url: {
type: String,
default: () => ''
},
superCodeVal: {
type: String,
default: () => ''
},
required: {
type: Boolean,
default: () => false
},
rules: {
type: Array,
default: () => []
},
placeholder: {
type: String,
default: ''
},
lastLevel: {
type: Number,
default: () => 3
}
},
data() {
return {
show: false,
fieldValue: '',
cascaderValue: '',
fieldNames: {
text: 'dictName',
value: 'dictCode'
},
options: [],
isExecute: 1,
tileArr: []
}
},
methods: {
// 全部选项选择完毕后,会触发 finish 事件
onFinish({ selectedOptions }) {
// this.show = false
if (this.level > 0) {
this.show = false
}
if (this.isCode) {
this.fieldValue = selectedOptions.map((option) => `${option.dictName}(${option.dictCode})`).join('/')
} else {
const fieldValue = selectedOptions.map((option) => option.dictName).join(',')
if (fieldValue.split('/').length) {
this.fieldValue = fieldValue
this.$emit('input', fieldValue)
return
}
this.fieldValue = fieldValue.split(',').join('/')
}
this.$emit('input', this.fieldValue.split('/') + '')
},
selectChange({ value, selectedOptions, tabIndex, index }) {
this.level = tabIndex > 0 ? tabIndex - 1 : 0
// 判断循环了多少次 并且是回显还是重新选择
if (this.isExecute >= this.lastLevel + 1 && !selectedOptions) {
return
}
// 判断重新选择的个数是否大于传入的lastLevel
if (selectedOptions && selectedOptions.length >= this.lastLevel) {
return
}
if (this.url) {
this.$http.post(this.url, { level: this.level, parentCode: value }).then((res) => {
// 检查重复项
if (!this.deWeightFour(this.tileArr, res.data)) {
this.tileArr.push(...res.data)
}
if (res.data && res.data.length) {
this.isExecute++
this.getDicData(index++)
}
this.$set(this, 'options', this.setTreeData(this.tileArr))
})
} else {
console.error('请配置Url地址')
}
},
// 遍历数据并添加children
setTreeData(source) {
const cloneData = JSON.parse(JSON.stringify(source)) // 对源数据深度克隆
return cloneData.filter((father) => {
// 循环所有项,并添加children属性
const branchArr = cloneData.filter((child) => father.dictCode === child.parentCode) // 返回每一项的子级数组
branchArr.length > 0 && (father.children = branchArr) // 给父级添加一个children属性,并赋值
return father.parentCode === this.superCodeVal // 返回第一层
})
},
// 判断要添加的值是否在这个数组李是否有重复
deWeightFour(sourceData, inspectData) {
const source = sourceData.map((item) => item.id)
return inspectData.map((item) => source.includes(item.id)).includes(true)
},
getDicData(tabIndex = 0) {
// eslint-disable-next-line no-useless-escape
const str = this.value.split(',').map((item) => item.replace(/\([^\)]*\)/g, ''))
const items = str[tabIndex]
this.tileArr.forEach((item) => {
if (item.dictName === items) {
console.log(item.dictCode)
this.cascaderValue = item.dictCode
this.selectChange({ value: item.dictCode, tabIndex: 0, index: ++tabIndex })
}
})
}
},
created() {
this.fieldValue = this.value.split(',').join('/')
this.selectChange({ value: this.superCodeVal, tabIndex: 1 })
},
watch: {
value: {
handler(v) {
this.fieldValue = this.value.split(',').join('/')
}
},
show: {
handler(v) {
if (v && this.fieldValue && this.isExecute) {
this.getDicData()
}
}
}
}
}
</script>
<style>
</style>