539 lines
14 KiB
Vue
539 lines
14 KiB
Vue
<template>
|
||
<view class="tm-pickersView flex-start px-24" :class="[black_tmeme?'grey-darken-5':bgColor]">
|
||
<!-- @change="bindChange" -->
|
||
|
||
<picker-view @change="change" @pickstart='$emit("aniStart")' @pickend='$emit("aniEnd")' v-if="listData.length>0" :value="value_default"
|
||
:mask-style='black_tmeme?"opacity:0;":""'
|
||
indicator-style='height:50px;'
|
||
indicator-class="tm-pickersBView-item-h"
|
||
class="tm-pickersBView-wk">
|
||
<picker-view-column v-for="(item,index) in listData" :key="index">
|
||
<view class="tm-pickersBView-item fulled-height flex-center " style="margin: 0 5px;" :class="[value_default[index]==index_pub?'text-size-n text-weight-b active':'',black_tmeme?'bk':'']" v-for="(item_data,index_pub) in listData[index]" :key="index_pub">
|
||
<text v-if="dataType == 'string'" >{{item_data}}</text>
|
||
<text v-if="dataType == 'object'">{{item_data[rangKey]}}</text>
|
||
</view>
|
||
</picker-view-column>
|
||
|
||
</picker-view>
|
||
|
||
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
/**
|
||
* 普通级联拉选择器(嵌入式)
|
||
* @description 多级关联,单级关联选择
|
||
* @property {Array} default-value = [] 默认:[],默认赋值项。可选三种赋值方式,名称赋值,对象赋值,数字序列赋值
|
||
* @property {String|Number} item-height = [34|42|50|58|62] 项目的高度单位px
|
||
* @property {Array} list = [] 选择器的数据,可选格式:Array<string>,Array<object>.如果为object格式需要提供rangKey.如果为多级需要提供children.key值
|
||
* @property {String} rang-key = [text|title] 默认:text,如果List格式为对象数组,需要提供此值
|
||
* @property {String} children-key = [children] 默认:children,如果List格式为对象数组且为多级联选择,需要提供此值,理论上无限级联数据
|
||
* @property {String|Boolean} black = [true|false] 是否开启暗黑模式。
|
||
* @property {String|Boolean} disabled = [true|false] 是否禁用
|
||
* @property {String} bg-color = [white|blue] 默认:white,白色背景;请填写背景的主题色名称。
|
||
* @property {Function} change 列数被选中改变时触发。
|
||
*
|
||
*/
|
||
|
||
export default {
|
||
name: "tm-pickersView",
|
||
props: {
|
||
// 默认选中的项
|
||
// 格式有三种分别是[string,string...]
|
||
// [数字序列,数字序列....]
|
||
// 和list同等对象结构[{},{},...],此格式需要提供rangKey字段否则报错。
|
||
defaultValue:{
|
||
type:Array,
|
||
default:()=>{return []}
|
||
},
|
||
// 行高。
|
||
itemHeight: {
|
||
type: String | Number,
|
||
default: 40
|
||
},
|
||
list: {
|
||
type: Array,
|
||
default: () => {
|
||
return []
|
||
}
|
||
},
|
||
// 如果数据是对象,则需要提供key值。
|
||
rangKey: {
|
||
type: String,
|
||
default: "text"
|
||
},
|
||
rangKeyId: {
|
||
type: String,
|
||
default: "id"
|
||
},
|
||
// 如果是联级,则需要提供子集key值。
|
||
childrenKey: {
|
||
type: String,
|
||
default: "children"
|
||
},
|
||
black:{
|
||
type:String|Boolean,
|
||
default:null
|
||
},
|
||
// 是否禁用
|
||
disabled:{
|
||
type:String|Boolean,
|
||
default:false
|
||
},
|
||
// 背景颜色,主题色名称。
|
||
bgColor:{
|
||
type:String,
|
||
default:'white'
|
||
}
|
||
|
||
},
|
||
data() {
|
||
return {
|
||
value_default:[],
|
||
pre_value:[],
|
||
scrollEvent: 0,
|
||
childrenIndex: 0,
|
||
listIndex: [],
|
||
listData: [],
|
||
|
||
idx:9123
|
||
};
|
||
},
|
||
mounted() {
|
||
this.$nextTick(function(){
|
||
this.chulisdata()
|
||
this.setDefaultValue();
|
||
|
||
})
|
||
},
|
||
watch:{
|
||
defaultValue:{
|
||
deep:true,
|
||
handler: function(newV,oldV){
|
||
this.chulisdata()
|
||
this.$nextTick(function(){
|
||
this.inits();
|
||
})
|
||
}
|
||
},
|
||
list:{
|
||
deep:true,
|
||
handler:async function(newV,oldV){
|
||
this.chulisdata()
|
||
this.$nextTick(async function(){
|
||
await this.inits();
|
||
})
|
||
}
|
||
},
|
||
},
|
||
computed: {
|
||
black_tmeme: function() {
|
||
if (this.black !== null) return this.black;
|
||
return this.$tm.vx.state().tmVuetify.black;
|
||
},
|
||
dataType: function() {
|
||
// 数据有误
|
||
if (typeof this.list !== 'object' && !Array.isArray(this.list) && !this.list.length) return null;
|
||
if (typeof this.list[0] === 'string') return 'string';
|
||
if (typeof this.list[0] === 'object') return 'object';
|
||
},
|
||
|
||
gridNum: function() {
|
||
let t = this;
|
||
if (
|
||
(typeof this.list !== 'object' && !Array.isArray(this.list) && this.list.length==0)||
|
||
typeof this.list[0] === 'undefined'
|
||
) {
|
||
this.listIndex = [{
|
||
itemIndex: 0,
|
||
childrenIndex: 0,
|
||
wz: 0
|
||
}]
|
||
return 0
|
||
};
|
||
if (typeof this.list[0] === 'string') {
|
||
this.listIndex = [{
|
||
itemIndex: 0,
|
||
childrenIndex: 0,
|
||
wz: 0
|
||
}]
|
||
return 1
|
||
}
|
||
if (typeof this.list[0] === 'object') {
|
||
let index = 0;
|
||
let cindex = 1;
|
||
let pds = []
|
||
function tests(obj) {
|
||
if(!obj||obj?.length==0){
|
||
return;
|
||
}
|
||
cindex = cindex+1;
|
||
index +=1;
|
||
pds.push({
|
||
itemIndex: 0,
|
||
childrenIndex: index,
|
||
wz: 0
|
||
})
|
||
if (obj && typeof obj === 'object' && Array.isArray(obj)) {
|
||
if (obj[0][t.childrenKey]) {
|
||
tests(obj[0][t.childrenKey]);
|
||
}
|
||
}
|
||
}
|
||
pds.push({
|
||
itemIndex: 0,
|
||
childrenIndex: index,
|
||
wz: 0
|
||
})
|
||
tests(this.list[0][this.childrenKey])
|
||
t.listIndex = pds;
|
||
return cindex;
|
||
}
|
||
},
|
||
|
||
},
|
||
methods: {
|
||
SeletecdeIndexdefault(){
|
||
let d = []
|
||
|
||
for(let i=0;i<this.gridNum;i++){
|
||
d.push(this.listIndex[i].itemIndex)
|
||
}
|
||
this.value_default = d;
|
||
},
|
||
// 获取当前选中的数据。
|
||
getSelectedValue(){
|
||
let t = this;
|
||
// 总的级联数。
|
||
let dNum = this.gridNum;
|
||
let pd = this.listIndex;
|
||
|
||
if(this.dataType === 'string'){
|
||
return [{
|
||
index:this.listIndex[0].itemIndex,
|
||
data:this.listData[0][this.listIndex[0].itemIndex]
|
||
}]
|
||
}else if(this.dataType === 'object'){
|
||
|
||
if(dNum===1){
|
||
|
||
let ps = {...this.listData[0][this.listIndex[0].itemIndex]};
|
||
delete ps.children;
|
||
return [{
|
||
index:this.listIndex[0].itemIndex,
|
||
data:ps
|
||
}]
|
||
|
||
}else if(dNum>1){
|
||
let p = [];
|
||
this.listIndex.forEach((item,index)=>{
|
||
if(t.listData[index]){
|
||
let ps = {...t.listData[index][item.itemIndex]};
|
||
delete ps.children;
|
||
p.push({
|
||
index:item.itemIndex,
|
||
data:ps
|
||
})
|
||
}
|
||
|
||
})
|
||
|
||
return p;
|
||
}
|
||
}
|
||
return [];
|
||
},
|
||
chulisdata() {
|
||
// 总的级联数。
|
||
let dNum = this.gridNum;
|
||
|
||
let t = this;
|
||
if (dNum === 0) {
|
||
this.listData = [];
|
||
this.$forceUpdate()
|
||
return this.listData;
|
||
}
|
||
if (dNum === 1) {
|
||
this.listData = [this.list];
|
||
// this.listData.push([...this.list]);
|
||
this.$forceUpdate()
|
||
|
||
return this.listData;
|
||
}
|
||
|
||
if (dNum > 1) {
|
||
|
||
let index = 1;
|
||
let list = [];
|
||
let p = [];
|
||
function tests(obj) {
|
||
if(index > dNum) return;
|
||
list.push([...obj])
|
||
if(obj[t.listIndex[index]?.itemIndex]){
|
||
let cl = obj[t.listIndex[index].itemIndex][t.childrenKey];
|
||
if (cl && typeof cl === 'object' && Array.isArray(cl)) {
|
||
index++;
|
||
|
||
tests(cl);
|
||
}
|
||
}
|
||
|
||
}
|
||
p.push([...this.list])
|
||
|
||
if(this.list[t.listIndex[0].itemIndex][this.childrenKey]){
|
||
tests(this.list[t.listIndex[0].itemIndex][this.childrenKey])
|
||
}
|
||
p.push(...list);
|
||
this.$forceUpdate()
|
||
this.listData = p;
|
||
}
|
||
|
||
return this.listData;
|
||
},
|
||
setDefaultValue(objSelected){
|
||
let t = this;
|
||
uni.$tm.sleep(50).then(()=>t.inits(objSelected))
|
||
.then(()=>uni.$tm.sleep(50))
|
||
.then(()=>t.SeletecdeIndexdefault())
|
||
|
||
},
|
||
async inits(objSelected){
|
||
// 总的级联数。
|
||
let dNum = this.gridNum;
|
||
let t = this;
|
||
var sjd = null;
|
||
if(typeof objSelected ==='object' && Array.isArray(objSelected)){
|
||
sjd = objSelected;
|
||
}else{
|
||
if(!this.defaultValue||this.defaultValue.length==0) return;
|
||
sjd = this.defaultValue;
|
||
}
|
||
let typeindex = typeof sjd[0];
|
||
|
||
if(dNum===0) return;
|
||
|
||
if(typeindex === 'number'){
|
||
if (dNum === 1) {
|
||
let itemIndex = sjd[0];
|
||
if(typeof itemIndex === 'number' && !isNaN(itemIndex) ){
|
||
this.$set(this.listIndex[0], 'itemIndex', itemIndex);
|
||
|
||
}
|
||
|
||
return
|
||
}else if(dNum > 1){
|
||
|
||
let index = 1;
|
||
async function tests() {
|
||
if(index > dNum) return;
|
||
|
||
let itemIndex = t.defaultValue[index];
|
||
|
||
if(typeof itemIndex === 'number' && !isNaN(itemIndex) &&typeof t.listIndex[index] === 'object' && typeof t.listIndex[index] !=='undefined'){
|
||
await uni.$tm.sleep(30)
|
||
t.$set(t.listIndex[index], 'itemIndex', itemIndex);
|
||
|
||
t.chulisdata();
|
||
index++;
|
||
await tests();
|
||
}
|
||
}
|
||
|
||
let itemIndex = sjd[0];
|
||
|
||
this.$set(this.listIndex[0], 'itemIndex', itemIndex);
|
||
|
||
|
||
this.chulisdata();
|
||
|
||
await tests()
|
||
|
||
}
|
||
|
||
}else if(typeindex === 'string'){
|
||
|
||
if(this.dataType==='string'){
|
||
if (dNum === 1) {
|
||
let valueStr = sjd[0];
|
||
if(typeof valueStr !=='string' || typeof valueStr ==='undefined' || valueStr ==null){
|
||
return;
|
||
}
|
||
let itemIndex = this.listData[0].indexOf(valueStr)
|
||
if(itemIndex>-1){
|
||
this.$set(this.listIndex[0], 'itemIndex', itemIndex);
|
||
|
||
}
|
||
|
||
return
|
||
}
|
||
}else if(this.dataType === 'object'){
|
||
if (dNum === 1) {
|
||
let valueStr = sjd[0];
|
||
if(typeof valueStr !=='string' || typeof valueStr ==='undefined' || valueStr ==null){
|
||
return;
|
||
}
|
||
let itemIndex = this.listData[0].findIndex(item=>{
|
||
return item[t.rangKey] == valueStr;
|
||
})
|
||
if(itemIndex>-1){
|
||
this.$set(this.listIndex[0], 'itemIndex', itemIndex);
|
||
|
||
}
|
||
return
|
||
}else if(dNum>1){
|
||
let index = 0;
|
||
async function tests() {
|
||
if(index > dNum) return;
|
||
|
||
if(typeof t.listIndex[index] === 'object' && typeof t.listIndex[index] !=='undefined'){
|
||
let valueStr = t.defaultValue[index];
|
||
if(typeof valueStr !=='string' || typeof valueStr ==='undefined' || valueStr ==null){
|
||
return;
|
||
}
|
||
let itemIndex = t.listData[index].findIndex(item=>{
|
||
return item[t.rangKey] == valueStr;
|
||
})
|
||
if(itemIndex>-1){
|
||
await uni.$tm.sleep(30)
|
||
t.$set(t.listIndex[index], 'itemIndex', itemIndex);
|
||
|
||
t.chulisdata();
|
||
|
||
}
|
||
|
||
index++;
|
||
await tests();
|
||
|
||
}
|
||
}
|
||
|
||
await tests()
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
}
|
||
}else if(typeindex === 'object'){
|
||
|
||
if (dNum === 1) {
|
||
let valueStr = sjd[0];
|
||
if(typeof valueStr[t.rangKey] ==='undefined' || typeof valueStr !=='object' || typeof valueStr ==='undefined' || valueStr ==null){
|
||
return;
|
||
}
|
||
|
||
let itemIndex = this.listData[0].findIndex(item=>{
|
||
return (item[t.rangKey] == valueStr[t.rangKey])||(parseInt(item[t.rangKeyId]) == parseInt(valueStr[t.rangKeyId]));;
|
||
})
|
||
if(itemIndex>-1){
|
||
this.$set(this.listIndex[0], 'itemIndex', itemIndex);
|
||
|
||
}
|
||
|
||
return
|
||
}else if(dNum>1){
|
||
let index = 0;
|
||
async function tests() {
|
||
if(index > dNum) return;
|
||
|
||
if(typeof t.listIndex[index] === 'object' && typeof t.listIndex[index] !=='undefined'){
|
||
let valueStr = t.defaultValue[index];
|
||
if(typeof valueStr[t.rangKey] ==='undefined' || typeof valueStr !=='object' || typeof valueStr ==='undefined' || valueStr ==null){
|
||
return;
|
||
}
|
||
let itemIndex = t.listData[index].findIndex(item=>{
|
||
return (item[t.rangKey] == valueStr[t.rangKey])||(parseInt(item[t.rangKeyId]) == parseInt(valueStr[t.rangKeyId]));
|
||
})
|
||
if(itemIndex>-1){
|
||
await uni.$tm.sleep(30)
|
||
t.$set(t.listIndex[index], 'itemIndex', itemIndex);
|
||
t.$set(t.listIndex[index], 'wz', itemIndex * t.itemHeight);
|
||
t.chulisdata();
|
||
}
|
||
|
||
index++;
|
||
await tests();
|
||
|
||
}
|
||
}
|
||
await tests()
|
||
|
||
}
|
||
}
|
||
},
|
||
change(e) {
|
||
let pl = [...e.detail.value];
|
||
|
||
this.pre_value =[...this.value_default];
|
||
|
||
if(this.disabled){
|
||
this.value_default = this.pre_value;
|
||
|
||
return;
|
||
}
|
||
let childrenIndex = 0;
|
||
for(let i=0;i<pl.length;i++){
|
||
if(this.listIndex[i].itemIndex !== pl[i]){
|
||
childrenIndex = this.listIndex[i].childrenIndex;
|
||
break;
|
||
}
|
||
}
|
||
|
||
this.childrenIndex = childrenIndex;
|
||
|
||
for(let i=childrenIndex;i<pl.length;i++){
|
||
if(this.listIndex[i]?.itemIndex !== pl[i]){
|
||
this.$set(this.listIndex[i],'itemIndex',pl[i])
|
||
}else{
|
||
this.$set(this.listIndex[i],'itemIndex',0)
|
||
pl[i] = 0;
|
||
}
|
||
}
|
||
|
||
this.chulisdata()
|
||
this.$nextTick(function(){
|
||
this.value_default = pl;
|
||
this.$emit("change",pl)
|
||
})
|
||
|
||
},
|
||
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style >
|
||
.tm-pickersView .tm-pickersBView-item-h{
|
||
height: 50px;
|
||
background-color: rgba(0,0,0,0.03);
|
||
width: calc(100% - 10px);
|
||
margin-left: 5px;
|
||
border-radius: 20rpx;
|
||
border: none;
|
||
}
|
||
.tm-pickersView .tm-pickersBView-item-h::after,.tm-pickersView .tm-pickersBView-item-h::before{
|
||
border: none;
|
||
}
|
||
.tm-pickersView .tm-pickersBView-wk{
|
||
position: relative;
|
||
width: 750rpx;
|
||
height: 500rpx;
|
||
|
||
}
|
||
.tm-pickersView .tm-pickersBView-wk .tm-pickersBView-item.bk{
|
||
opacity: 0.4;
|
||
}
|
||
.tm-pickersView .tm-pickersBView-wk .tm-pickersBView-item.active{
|
||
opacity: 1;
|
||
border-radius: 20rpx;
|
||
border: none;
|
||
background-color: rgba(0,0,0,0.06);
|
||
}
|
||
.tm-pickersView .tm-pickersBView-wk .tm-pickersBView-item.active.bk{
|
||
background-color: rgba(255,255,255,0.06);
|
||
}
|
||
</style>
|