first commit

This commit is contained in:
lingxiao865
2026-02-10 08:05:03 +08:00
commit c5af079d8c
1094 changed files with 97530 additions and 0 deletions

View File

@@ -0,0 +1,315 @@
<template>
<view>
<t-popup
v-if="usePopup"
:visible="dataVisible"
placement="bottom"
:close-on-overlay-click="autoClose"
:show-overlay="isShowOverlay(popupProps && popupProps.showOverlay, true)"
:using-custom-navbar="usingCustomNavbar || (popupProps && popupProps.usingCustomNavbar)"
:custom-navbar-height="coalesce(customNavbarHeight, popupProps && popupProps.usingCustomNavbar)"
:z-index="(popupProps && popupProps.zIndex) || defaultPopUpzIndex"
:overlay-props="(popupProps && popupProps.overlayProps) || defaultPopUpProps"
@visible-change="onPopupChange"
>
<template #content>
<view
:style="tools._style([customStyle])"
:class="classPrefix + ' ' + tClass"
>
<view
v-if="header"
:class="classPrefix + '__toolbar'"
>
<view
v-if="cancelBtn"
:class="classPrefix + '__cancel ' + tClassCancel"
@click="onCancel"
>
{{ cancelBtn }}
</view>
<view :class="classPrefix + '__title ' + tClassTitle">
{{ title }}
</view>
<view
v-if="confirmBtn"
:class="classPrefix + '__confirm ' + tClassConfirm"
@click="onConfirm"
>
{{ confirmBtn }}
</view>
</view>
<slot name="header" />
<slot name="content" />
<view
:class="tools.cls(classPrefix + '__main', [])"
disable-scroll
>
<slot />
<view :class="classPrefix + '__mask ' + classPrefix + '__mask--top'" />
<view :class="classPrefix + '__mask ' + classPrefix + '__mask--bottom'" />
<view
:class="classPrefix + '__indicator'"
:style="'height: ' + itemHeight + 'px; top: ' + indicatorTop + 'px'"
/>
</view>
<slot name="footer" />
</view>
</template>
</t-popup>
<block v-else>
<view
:style="tools._style([customStyle])"
:class="classPrefix + ' ' + tClass"
>
<view
v-if="header"
:class="classPrefix + '__toolbar'"
>
<view
v-if="cancelBtn"
:class="classPrefix + '__cancel ' + tClassCancel"
@click="onCancel"
>
{{ cancelBtn }}
</view>
<view :class="classPrefix + '__title ' + tClassTitle">
{{ title }}
</view>
<view
v-if="confirmBtn"
:class="classPrefix + '__confirm ' + tClassConfirm"
@click="onConfirm"
>
{{ confirmBtn }}
</view>
</view>
<slot name="header" />
<slot name="content" />
<view
:class="tools.cls(classPrefix + '__main', [])"
disable-scroll
>
<slot />
<view :class="classPrefix + '__mask ' + classPrefix + '__mask--top'" />
<view :class="classPrefix + '__mask ' + classPrefix + '__mask--bottom'" />
<view
:class="classPrefix + '__indicator'"
:style="'height: ' + itemHeight + 'px; top: ' + indicatorTop + 'px'"
/>
</view>
<slot name="footer" />
</view>
</block>
</view>
</template>
<script>
import TPopup from '../popup/popup';
import { uniComponent } from '../common/src/index';
import { coalesce } from '../common/utils';
import { prefix } from '../common/config';
import props from './props';
import useCustomNavbar from '../mixins/using-custom-navbar';
import tools from '../common/utils.wxs';
import { ParentMixin, RELATION_MAP } from '../common/relation';
const name = `${prefix}-picker`;
const DEFAULT_KEYS = { value: 'value', label: 'label', icon: 'icon' };
export default uniComponent({
name,
options: {
styleIsolation: 'shared',
},
externalClasses: [
`${prefix}-class`,
`${prefix}-class-confirm`,
`${prefix}-class-cancel`,
`${prefix}-class-title`,
],
components: {
TPopup,
},
mixins: [
ParentMixin(RELATION_MAP.PickerItem),
useCustomNavbar,
],
props: {
...props,
},
emits: [
'visible-change',
'update:visible',
],
data() {
return {
prefix,
classPrefix: name,
defaultPopUpProps: {},
defaultPopUpzIndex: 11500,
indicatorTop: 72, // 默认indicator位置会动态计算
tools,
dataValue: coalesce(this.value, this.defaultValue),
dataVisible: this.visible,
};
},
watch: {
value: {
handler(value) {
this.dataValue = value;
},
immediate: true,
},
visible: {
handler(v) {
this.dataVisible = v;
},
immediate: true,
},
dataVisible: {
handler() {
this.onWatchVisible();
setTimeout(() => {
this.onWatchVisible();
});
},
immediate: true,
},
dataValue: {
handler() {
this.onWatchVisible();
},
immediate: true,
},
itemHeight: {
handler() {
this.updateIndicatorPosition();
},
immediate: true,
},
visibleItemCount: {
handler() {
this.updateIndicatorPosition();
},
immediate: true,
},
},
mounted() {
this.children?.map((column, index) => (column.columnIndex = index));
this.updateIndicatorPosition();
setTimeout(() => {
this.updateChildren();
});
},
methods: {
coalesce,
innerAfterLinked() {
this.updateChildren();
},
updateChildren() {
const { pickItemHeight } = this;
const { value, defaultValue, keys, visibleItemCount, itemHeight } = this;
this.children?.forEach((child, index) => {
child.value = coalesce(value?.[index], defaultValue?.[index], '');
child.columnIndex = index;
child.pickItemHeight = pickItemHeight;
child.itemHeight = itemHeight;
child.visibleItemCount = visibleItemCount;
child.keys = { ...DEFAULT_KEYS, ...(keys || {}) };
child.update();
});
},
getSelectedValue() {
const value = this.children?.map(item => item._selectedValue);
const label = this.children?.map(item => item._selectedLabel);
return [value, label];
},
getColumnIndexes() {
const columns = this.children?.map((pickerColumn, columnIndex) => ({
column: columnIndex,
index: pickerColumn._selectedIndex,
}));
return columns;
},
onConfirm() {
const [value, label] = this.getSelectedValue();
const columns = this.getColumnIndexes();
this.close('confirm-btn');
this.$emit('confirm', { value, label, columns });
if (JSON.stringify(this.dataValue) === JSON.stringify(value)) return;
this.$emit('change', { value, label, columns });
},
triggerColumnChange({ column, index }) {
const [value, label] = this.getSelectedValue();
this.$emit('pick', { value, label, column, index });
},
onCancel() {
this.close('cancel-btn');
this.$emit('cancel');
},
onPopupChange(e) {
const { visible } = e;
this.close('overlay');
this.$emit('visible-change', { visible });
this.$emit('update:visible', visible);
},
close(trigger) {
if (this.autoClose) {
this.dataVisible = false;
this.$emit('update:visible', false);
}
this.$emit('close', { trigger });
},
updateIndicatorPosition() {
const { itemHeight, visibleItemCount } = this;
const indicatorTop = ((visibleItemCount - 1) / 2) * itemHeight;
this.indicatorTop = indicatorTop;
},
onWatchVisible() {
const {
usePopup,
dataVisible,
} = this;
if (!usePopup || dataVisible) {
this.updateChildren();
this.updateIndicatorPosition();
}
},
isShowOverlay(value, defaultValue) {
return tools.isBoolean(value) ? value : defaultValue;
},
},
});
</script>
<style scoped>
@import './picker.css';
/* #ifndef MP-WEIXIN */
/* 适配 qq 小程序等 */
:deep(t-picker-item) {
z-index: 1;
flex: 1;
}
/* #endif */
</style>