1
This commit is contained in:
@@ -0,0 +1,409 @@
|
||||
<script lang="ts">
|
||||
import { PropType } from "vue"
|
||||
import { getUid } from "../../core/util/xCoreUtil.uts"
|
||||
import { checkIsCssUnit, rpx2px,getUnit } from "../../core/util/xCoreUtil.uts"
|
||||
import { xConfig } from "../../config/xConfig.uts"
|
||||
// import pickerItem from './picker-item.uvue'
|
||||
import { X_PICKER_X_ITEM } from "../../interface.uts"
|
||||
|
||||
/**
|
||||
* @name 选择容器子节点 xPickerViewItem
|
||||
* @description xPickerView内部子组件,不可引用
|
||||
* @page /pages/index/picker-view
|
||||
* @category 表单组件
|
||||
* @constant 平台兼容
|
||||
* | Harmony | H5 | andriod | IOS | 小程序 | UTS | UNIAPP-X SDK | version |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| ☑ | ☑ | ☑️ | ☑️ | ☑️ | ☑️ | 4.76+ | 1.1.18 |
|
||||
*/
|
||||
export default {
|
||||
// components: {
|
||||
// 'picker-item': pickerItem
|
||||
// },
|
||||
data() {
|
||||
return {
|
||||
boxHeight: 0,
|
||||
id: ('xPickerItem-' + getUid()) as string,
|
||||
nowCurrentIndex: [0],
|
||||
tid: 0,
|
||||
tid2:0,
|
||||
tid3:3,
|
||||
}
|
||||
},
|
||||
emits: ['changeDeep', 'countChange'],
|
||||
props: {
|
||||
cellHeight: {
|
||||
type: String,
|
||||
default: '60'
|
||||
},
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 350
|
||||
},
|
||||
list: {
|
||||
type: Array as PropType<X_PICKER_X_ITEM[]>,
|
||||
default: () : X_PICKER_X_ITEM[] => [] as X_PICKER_X_ITEM[]
|
||||
},
|
||||
wrapWight: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
parentIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
selectedIndex: {
|
||||
type: Array as PropType<number[]>,
|
||||
default: () : number[] => [] as number[]
|
||||
},
|
||||
cellUnits: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () : string[] => [] as string[]
|
||||
},
|
||||
unitsFontSize:{
|
||||
type:String,
|
||||
default:'12'
|
||||
},
|
||||
fontSize: {
|
||||
type: String,
|
||||
default: "15"
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let t = this;
|
||||
this.pushDeepCount(this.parentIndex)
|
||||
t.setNowCurrentIndex(false)
|
||||
|
||||
},
|
||||
beforeUnmount() {
|
||||
clearTimeout(this.tid)
|
||||
clearTimeout(this.tid2)
|
||||
clearTimeout(this.tid3)
|
||||
},
|
||||
computed: {
|
||||
|
||||
_fontSize() : string {
|
||||
let fontSize = checkIsCssUnit(this.fontSize, xConfig.unit)
|
||||
|
||||
if(xConfig.fontScale==1) return fontSize;
|
||||
let sizeNumber = parseInt(fontSize)
|
||||
if(isNaN(sizeNumber)){
|
||||
sizeNumber = 16
|
||||
}
|
||||
return (sizeNumber*xConfig.fontScale).toString() + getUnit(this.fontSize)
|
||||
},
|
||||
_parentIndex() : number {
|
||||
return this.parentIndex
|
||||
},
|
||||
|
||||
_cellHeight() : string {
|
||||
return checkIsCssUnit(this.cellHeight, xConfig.unit)
|
||||
},
|
||||
_boxHeight() : number {
|
||||
let p = parseInt(this.cellHeight);
|
||||
if (this.cellHeight.lastIndexOf('rpx') > -1) {
|
||||
p = rpx2px(p);
|
||||
}
|
||||
return p
|
||||
},
|
||||
|
||||
_totalHeight() : number {
|
||||
return (Math.max(1, this._list.length) + 4) * this._boxHeight
|
||||
},
|
||||
|
||||
_wrapWight() : number {
|
||||
return this.wrapWight
|
||||
},
|
||||
_selectedIndex() : number[] {
|
||||
|
||||
return this.selectedIndex
|
||||
},
|
||||
|
||||
|
||||
_unitsName() : string {
|
||||
if (this.cellUnits.length == 0) return ""
|
||||
if (this.cellUnits.length < this._parentIndex) return ""
|
||||
return this.cellUnits[this._parentIndex]! as string
|
||||
},
|
||||
_cellUnits() : string[] {
|
||||
return this.cellUnits as string[]
|
||||
},
|
||||
_list(): X_PICKER_X_ITEM[] {
|
||||
return this.list
|
||||
},
|
||||
_nowChildren(): X_PICKER_X_ITEM[] {
|
||||
if(this._list.length==0) return [] as X_PICKER_X_ITEM[]
|
||||
let index = Math.max(0,Math.min(this.nowCurrentIndex[0],this._list.length-1))
|
||||
let item = this._list[index];
|
||||
|
||||
return item.children
|
||||
},
|
||||
_isDark():boolean{
|
||||
return xConfig.dark=='dark'
|
||||
},
|
||||
_maskStyle():string{
|
||||
if(this._isDark){
|
||||
|
||||
return 'background-image:linear-gradient(180deg,rgba(0, 0, 0, 0),rgba(0, 0, 0, 0)),linear-gradient(0deg, rgba(0, 0, 0, 0),rgba(0, 0, 0, 0))'
|
||||
}
|
||||
return 'background-image:linear-gradient(180deg,rgba(255,255,255,0),rgba(255,255,255,0)),linear-gradient(0deg, rgba(255,255,255,0),rgba(255,255,255,0))'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
list(){
|
||||
let t = this;
|
||||
t.setNowCurrentIndex(true)
|
||||
},
|
||||
selectedIndex(newvaluse : number[]) {
|
||||
let t = this;
|
||||
t.setNowCurrentIndex(false)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setNowCurrentIndex(isTmChange:boolean){
|
||||
let t = this;
|
||||
clearTimeout(this.tid3)
|
||||
// #ifdef MP-WEIXIN
|
||||
this.tid3 = setTimeout(function() {
|
||||
t.nowCurrentIndex = [t.getIndexByid()] as number[]
|
||||
if(isTmChange){
|
||||
t.mchange(t.nowCurrentIndex)
|
||||
}
|
||||
}, 15);
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
t.nowCurrentIndex = [t.getIndexByid()] as number[]
|
||||
if(isTmChange){
|
||||
t.mchange(t.nowCurrentIndex)
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
getIndexByid():number{
|
||||
let index = 0
|
||||
|
||||
if(this._selectedIndex.length==0) return index;
|
||||
if(this.parentIndex>this._selectedIndex.length) return index
|
||||
|
||||
index = this._selectedIndex[this.parentIndex]
|
||||
|
||||
index = Math.max(0,Math.min(index,this._list.length-1))
|
||||
return index;
|
||||
},
|
||||
getIdByindex():string|null{
|
||||
let id = null;
|
||||
if(this._list.length==0) return id
|
||||
if(this.nowCurrentIndex.length==0) return id;
|
||||
let index = Math.max(0,Math.min(this.nowCurrentIndex[0],this._list.length-1))
|
||||
return this._list[index].id
|
||||
|
||||
},
|
||||
mchange(indexs : number[]) {
|
||||
|
||||
let index = indexs[0];
|
||||
let parentIndex = this.parentIndex;
|
||||
let ids = this._selectedIndex.slice(0)
|
||||
|
||||
|
||||
|
||||
if(parentIndex<=ids.length-1){
|
||||
ids.splice(parentIndex,1,index)
|
||||
}else{
|
||||
for(let i=0;i<this.parentIndex;i++){
|
||||
ids.push(0)
|
||||
}
|
||||
ids.push(index)
|
||||
|
||||
}
|
||||
|
||||
this.$emit("changeDeep", ids)
|
||||
},
|
||||
change(s : number[]) {
|
||||
this.$emit("changeDeep", s)
|
||||
},
|
||||
|
||||
pushDeepCount(n:number){
|
||||
|
||||
this.$emit("countChange", n)
|
||||
},
|
||||
onChange(event : UniPickerViewChangeEvent) {
|
||||
if (event.detail.value.length == 0 || this._list.length==0) return;
|
||||
let indexs = event.detail.value!;
|
||||
if (indexs.join('') == this.nowCurrentIndex.join('')) return;
|
||||
let index = indexs[0]
|
||||
index = Math.max(0,Math.min(index,this._list.length-1))
|
||||
let item = this._list[index]
|
||||
if (item.disabled) {
|
||||
// 寻找最近的未禁用项
|
||||
let left = index - 1
|
||||
let right = index + 1
|
||||
let found = -1
|
||||
while (left >= 0 || right < this._list.length) {
|
||||
if (left >= 0 && !this._list[left].disabled) { found = left; break }
|
||||
if (right < this._list.length && !this._list[right].disabled) { found = right; break }
|
||||
left -= 1
|
||||
right += 1
|
||||
}
|
||||
if (found >= 0) {
|
||||
index = found
|
||||
indexs = [index]
|
||||
} else {
|
||||
// 全部禁用,回退到0
|
||||
index = 0
|
||||
indexs = [0]
|
||||
}
|
||||
}
|
||||
this.nowCurrentIndex = indexs;
|
||||
|
||||
this.mchange(indexs)
|
||||
}
|
||||
|
||||
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<view>
|
||||
<view class="xPickerViewUnit" v-if="_unitsName!=''">
|
||||
<x-text :font-size="unitsFontSize" class="xPickerViewUnitText">{{_unitsName}}</x-text>
|
||||
</view>
|
||||
<view class="xPickerView">
|
||||
<view style="padding: 0 2.5px;">
|
||||
<picker-view :value="nowCurrentIndex" @change="onChange"
|
||||
:style="{height:'250px',width:(_wrapWight-5)+'px'}"
|
||||
:mask-style="`${_maskStyle}`"
|
||||
:mask-bottom-style="_maskStyle"
|
||||
:mask-top-style="_maskStyle"
|
||||
:indicator-class="_isDark?'indicatorClassDark':'indicatorClassLight'"
|
||||
:indicator-style="`height:50px;backgroundColor:${_isDark?'rgba(255,255,255,0.05)':'rgba(0,0,0,0.05)'};border-radius:10px`">
|
||||
<picker-view-column>
|
||||
<view :style="{height:'50px'}" v-for="(item,index) in _list" :key="index"
|
||||
class="xPickerViewWrapCoumn">
|
||||
<text class="xPickerViewWrapCoumnText" :style="{
|
||||
fontSize:_fontSize,
|
||||
lineHeight: 1.1,
|
||||
fontWeight:nowCurrentIndex[0]==index?'bold':'inherit',
|
||||
opacity:item.disabled?0.4:(nowCurrentIndex[0]==index?1:0.6),
|
||||
color: _isDark?'rgba(255,255,255,0.8)':'#000000'}">
|
||||
{{item.title}}
|
||||
</text>
|
||||
</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
|
||||
</view>
|
||||
|
||||
<x-picker-item @countChange="pushDeepCount" :font-size="fontSize" :cellUnits="_cellUnits" @changeDeep="change" :selectedIndex="_selectedIndex"
|
||||
:wrapWight="_wrapWight" :parentIndex="_parentIndex+1" v-if="_nowChildren.length>0" :list="_nowChildren"
|
||||
:cell-height="_cellHeight">
|
||||
</x-picker-item>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
</template>
|
||||
<style>
|
||||
/* #ifdef WEB */
|
||||
.uni-picker-view-indicator:after,
|
||||
.uni-picker-view-indicator:before {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
/* #ifdef MP-WEIXIN */
|
||||
.indicatorClassDark:after,
|
||||
.indicatorClassDark:before,
|
||||
.indicatorClassLight:after,
|
||||
.indicatorClassLight:before {
|
||||
content:'';
|
||||
height: 0px;
|
||||
width: 100%;
|
||||
border-color: transparent;
|
||||
}
|
||||
.indicatorClassDark{
|
||||
background-color: rgba(255,255,255,0.05);
|
||||
}
|
||||
.indicatorClassLight{
|
||||
background-color: rgba(0,0,0,0.05);
|
||||
}
|
||||
/* #endif */
|
||||
.xPickerViewUnit {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.xPickerViewUnitText {
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.xPickerViewWrapCoumnText {
|
||||
margin:0 6px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
/* lines: 2; */
|
||||
/* #ifdef WEB */
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.xPickerView {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.xPickerViewWrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.xPickerContent {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.xPickerMasker {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.xPickErBar {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 10px;
|
||||
margin: 0 3px;
|
||||
flex: 1;
|
||||
|
||||
}
|
||||
|
||||
.xPickerContent {
|
||||
transition-duration: 350ms;
|
||||
transition-property: left, right, top, bottom;
|
||||
transition-timing-function: cubic-bezier(0, 0.55, 0.45, 1);
|
||||
}
|
||||
|
||||
.xPickerViewWrapCoumn {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
/* background-color: #f5f5f5; */
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user