Initial commit of akmon project
This commit is contained in:
121
uni_modules/lime-picker/components/l-picker/index.scss
Normal file
121
uni_modules/lime-picker/components/l-picker/index.scss
Normal file
@@ -0,0 +1,121 @@
|
||||
@import '~@/uni_modules/lime-style/index.scss';
|
||||
$prefix: l !default;
|
||||
$picker: #{$prefix}-picker;
|
||||
|
||||
$picker-border-radius: create-var(picker-border-radius, 24rpx);
|
||||
$picker-bg-color: create-var(picker-bg-color, $bg-color-container);
|
||||
$picker-toolbar-height: create-var(picker-toolbar-height, 116rpx);
|
||||
|
||||
$picker-cancel-color: create-var(picker-cancel-color, $text-color-2);
|
||||
$picker-confirm-color: create-var(picker-confirm-color, $primary-color);
|
||||
$picker-button-font-size: create-var(picker-button-font-size, 16px);
|
||||
|
||||
$picker-title-font-size: create-var(picker-title-font-size, 18px);
|
||||
$picker-title-font-weight: create-var(picker-title-font-weight, 700);
|
||||
$picker-title-line-height: create-var(picker-title-line-height, 52rpx);
|
||||
$picker-title-color: create-var(picker-title-color, $text-color-1);
|
||||
|
||||
|
||||
$picker-group-height: create-var(picker-group-height, 400rpx);
|
||||
$picker-indicator-bg-color: create-var(picker-indicator-bg-color, $fill-4);
|
||||
$picker-indicator-border-radius: create-var(picker-indicator-border-radius, 12rpx);
|
||||
|
||||
$picker-item-height: create-var(picker-item-height, 50px);
|
||||
$picker-item-active-color: create-var(picker-item-active-color, $text-color-1);
|
||||
|
||||
|
||||
$picker-loading-mask-color: create-var(picker-loading-mask-color, rgba(255,255,255,.9));
|
||||
$picker-loading-color: create-var(picker-loading-color, $primary-color);
|
||||
|
||||
.#{$picker} {
|
||||
position: relative;
|
||||
background-color: $picker-bg-color;
|
||||
border-top-left-radius: $picker-border-radius;
|
||||
border-top-right-radius: $picker-border-radius;
|
||||
|
||||
&__toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
height: $picker-toolbar-height;
|
||||
flex-direction: row;
|
||||
position: relative;
|
||||
}
|
||||
&__title {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
// flex: 1;
|
||||
// width: 100%;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: $picker-title-color;
|
||||
// line-height: $picker-toolbar-height;
|
||||
line-height: $picker-title-line-height;
|
||||
font-weight: $picker-title-font-weight;
|
||||
font-size: $picker-title-font-size;
|
||||
}
|
||||
|
||||
&__cancel,
|
||||
&__confirm {
|
||||
/* #ifndef APP-ANDROID || APP-IOS || APP-HARMONY */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
user-select: none;
|
||||
/* #endif */
|
||||
font-size: $picker-button-font-size;
|
||||
line-height: $picker-toolbar-height;
|
||||
height: 100%;
|
||||
padding: 0 $spacer;
|
||||
}
|
||||
|
||||
&__cancel {
|
||||
color: $picker-cancel-color;
|
||||
}
|
||||
|
||||
&__confirm {
|
||||
color: $picker-confirm-color;
|
||||
}
|
||||
|
||||
|
||||
&__main {
|
||||
display: flex;
|
||||
height: $picker-group-height;
|
||||
flex-direction: row;
|
||||
padding: 0 $spacer-xs;
|
||||
}
|
||||
&__mask {
|
||||
|
||||
}
|
||||
&__empty {
|
||||
pointer-events: none;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 3;
|
||||
}
|
||||
&__loading {
|
||||
z-index: 3;
|
||||
// color: $picker-loading-color;
|
||||
background: $picker-loading-mask-color;
|
||||
// background-color: red;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0
|
||||
}
|
||||
}
|
||||
292
uni_modules/lime-picker/components/l-picker/l-picker.uvue
Normal file
292
uni_modules/lime-picker/components/l-picker/l-picker.uvue
Normal file
@@ -0,0 +1,292 @@
|
||||
<template>
|
||||
<view class="l-picker" :style="[styles]" ref="pickerRef">
|
||||
<view class="l-picker__toolbar" :key="ohosShow" v-if="cancelBtn != null || title != null || confirmBtn != null">
|
||||
<text class="l-picker__cancel" :key="ohosShow" :style="cancelStyle??''" v-if="cancelBtn != null"
|
||||
@click="onCancel">{{cancelBtn}}</text>
|
||||
<text class="l-picker__title" :key="ohosShow" :style="titleStyle??''">{{title}}</text>
|
||||
<text class="l-picker__confirm" :key="ohosShow" :style="confirmStyle??''" v-if="confirmBtn != null"
|
||||
@click="onConfirm">{{confirmBtn}}</text>
|
||||
</view>
|
||||
<slot name="header"></slot>
|
||||
<view class="l-picker__main" :style="[groupHeight != null ? { height: groupHeight}: {}]">
|
||||
<slot>
|
||||
<l-picker-item v-for="(options, i) in props.columns" :options="options" :key="i" :column="i"
|
||||
:value="pickerValue.length > i ? pickerValue[i]: null"></l-picker-item>
|
||||
</slot>
|
||||
<view class="l-picker__empty" v-if="isEmpty">
|
||||
<slot name="empty"></slot>
|
||||
</view>
|
||||
</view>
|
||||
<slot name="footer" />
|
||||
<view class="l-picker__loading" ref="loadingRef" v-if="loading"
|
||||
:style="[loadingMaskColor != null ? {background: loadingMaskColor}: {}]">
|
||||
<!-- #ifndef APP -->
|
||||
<l-loading :size="loadingSize" :color="loadingColor"></l-loading>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="uts" setup>
|
||||
/**
|
||||
* Picker 选择器组件
|
||||
* @description 多列数据选择器,支持级联数据展示和自定义样式配置
|
||||
* <br>插件类型:LPickerComponentPublicInstance
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?name=lime-picker
|
||||
*
|
||||
* @property {string} cancelBtn 取消按钮文字
|
||||
* @property {string | UTSJSONObject} cancelStyle 取消按钮样式
|
||||
* @property {string} confirmBtn 确定按钮文字
|
||||
* @property {string | UTSJSONObject} confirmStyle 确定按钮样式
|
||||
* @property {string} title 标题文字
|
||||
* @property {string | UTSJSONObject} titleStyle 标题样式
|
||||
* @property {UTSJSONObject} keys 字段别名配置(例:{value: 'id', label: 'name'})
|
||||
* @property {PickerColumn[]} columns 选择器列数据(必填)
|
||||
* @property {PickerValue[]} modelValue 选中值(支持v-model)
|
||||
* @property {PickerValue[]} defaultValue 默认选中值
|
||||
* @property {PickerValue[]} value 选中值(兼容旧版)
|
||||
* @property {boolean} loading 是否显示加载状态
|
||||
* @property {string} loadingColor 加载图标颜色
|
||||
* @property {string} loadingMaskColor 加载遮罩颜色
|
||||
* @property {string} loadingSize 加载图标尺寸
|
||||
* @property {string} itemHeight 选项行高度
|
||||
* @property {string} itemColor 选项文字颜色
|
||||
* @property {string} itemFontSize 选项字体大小
|
||||
* @property {string} itemActiveColor 选中项颜色
|
||||
* @property {string} indicatorStyle 指示器样式
|
||||
* @property {string} bgColor 背景颜色
|
||||
* @property {string} groupHeight 选项组高度
|
||||
* @property {string} radius 圆角半径
|
||||
* @property {boolean} resetIndex 是否重置选中索引
|
||||
*
|
||||
* @event {Function} confirm 点击确定时触发(事件参数:PickerConfirmEvent)
|
||||
* @event {Function} cancel 点击取消时触发
|
||||
* @event {Function} change 值变化时触发(事件参数:PickerPickEvent)
|
||||
* @event {Function} column-change 列数据变化时触发(事件参数:PickerChangeInfo)
|
||||
*/
|
||||
import { PickerProps, PickerColumn, PickerValue, PickerColumnItem, PickerConfirmEvent, PickerPickEvent } from './type';
|
||||
import { pushAt } from './utils';
|
||||
import { unitConvert } from '@/uni_modules/lime-shared/unitConvert'
|
||||
// #ifdef APP
|
||||
import { useLoading } from '@/uni_modules/lime-loading'
|
||||
// #endif
|
||||
const emit = defineEmits(['change', 'cancel', 'pick', 'confirm', 'update:modelValue', 'update:value']);
|
||||
const props = withDefaults(defineProps<PickerProps>(), {
|
||||
columns: [] as PickerColumn[],
|
||||
loading: false,
|
||||
resetIndex: false,
|
||||
loadingSize: '64rpx'
|
||||
})
|
||||
const pickerItemInstanceArray = reactive<LPickerItemComponentPublicInstance[]>([]);
|
||||
const ohosShow = ref(0)
|
||||
const modelValue = ref<PickerValue[]>(props.value ?? props.modelValue ?? props.defaultValue ?? [])
|
||||
const pickerValue = computed({
|
||||
set(value : PickerValue[]) {
|
||||
if (value.join('') == modelValue.value.join('')) return
|
||||
modelValue.value = value;
|
||||
emit('update:modelValue', value)
|
||||
emit('change', value)
|
||||
},
|
||||
get() : PickerValue[] {
|
||||
return props.value ?? props.modelValue ?? modelValue.value
|
||||
}
|
||||
} as WritableComputedOptions<PickerValue[]>)
|
||||
|
||||
const isEmpty = computed(() : boolean => {
|
||||
return props.columns.length == 0 && pickerItemInstanceArray.every(child => child.options.length == 0)
|
||||
})
|
||||
const styles = computed(() : Map<string, any> => {
|
||||
const style = new Map<string, any>()
|
||||
if (props.bgColor != null) {
|
||||
style.set('background', props.bgColor!)
|
||||
}
|
||||
if (props.radius != null) {
|
||||
style.set('border-top-left-radius', props.radius!)
|
||||
style.set('border-top-right-radius', props.radius!)
|
||||
}
|
||||
return style
|
||||
})
|
||||
|
||||
const curIndexArray = ref<number[]>([]);
|
||||
const curValueArray = ref([...pickerValue.value]);
|
||||
const curItemArray : PickerColumnItem[] = []
|
||||
const realColumns = computed(() : PickerColumn[] => {
|
||||
const pickerColumns = pickerItemInstanceArray.map((child) : PickerColumn => child.options)
|
||||
if (pickerColumns.length > 0) {
|
||||
return pickerColumns
|
||||
}
|
||||
return props.columns
|
||||
})
|
||||
|
||||
const manageChildInList = (child : LPickerItemComponentPublicInstance, shouldAdd : boolean) => {
|
||||
const index = pickerItemInstanceArray.indexOf(child);
|
||||
if (shouldAdd) {
|
||||
if (index != -1) return
|
||||
pickerItemInstanceArray.push(child)
|
||||
} else {
|
||||
if (index == -1) return
|
||||
pickerItemInstanceArray.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
const updateItems = (item : PickerColumnItem, index : number, column : number) => {
|
||||
pushAt(curIndexArray.value, column, index)
|
||||
pushAt(curValueArray.value, column, item.value)
|
||||
pushAt(curItemArray, column, item)
|
||||
};
|
||||
|
||||
const updatePickerItems = () => {
|
||||
const _indexs : number[] = []
|
||||
const _values : any[] = []
|
||||
pickerItemInstanceArray.forEach((child, column) => {
|
||||
if (child.options.length == 0) return
|
||||
const value = curValueArray.value.length > column ? curValueArray.value[column] : null;
|
||||
// #ifndef APP
|
||||
const index = value == null ? 0 : child._.exposed.getIndexByValue(value);
|
||||
child._.exposed.setIndex(index)
|
||||
// #endif
|
||||
// #ifdef APP
|
||||
// const index = value == null ? 0 : child.getIndexByValue(value)
|
||||
// child.setIndex(index)
|
||||
const index : number = (value == null ? 0 : child.$callMethod('getIndexByValue', value)) as number
|
||||
child.$callMethod('setIndex', index)
|
||||
// #endif
|
||||
const item = child.options[index]
|
||||
_indexs.push(index)
|
||||
_values.push(item.value)
|
||||
|
||||
pushAt(curItemArray, column, item)
|
||||
// pushAt(curIndexArray.value, column, index)
|
||||
// pushAt(curValueArray.value, column, item.value)
|
||||
// // 不能改变单向数据流, 只有值不存在时候才处理
|
||||
// if(pickerValue.value.length == 0) {
|
||||
// pickerValue.value = [...curValueArray.value]
|
||||
// }
|
||||
// if(pickerValue.value.join('') == curValueArray.value.join('')) return
|
||||
// pickerValue.value = [...curValueArray.value]
|
||||
})
|
||||
if (curIndexArray.value.join('') == _indexs.join('')) return
|
||||
curIndexArray.value = _indexs
|
||||
curValueArray.value = _values
|
||||
// if(pickerValue.value.length == 0) {
|
||||
pickerValue.value = [...curValueArray.value]
|
||||
// }
|
||||
}
|
||||
|
||||
const onPick = (item : PickerColumnItem, index : number, column : number) => {
|
||||
if (curIndexArray.value[column] == index) return
|
||||
pushAt(curIndexArray.value, column, index)
|
||||
pushAt(curValueArray.value, column, item.value)
|
||||
pushAt(curItemArray, column, item)
|
||||
const obj : PickerPickEvent = {
|
||||
values: curValueArray.value,
|
||||
column,
|
||||
index
|
||||
}
|
||||
pickerValue.value = [...curValueArray.value]
|
||||
emit('pick', obj)
|
||||
};
|
||||
|
||||
const onCancel = (e : UniPointerEvent) => {
|
||||
updatePickerItems()
|
||||
emit('cancel', e)
|
||||
}
|
||||
const onConfirm = (e : UniPointerEvent) => {
|
||||
const values = [...curValueArray.value];
|
||||
const indexs = [...curIndexArray.value];
|
||||
const items = curItemArray.map((item) : PickerColumnItem => toRaw(item))
|
||||
if (pickerValue.value.join('') != values.join('')) {
|
||||
pickerValue.value = values;
|
||||
}
|
||||
const obj : PickerConfirmEvent = {
|
||||
values,
|
||||
indexs,
|
||||
items
|
||||
}
|
||||
emit('confirm', obj)
|
||||
}
|
||||
const stopPickerValue = watch(pickerValue, () => {
|
||||
if (pickerValue.value.join('') == curValueArray.value.join('')) return
|
||||
curValueArray.value = pickerValue.value.map((item : PickerValue) => item);
|
||||
updatePickerItems()
|
||||
})
|
||||
|
||||
const stopColumns = watch(realColumns, () => {
|
||||
updatePickerItems()
|
||||
// nextTick(() => {
|
||||
// setTimeout(()=>{
|
||||
// updatePickerItems()
|
||||
// },2000)
|
||||
|
||||
// })
|
||||
})
|
||||
|
||||
|
||||
// #ifdef APP-HARMONY
|
||||
// 在弹窗中 文本没有样式,给它重绘
|
||||
const pickerRef = ref<UniElement|null>(null)
|
||||
const updateOhosKey = () =>{
|
||||
requestAnimationFrame(()=>{
|
||||
ohosShow.value++
|
||||
setTimeout(()=>{
|
||||
ohosShow.value++
|
||||
},200)
|
||||
pickerRef.value?.getBoundingClientRectAsync((res)=>{
|
||||
ohosShow.value++
|
||||
})
|
||||
})
|
||||
}
|
||||
const resizeObserver = new UniResizeObserver((entries : Array<UniResizeObserverEntry>) => {
|
||||
nextTick(updateOhosKey)
|
||||
})
|
||||
|
||||
const stopWatch = watch(():UniElement|null => pickerRef.value, (el:UniElement|null) => {
|
||||
if(el== null) return
|
||||
nextTick(updateOhosKey)
|
||||
resizeObserver.observe(el)
|
||||
})
|
||||
|
||||
onUnmounted(()=>{
|
||||
stopWatch()
|
||||
resizeObserver.disconnect()
|
||||
})
|
||||
// #endif
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
|
||||
if (pickerValue.value.join('') != curValueArray.value.join('') && pickerValue.value.length > 0) {
|
||||
curValueArray.value = [...pickerValue.value]
|
||||
updatePickerItems()
|
||||
}
|
||||
})
|
||||
})
|
||||
// #ifdef APP
|
||||
const loadingRef = ref<UniElement | null>(null);
|
||||
// const {play, clear, failed} = useLoading(loadingRef, 'circular', props.loadingColor?? '#3283ff', unitConvert(props.loadingSize))
|
||||
const loadingAni = useLoading(loadingRef)
|
||||
loadingAni.type = 'circular'
|
||||
loadingAni.color = props.loadingColor ?? '#3283ff'
|
||||
loadingAni.ratio = unitConvert(props.loadingSize)
|
||||
watchEffect(() => {
|
||||
if (props.loading) {
|
||||
loadingAni.play()
|
||||
} else {
|
||||
loadingAni.clear()
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
stopPickerValue()
|
||||
stopColumns()
|
||||
})
|
||||
|
||||
provide('limePicker', props)
|
||||
provide('limePickerOnPick', onPick)
|
||||
provide('limePickerUpdateItems', updateItems)
|
||||
provide('limePickerItems', pickerItemInstanceArray)
|
||||
provide('limePickerManageChildInList', manageChildInList)
|
||||
</script>
|
||||
<style lang="scss">
|
||||
@import './index.scss';
|
||||
</style>
|
||||
261
uni_modules/lime-picker/components/l-picker/l-picker.vue
Normal file
261
uni_modules/lime-picker/components/l-picker/l-picker.vue
Normal file
@@ -0,0 +1,261 @@
|
||||
<template>
|
||||
<view class="l-picker" :style="[styles]">
|
||||
<view class="l-picker__toolbar" v-if="cancelBtn || title || confirmBtn">
|
||||
<text class="l-picker__cancel" :style="cancelStyle" v-if="cancelBtn" @click="onCancel">{{cancelBtn}}</text>
|
||||
<text class="l-picker__title" :style="titleStyle" v-if="title">{{title}}</text>
|
||||
<text class="l-picker__confirm" :style="confirmStyle" v-if="confirmBtn" @click="onConfirm">{{confirmBtn}}</text>
|
||||
</view>
|
||||
<slot name="header"></slot>
|
||||
<view class="l-picker__main" :style="[groupHeight ? { height: groupHeight}: {}]">
|
||||
<slot>
|
||||
<l-picker-item v-for="(options, i) in columns" :options="options" :key="i" :column="i" :value="pickerValue.length > i ? pickerValue[i]: null"></l-picker-item>
|
||||
</slot>
|
||||
<view class="l-picker__empty" v-if="isEmpty">
|
||||
<slot name="empty"></slot>
|
||||
</view>
|
||||
</view>
|
||||
<slot name="footer" />
|
||||
<view class="l-picker__loading" ref="loadingRef" v-if="loading" :style="[loadingMaskColor ? {background: loadingMaskColor}: {}]">
|
||||
<l-loading :size="loadingSize" :color="loadingColor"></l-loading>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
// @ts-nocheck
|
||||
/**
|
||||
* Picker 选择器组件
|
||||
* @description 多列数据选择器,支持级联数据展示和自定义样式配置
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?name=lime-picker
|
||||
*
|
||||
* @property {string} cancelBtn 取消按钮文字
|
||||
* @property {string | UTSJSONObject} cancelStyle 取消按钮样式
|
||||
* @property {string} confirmBtn 确定按钮文字
|
||||
* @property {string | UTSJSONObject} confirmStyle 确定按钮样式
|
||||
* @property {string} title 标题文字
|
||||
* @property {string | UTSJSONObject} titleStyle 标题样式
|
||||
* @property {UTSJSONObject} keys 字段别名配置(例:{value: 'id', label: 'name'})
|
||||
* @property {PickerColumn[]} columns 选择器列数据(必填)
|
||||
* @property {PickerValue[]} modelValue 选中值(支持v-model)
|
||||
* @property {PickerValue[]} defaultValue 默认选中值
|
||||
* @property {PickerValue[]} value 选中值(兼容旧版)
|
||||
* @property {boolean} loading 是否显示加载状态
|
||||
* @property {string} loadingColor 加载图标颜色
|
||||
* @property {string} loadingMaskColor 加载遮罩颜色
|
||||
* @property {string} loadingSize 加载图标尺寸
|
||||
* @property {string} itemHeight 选项行高度
|
||||
* @property {string} itemColor 选项文字颜色
|
||||
* @property {string} itemFontSize 选项字体大小
|
||||
* @property {string} itemActiveColor 选中项颜色
|
||||
* @property {string} indicatorStyle 指示器样式
|
||||
* @property {string} bgColor 背景颜色
|
||||
* @property {string} groupHeight 选项组高度
|
||||
* @property {string} radius 圆角半径
|
||||
* @property {boolean} resetIndex 是否重置选中索引
|
||||
*
|
||||
* @event {Function} confirm 点击确定时触发(事件参数:PickerConfirmEvent)
|
||||
* @event {Function} cancel 点击取消时触发
|
||||
* @event {Function} change 值变化时触发(事件参数:PickerPickEvent)
|
||||
* @event {Function} column-change 列数据变化时触发(事件参数:PickerChangeInfo)
|
||||
*/
|
||||
import type { PickerProps, PickerColumn, PickerValue, PickerColumnItem, PickerConfirmEvent, PickerPickEvent } from './type';
|
||||
import { defineComponent, computed, ref, watch, onMounted, nextTick, onBeforeUnmount, provide, reactive, toRaw } from '@/uni_modules/lime-shared/vue';
|
||||
import pickerProps from './props';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'l-picker',
|
||||
props: pickerProps,
|
||||
emits: ['change', 'cancel', 'pick','confirm' ,'update:modelValue', 'update:value'],
|
||||
setup(props, {emit}) {
|
||||
const pickerItemInstanceArray = ref<LPickerItemComponentPublicInstance[]>([]);
|
||||
|
||||
const modelValue = ref<PickerValue[]>(props.value || props.modelValue || props.defaultValue || [])
|
||||
const pickerValue = computed({
|
||||
set(value: PickerValue[]) {
|
||||
if(value.join('') == modelValue.value.join('')) return
|
||||
modelValue.value = value;
|
||||
emit('update:modelValue', value)
|
||||
emit('change', value)
|
||||
// #ifdef VUE2
|
||||
emit('input', value)
|
||||
// #endif
|
||||
},
|
||||
get():PickerValue[] {
|
||||
return props.value || props.modelValue || modelValue.value
|
||||
}
|
||||
} as WritableComputedOptions<PickerValue[]>)
|
||||
|
||||
const isEmpty = computed(():boolean => {
|
||||
return props.columns.length == 0 && pickerItemInstanceArray.value.every(child => child.options.length == 0)
|
||||
})
|
||||
const styles = computed(()=>{
|
||||
const style:Record<string, any> = {}
|
||||
if(props.bgColor) {
|
||||
style['background'] = props.bgColor!
|
||||
}
|
||||
if(props.radius) {
|
||||
style['border-top-left-radius'] = props.radius!
|
||||
style['border-top-right-radius'] = props.radius!
|
||||
}
|
||||
return style
|
||||
})
|
||||
|
||||
const curIndexArray = ref<number[]>([]);
|
||||
const curValueArray = ref([...pickerValue.value]);
|
||||
const curItemArray:PickerColumnItem[] = []
|
||||
const realColumns = computed(():PickerColumn[] => {
|
||||
const pickerColumns = pickerItemInstanceArray.value.map((child):PickerColumn => child.options)
|
||||
if(pickerColumns.length > 0) {
|
||||
return pickerColumns
|
||||
}
|
||||
return props.columns
|
||||
})
|
||||
const valueArrayEquals = computed(():boolean => pickerValue.value.join('') == curValueArray.value.join(''))
|
||||
|
||||
const manageChildInList = (child: LPickerItemComponentPublicInstance, shouldAdd: boolean) => {
|
||||
const index = pickerItemInstanceArray.value.indexOf(child);
|
||||
if(shouldAdd) {
|
||||
if(index != -1) return
|
||||
pickerItemInstanceArray.value.push(child)
|
||||
} else {
|
||||
if(index == -1) return
|
||||
pickerItemInstanceArray.value.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
const updateItems = (item: PickerColumnItem, index:number, column: number) => {
|
||||
curIndexArray.value[column] = index
|
||||
curValueArray.value[column] = item.value
|
||||
curItemArray[column] = item;
|
||||
|
||||
// clearTimeout(timer)
|
||||
// timer = setTimeout(()=>{
|
||||
// emit('change', [...curValueArray.value])
|
||||
// },50)
|
||||
};
|
||||
|
||||
const updatePickerItems = () => {
|
||||
const _indexs : number[] = []
|
||||
const _values : any[] = []
|
||||
pickerItemInstanceArray.value.forEach((child, column)=>{
|
||||
if(child.options.length == 0) return
|
||||
const value = curValueArray.value.length > column ? curValueArray.value[column] : null
|
||||
// #ifdef VUE3
|
||||
const index = value == null ? 0 : child._.exposed.getIndexByValue(value)
|
||||
child._.exposed.setIndex(index)
|
||||
// #endif
|
||||
// #ifdef VUE2
|
||||
const index = value == null ? 0 : child.getIndexByValue(value)
|
||||
child.setIndex(index)
|
||||
// #endif
|
||||
const item = child.options[index]
|
||||
_indexs.push(index)
|
||||
_values.push(item.value)
|
||||
|
||||
// curIndexArray.value[column] = index
|
||||
// curValueArray.value[column] = item.value
|
||||
curItemArray[column] = item
|
||||
|
||||
// 不能改变单向数据流, 只有值不存在时候才处理
|
||||
// if(pickerValue.value.length == 0) {
|
||||
// pickerValue.value = [...curValueArray.value]
|
||||
// }
|
||||
// if(pickerValue.value.join('') == curValueArray.value.join('')) return
|
||||
// pickerValue.value = [...curValueArray.value]
|
||||
|
||||
})
|
||||
if (curIndexArray.value.join('') == _indexs.join('')) return
|
||||
curIndexArray.value = _indexs
|
||||
curValueArray.value = _values
|
||||
// if(pickerValue.value.length == 0) {
|
||||
pickerValue.value = [...curValueArray.value]
|
||||
// }
|
||||
}
|
||||
|
||||
const onPick = (item: PickerColumnItem, index:number, column: number) => {
|
||||
if( curIndexArray.value[column] == index &&
|
||||
curValueArray.value[column] == item.value) return
|
||||
|
||||
curIndexArray.value[column] = index
|
||||
curValueArray.value[column] = item.value
|
||||
curItemArray[column] = item
|
||||
const obj:PickerPickEvent = {
|
||||
values: curValueArray.value,
|
||||
column,
|
||||
index
|
||||
}
|
||||
pickerValue.value = [...curValueArray.value]
|
||||
emit('pick', obj)
|
||||
};
|
||||
|
||||
const onCancel = (e: UniPointerEvent) => {
|
||||
updatePickerItems()
|
||||
emit('cancel', e)
|
||||
}
|
||||
const onConfirm = (e: UniPointerEvent) => {
|
||||
const values = [...curValueArray.value];
|
||||
const indexs = [...curIndexArray.value];
|
||||
const items = curItemArray.map((item):PickerColumnItem => toRaw(item))
|
||||
if(pickerValue.value.join('') != values.join('')) {
|
||||
pickerValue.value = values;
|
||||
}
|
||||
|
||||
const obj:PickerConfirmEvent = {
|
||||
values,
|
||||
indexs,
|
||||
items
|
||||
}
|
||||
emit('confirm', obj)
|
||||
}
|
||||
|
||||
const stopPickerValue = watch(pickerValue, () => {
|
||||
nextTick(()=>{
|
||||
curValueArray.value = pickerValue.value.map((item: PickerValue) => item);
|
||||
updatePickerItems()
|
||||
})
|
||||
})
|
||||
const stopColumns = watch(realColumns, ()=>{
|
||||
// nextTick(()=>{
|
||||
// updatePickerItems()
|
||||
// })
|
||||
updatePickerItems()
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
nextTick(()=>{
|
||||
if(
|
||||
!valueArrayEquals.value &&
|
||||
pickerValue.value.length > 0) {
|
||||
curValueArray.value = [...pickerValue.value]
|
||||
updatePickerItems()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(()=> {
|
||||
stopPickerValue()
|
||||
stopColumns()
|
||||
})
|
||||
|
||||
provide('limePicker', props)
|
||||
provide('limePickerOnPick', onPick)
|
||||
provide('limePickerUpdateItems', updateItems)
|
||||
provide('limePickerItems', pickerItemInstanceArray)
|
||||
provide('limePickerManageChildInList', manageChildInList)
|
||||
|
||||
return {
|
||||
styles,
|
||||
pickerValue,
|
||||
isEmpty,
|
||||
onCancel,
|
||||
onConfirm
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
<style lang="scss">
|
||||
@import './index.scss';
|
||||
</style>
|
||||
121
uni_modules/lime-picker/components/l-picker/props.ts
Normal file
121
uni_modules/lime-picker/components/l-picker/props.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
// @ts-nocheck
|
||||
export default {
|
||||
/**
|
||||
* 取消按钮文字
|
||||
*/
|
||||
cancelBtn: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
cancelStyle: {
|
||||
type:[String, Object],
|
||||
default: null
|
||||
},
|
||||
/**
|
||||
* 确定按钮文字
|
||||
*/
|
||||
confirmBtn: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
confirmStyle: {
|
||||
type: [String, Object],
|
||||
default: null
|
||||
},
|
||||
keys: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
title: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
titleStyle: {
|
||||
type: [String, Object],
|
||||
default: null
|
||||
},
|
||||
/**
|
||||
* 配置每一列的选项
|
||||
*/
|
||||
columns: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
/**
|
||||
* 选中值
|
||||
*/
|
||||
modelValue: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
defaultValue: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
/**
|
||||
* 是否为加载状态
|
||||
*/
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
loadingColor: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
loadingMaskColor: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
loadingSize: {
|
||||
type: String,
|
||||
default: '64rpx'
|
||||
},
|
||||
itemHeight: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
itemColor: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
itemFontSize: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
itemActiveColor: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
|
||||
indicatorStyle: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bgColor:{
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
groupHeight:{
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
radius:{
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
/**
|
||||
* 列表更新后,是否归0
|
||||
*/
|
||||
resetIndex: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
80
uni_modules/lime-picker/components/l-picker/type.ts
Normal file
80
uni_modules/lime-picker/components/l-picker/type.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
// @ts-nocheck
|
||||
export type PickerValue = any;//string | number;
|
||||
export type PickerColumnItem = {
|
||||
id: any|null;
|
||||
label : string;
|
||||
disabled: boolean | null;
|
||||
value : string;//string | number;
|
||||
children : PickerColumn | null
|
||||
}
|
||||
export type PickerColumn = PickerColumnItem[];
|
||||
export type PickerPickEvent= {
|
||||
values: PickerValue[];
|
||||
column : number;
|
||||
index : number;
|
||||
}
|
||||
export type PickerConfirmEvent = {
|
||||
values: PickerValue[]
|
||||
indexs: number[]
|
||||
items: PickerColumnItem[]
|
||||
}
|
||||
/**
|
||||
* 定义比较数组时返回的变化对象类型。
|
||||
*/
|
||||
export type PickerChangeInfo = {
|
||||
column: number; // 变化的列索引
|
||||
direction: 1 | -1 | 0; // 变化方向:1 表示增加,-1 表示减少, 0表示无变化
|
||||
index: number; // 变化后的新值,在列表中表示下标
|
||||
}
|
||||
|
||||
|
||||
export interface PickerProps {
|
||||
/**
|
||||
* 取消按钮文字
|
||||
*/
|
||||
cancelBtn ?: string;
|
||||
cancelStyle ?: string | UTSJSONObject;
|
||||
/**
|
||||
* 确定按钮文字
|
||||
*/
|
||||
confirmBtn ?: string;
|
||||
confirmStyle ?: string | UTSJSONObject;
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
title ?: string;
|
||||
titleStyle ?: string | UTSJSONObject;
|
||||
/**
|
||||
* 用来定义 value / label 在 `options` 中对应的字段别名
|
||||
*/
|
||||
keys?: UTSJSONObject;
|
||||
/**
|
||||
* 配置每一列的选项
|
||||
*/
|
||||
columns : PickerColumn[];
|
||||
/**
|
||||
* 选中值
|
||||
*/
|
||||
modelValue ?: PickerValue[];
|
||||
defaultValue ?: PickerValue[];
|
||||
value ?: PickerValue[];
|
||||
/**
|
||||
* 是否为加载状态
|
||||
*/
|
||||
loading: boolean;
|
||||
loadingColor?: string;
|
||||
loadingMaskColor?: string;
|
||||
loadingSize: string;
|
||||
|
||||
itemHeight?: string;
|
||||
itemColor?: string;
|
||||
itemFontSize?: string;
|
||||
itemActiveColor?: string;
|
||||
itemActiveFontWeight?: number;
|
||||
|
||||
indicatorStyle?: string;
|
||||
bgColor?:string;
|
||||
groupHeight?:string;
|
||||
radius?:string;
|
||||
resetIndex: boolean
|
||||
}
|
||||
22
uni_modules/lime-picker/components/l-picker/utils.uts
Normal file
22
uni_modules/lime-picker/components/l-picker/utils.uts
Normal file
@@ -0,0 +1,22 @@
|
||||
// @ts-nocheck
|
||||
/**
|
||||
* 在数组的指定位置插入或更新值。
|
||||
* 如果指定的索引小于数组的长度,则更新该位置的值。
|
||||
* 如果指定的索引大于或等于数组的长度,则将值添加到数组的末尾。
|
||||
*
|
||||
* @param {number[]} arr - 要操作的数字数组。
|
||||
* @param {number} index - 要插入或更新值的索引位置。
|
||||
* @param {number} value - 要插入或更新的值。
|
||||
*/
|
||||
export function pushAt<T>(arr: T[], index: number, value: T){
|
||||
// #ifdef APP-ANDROID
|
||||
if (index < arr.length) {
|
||||
arr[index] = value;
|
||||
} else {
|
||||
arr.push(value);
|
||||
}
|
||||
// #endif
|
||||
// #ifndef APP-ANDROID
|
||||
arr[index] = value;
|
||||
// #endif
|
||||
};
|
||||
Reference in New Issue
Block a user