You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

539 lines
14 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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>