用过uniapp开发过小程序的都知道坑很多,很多组件都需要自己再封装,自己封装了一个通用的多列选择器,下面做一个记录
多列选择器
<!-- 多列选择器 -->
<template>
<picker mode="multiSelector" @columnchange="handleColumnChange" @change="pickerChange" :value="multiIndex" :range="multiArray" :range-key="rangekey">
<view class="uni-input space-between" hover-class="hover-color">
<slot name="before"></slot>
<text class="input-content ellipsis" :class="name?'':'color-placeholder'">{{name?name:placeholder}}</text>
<text class="iconfont icon-arrow-right input-icon text-light iconArea"></text>
<slot name="after"></slot>
</view>
</picker>
</template>
<script>
export default {
props: {
value: { default: ''}, // 必须要使用value
list: { type: Array, default: [] },
rangekey: { default: 'name' }, // 对应name取值
childkey: { default: 'children' }, // 子集
code: { default: 'code' }, // 对应value取值
pidkey: { default: 'pid' }, // 对应父id取值
placeholder: { default: '请选择' },
emitPath: { default: false, type: Boolean }, // 是否子父级关联 ,是的时候返回的是逗号分隔的父子code
level: { default: 3, type: Number } // 列数 2或者3
},
data() {
return {
multiArray: [[],],
multiIndex: [0, 0, 0],
name: "",
}
},
methods: {
handleColumnChange(e) {
let columnindex = e.detail.value; // 拖动列索引
switch (e.detail.column) {
case 0: //拖动第1列
// 第二级
let arr1 = this.multiArray[0];
this.multiArray[1] = arr1[columnindex][this.childkey]||[];
if(this.level === 3) {
// 第三级
let arr2 = this.multiArray[1];
this.multiArray[2] = arr2[0][this.childkey]||[];
}
this.multiIndex.splice(0, 1, columnindex)
this.multiIndex.splice(1, 1, 0)
this.multiIndex.splice(2, 1, 0)
break
case 1: //拖动第2列
if (this.level === 3) {
// 第三级
let arr3 = this.multiArray[1];
this.multiArray[2] = arr3[columnindex][this.childkey]||[];
}
this.multiIndex.splice(1, 1, columnindex)
this.multiIndex.splice(2, 1, 0)
break
}
},
//
pickerChange(e) {
let multiIndex = e.detail.value;
// 判断二级父元素不是一级,则重置二三级为0
if(this.multiArray[1][multiIndex[1]] && (this.multiArray[1][multiIndex[1]][this.pidkey] !== this.multiArray[0][multiIndex[0]].id)) {
console.log('二级')
// 第二级
let arr1 = this.multiArray[0];
this.multiArray[1] = arr1[multiIndex[0]][this.childkey]||[];
if(this.level === 3) {
// 第三级
let arr2 = this.multiArray[1];
this.multiArray[2] = arr2[0][this.childkey]||[];
}
multiIndex.splice(1, 1, 0)
multiIndex.splice(2, 1, 0)
}else if(this.multiArray[2] && this.multiArray[2][multiIndex[2]] && (this.multiArray[2][multiIndex[2]][this.pidkey] !== this.multiArray[1][multiIndex[1]].id)) {
console.log('三级')
if (this.level === 3) {
// 第三级
let arr3 = this.multiArray[1];
this.multiArray[2] = arr3[multiIndex[1]][this.childkey]||[];
}
multiIndex.splice(2, 1, 0)
}
if(this.emitPath) {
let codeArr = [], nameArr = [];
for(let i = 0; i < multiIndex.length; i++ ) {
if(this.multiArray[i] && this.multiArray[i][multiIndex[i]]) {
codeArr.push(this.multiArray[i][multiIndex[i]][this.code]);
nameArr.push(this.multiArray[i][multiIndex[i]][this.rangekey]);
}
}
let code = codeArr.join(',');
this.name = nameArr.join('/');
this.$emit('input', code)
}else {
let curArr = this.multiArray[2], code='';
if(curArr && curArr.length) {
code = curArr[multiIndex[2]][this.code];
this.name = curArr[multiIndex[2]][this.rangekey];
}else {
curArr = this.multiArray[1]
code = curArr[multiIndex[1]][this.code];
this.name = curArr[multiIndex[1]][this.rangekey];
}
this.$emit('input', code)
}
},
// 初始化级联数据
dataInit() {
// 第一级
this.multiArray[0] = this.list;
// 第二级
let arr1 = this.multiArray[0];
this.multiArray.push(arr1[this.multiIndex[0]][this.childkey]||[]);
if(this.level === 3) {
// 第三级
let arr2 = this.multiArray[1];
this.multiArray.push(arr2[this.multiIndex[1]][this.childkey]||[]);
}
},
curDataFind (data, code) {
let result;
if (!data) {
data = this.list;
}
for (var i = 0; i < data.length; i++) {
let item = data[i];
if (result) {
return result;
}
if (item[this.code] === code) {
result = item;
break;
} else if (item[this.childkey] && item[this.childkey].length > 0) {
result = this.curDataFind(item[this.childkey], code);
}
}
return result;
},
initName() {
if(this.list.length && this.value) {
if(this.emitPath) {
let nameArr = [], codeArr = this.value.split(',');
for(let i = 0; i < codeArr.length; i++ ) {
let item = this.curDataFind(this.list, codeArr[i]);
nameArr.push(item[this.rangekey]);
}
this.name = nameArr.join('/');
} else {
let item = this.curDataFind(this.list, this.value);
this.name = item[this.rangekey];
}
}else {
this.name = '';
}
}
},
watch: {
list: {
immediate: true,
handler(val) {
this.dataInit();
this.initName();
}
},
value: {
immediate: true,
handler(val) {
this.initName();
}
},
}
}
</script>
<style lang="scss" scoped>
</style>
附送单列选择器
单列选择器
<!-- 单列选择器 -->
<template>
<picker @change="bindPickerChange" :value="index" :range="list" :range-key="rangekey">
<view class="uni-input space-between font-md" hover-class="hover-color">
<text class="input-content ellipsis" v-if="coustomValue&&isCoustom">{{coustomValue}}</text>
<text class="input-content ellipsis" v-else-if="list[index][rangekey]">{{list[index][rangekey]}}</text>
<text class="input-content ellipsis color-placeholder" v-else>{{placeholder}}</text>
<text class="iconfont icon-arrow-right input-icon text-light"></text>
</view>
</picker>
</template>
<script>
export default {
props: {
value: { default: ''},// 必须要使用value
list: { type: Array, default: [] },
rangekey: { default: 'name' },
code: { default: 'code' },
placeholder: { default: '请选择' },
coustomValue: { default: ''},
},
data() {
return {
index: null,
isCoustom: true
}
},
methods: {
bindPickerChange(e) {
this.index = e.target.value;
this.isCoustom = false;
this.$emit('input', this.list[this.index][this.code])
},
getIndex() {
for (let i = 0; i < this.list.length; i++) {
if ((this.list[i][this.code]).toString() === (this.value).toString()) {
return i;
}
}
}
},
watch: {
list(val) {
this.index = this.getIndex();
},
value: {
immediate: true,
handler(val) {
if(val !== null && val !== '') {
this.index = this.getIndex();
}else {
this.index = null;
}
}
},
}
}
</script>
<style lang="scss" scoped>
</style>