<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: {
onFinish({ selectedOptions }) {
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
}
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地址')
}
},
setTreeData(source) {
const cloneData = JSON.parse(JSON.stringify(source))
return cloneData.filter((father) => {
const branchArr = cloneData.filter((child) => father.dictCode === child.parentCode)
branchArr.length > 0 && (father.children = branchArr)
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) {
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>