封装组件 components/TSelect
<template>
<el-select
v-model="selectValue"
v-loading="loading"
:placeholder="placeholder"
filterable
clearable
:disabled="disabled"
@change="changeEvent"
@clear="clearEvent"
>
<el-option
v-for="item in opitonList"
:key="item.treedataid"
:disabled="isLast?((!!item[props['disabled']||'blnisinactive'])||(!item[props['last']||'blnisdetail'])):!!item[props['disabled']||'blnisinactive']"
:label="props['codes'] ? (item[props['label']||'treedataname']+item.dot+item.pinyin) : (item[props['label']||'treedatacodeandname']+item.dot+item.pinyin)"
:value="item[props['value']||'treedataid']"
>
<span :style="{'float':'left','text-indent':(item.level-1)*1+'em','width':'100%'}" @click="selectEvent(item)">{{ item[props['label']||'treedatacodeandname'] }}</span>
</el-option>
</el-select>
</template>
<script>
import { flatten } from '@/base/utils'
export default {
name: 'TSelect',
props: {
props: { // 配置项
type: Object,
default() {
return {
value: 'treedataid',
label: 'treedatacodeandname',
disabled: 'blnisinactive',
last: 'blnisdetail',
codes: false
}
}
},
isLast: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
value: {
type: [Number, String],
default: ''
},
dotLength: {
type: Number,
default: 200
},
options: { // 选项列表数据
type: Array,
default() {
return []
}
},
placeholder: {
type: String,
default: '请选择'
},
isInline: {
type: Boolean,
default: false
},
loading: {
type: Boolean,
default: false
}
},
data() {
return {
opitonList: [],
firstLoad: true
}
},
computed: {
selectValue: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
}
},
watch: {
'options'(newval) {
if (newval.length >= 0 && this.firstLoad) {
this.firstLoad = false
setTimeout(() => {
this.firstLoad = true
}, 300)
this.opitonList = this.flatten(this.options).map(item => { return { pinyin: this.allPinYin(this.props['codes'] ? (item[this.props['label'] || 'treedataname']) : (item[this.props['label'] || 'treedatacodeandname'])), dot: this.getDots(this.dotLength), ...item } })
}
}
},
created() {
if (this.isInline && this.options.length > 0 && this.firstLoad) {
this.firstLoad = false
this.opitonList = this.flatten(this.options).map(item => { return { pinyin: this.allPinYin(this.props['codes'] ? (item[this.props['label'] || 'treedataname']) : (item[this.props['label'] || 'treedatacodeandname'])), dot: this.getDots(this.dotLength), ...item } })
}
},
methods: {
flatten,
// 获取选中的value值
changeEvent(val) {
this.$emit('change', val)
},
clearEvent() {
this.$emit('clear')
},
// 获取整个条目对象
selectEvent(item) {
if (item[this.props['value']] === this.selectValue) {
return false
}
this.$emit('select', item)
},
allPinYin(str) {
if (!window.pinyinUtil) {
console.log('缺少拼音库依赖,需要在index.html引入pinyinjs库!')
return ''
}
// eslint-disable-next-line
return pinyinUtil.getFirstLetter(str).toLowerCase() + pinyinUtil.getPinyin(str).replace(/s/g, '')
},
getDots(num = 10) {
return ' '.repeat(num)
}
}
}
</script>
base/utils/index.js
// 扁平化树形json
export function flatten(data, level = 0) {
if (data.length === 0) {
level = 0
}
++level
return data.reduce((arr, { treedataid, treedatacode, treedataname, treedatacodeandname, lngparentid, lngextendid, blnisdetail, path, intlevel, blnisinactive, childList = [] }) =>
arr.concat([{ treedataid, treedatacode, treedataname, treedatacodeandname, lngparentid, lngextendid, blnisdetail, path, intlevel, blnisinactive, level: level }], flatten(childList, level)), [])
}
引入组件在项目中使用
<el-form-item label="支出项目类别" prop="lngoutitemtypeid">
<TSelect
v-model="formInline.lngoutitemtypeid"
style="130px"
placeholder="请选择"
:options="outItemTypeList"
:is-last="true"
/>
</el-form-item>