feat:还原更新框架

This commit is contained in:
2026-07-23 14:49:48 +08:00
parent d5a6a16ea5
commit 75c7434f79
529 changed files with 43714 additions and 68201 deletions
@@ -1,27 +1,15 @@
<template>
<view class="u-picker-wraper">
<view v-if="hasInput" class="u-picker-input cursor-pointer" @click="onShowByClickInput">
<slot :value="inputLabel">
</slot>
<slot name="trigger" :value="inputLabel">
</slot>
<up-input
v-if="!$slots['default'] && !$slots['$default'] && !$slots['trigger']"
:readonly="true"
v-model="inputLabel"
v-bind="inputPropsInner">
</up-input>
<cover-view class="input-cover"></cover-view>
<view class="u-picker-warrper">
<view v-if="hasInput" class="u-picker-input cursor-pointer" @click="onShowByClickInput">
<slot>
<up-input :disabled="disabled" :disabledColor="disabledColor" :placeholder="placeholder" :readonly="true" border="surround" v-model="inputLabel"></up-input>
<div class="input-cover"></div>
</slot>
</view>
<u-popup
:show="show || (hasInput && showByClickInput)"
:mode="popupMode"
:zIndex="zIndex"
:bgColor="bgColor"
:round="round"
:duration="duration"
:pageInline="pageInline"
:overlayOpacity="overlayOpacity"
@close="closeHandler"
>
<view class="u-picker">
@@ -43,13 +31,11 @@
<slot name="toolbar-bottom"></slot>
<picker-view
class="u-picker__view"
:mask-class="maskClass"
:mask-style="maskStyleInner"
:indicatorStyle="`height: ${addUnit(itemHeight, 'px')}`"
:indicatorStyle="`height: ${addUnit(itemHeight)}`"
:value="innerIndex"
:immediateChange="immediateChange"
:style="{
height: `${addUnit(visibleItemCount * itemHeight, 'px')}`
height: `${addUnit(visibleItemCount * itemHeight)}`
}"
@change="changeHandler"
>
@@ -65,8 +51,8 @@
v-for="(item1, index1) in item"
:key="index1"
:style="{
height: addUnit(itemHeight, 'px'),
lineHeight: addUnit(itemHeight, 'px'),
height: addUnit(itemHeight),
lineHeight: addUnit(itemHeight),
fontWeight: index1 === innerIndex[index] ? 'bold' : 'normal',
display: 'block'
}"
@@ -103,10 +89,6 @@
* @property {Boolean} closeOnClickOverlay 是否允许点击遮罩关闭选择器(默认 false )
* @property {Array} defaultIndex 各列的默认索引
* @property {Boolean} immediateChange 是否在手指松开时立即触发change事件(默认 true )
* @property {String | Number} round 圆角值(默认 0)
* @property {String } bgColor 背景色值(默认 '' )
* @property {String | Number} duration 动画时长,单位ms (默认 300 )
* @property {String | Number} overlayDuration 遮罩层动画时长,单位ms (默认 350 )
* @event {Function} close 关闭选择器时触发
* @event {Function} cancel 点击取消按钮触发
* @event {Function} change 当选择值变化时触发
@@ -135,6 +117,19 @@ export default {
}
},
watch: {
// 监听默认索引的变化,重新设置对应的值
defaultIndex: {
immediate: true,
deep:true,
handler(n,o) {
// 修复uniapp调用子组件直接:defaultIndex="[0]"这样写
// v-model的值变化时候导致defaultIndexwatch也会执行的问题
//单纯vue不会出现
if (!o || n.join("/") != o.join("/")) {
this.setIndexs(n, true)
}
}
},
// 监听columns参数的变化
columns: {
immediate: true,
@@ -143,113 +138,40 @@ export default {
this.setColumns(n)
}
},
// 监听默认索引的变化,重新设置对应的值
defaultIndex: {
immediate: true,
deep:true,
handler(n,o) {
// 修复uniapp调用子组件直接:defaultIndex="[0]"这样写
// v-model的值变化时候导致defaultIndexwatch也会执行的问题
//单纯vue不会出现
if (!o || n.join("/") != o.join("/")) {
this.setIndexs(n, true)
}
}
},
modelValue: {
immediate: true,
deep:true,
handler(n,o) {
// 修复uniapp调用子组件直接:defaultIndex="[0]"这样写
// v-model的值变化时候导致defaultIndexwatch也会执行的问题
//单纯vue不会出现
if (!o || n.join("/") != o.join("/")) {
let arr = [];
if (n != null) {
n.forEach((element, index) => {
let currentCols = this.getColumnValues(index)
if(!Array.isArray(currentCols) && currentCols.length===0) {
return
}
if (typeof currentCols[0] === 'object') {
currentCols.forEach((item, index2) => {
if (item[this.valueName] == element) {
arr.push(index2)
}
})
} else {
currentCols.forEach((item, index2) => {
if (item == element) {
arr.push(index2)
}
})
}
});
// alert(arr)
if (arr.length == 0 && this.defaultIndex) {
} else {
this.setIndexs(arr, true)
}
}
}
}
}
},
emits: ['close', 'cancel', 'confirm', 'change', 'update:modelValue', 'update:show'],
computed: {
// input的props
inputPropsInner() {
return {
border: this.inputBorder,
placeholder: this.placeholder,
disabled: this.disabled,
disabledColor: this.disabledColor,
...this.inputProps
}
},
//已选&&已确认的值显示在input上面的文案
inputLabel() {
let firstItem = this.innerColumns[0] && this.innerColumns[0][0];
// //区分是不是对象数组
if (firstItem && Object.prototype.toString.call(firstItem) === '[object Object]') {
let res = this.innerColumns[0].filter(item => this.modelValue.includes(item[this.valueName]))
res = res.map(item => item[this.keyName]);
return res.join("/");
} else {
//用户确定的值,才显示到输入框
return this.modelValue.join("/");
}
},
//已选,待确认的值
inputValue() {
let items = this.innerColumns.map((item, index) => item[this.innerIndex[index]])
let res = []
//区分是不是对象数组
if (items[0] && Object.prototype.toString.call(items[0]) === '[object Object]') {
//对象数组返回属性值集合
items.forEach(element => {
res.push(element && element[this.valueName])
});
} else {
//非对象数组返回元素集合
items.forEach((element, index) => {
res.push(element)
});
}
return res
},
maskStyleInner() {
// 显式传入时,始终以外部传参为准(即使传空字符串)
if (this.upHasProp('maskStyle')) {
return this.maskStyle || ''
}
if (this.upThemeIsDark) {
const topBottomStrong = 'rgba(28, 28, 30, 0.95)'
const topBottomWeak = 'rgba(28, 28, 30, 0.6)'
return `background-image: linear-gradient(180deg, ${topBottomStrong}, ${topBottomWeak}), linear-gradient(0deg, ${topBottomStrong}, ${topBottomWeak});`
}
return ''
//已选&&已确认的值显示在input上面的文案
inputLabel() {
let firstItem = this.innerColumns[0] && this.innerColumns[0][0];
// //区分是不是对象数组
if (firstItem && Object.prototype.toString.call(firstItem) === '[object Object]') {
let res = this.innerColumns[0].filter(item => this.modelValue.includes(item['id']))
res = res.map(item => item[this.keyName]);
return res.join("/");
} else {
//用户确定的值,才显示到输入框
return this.modelValue.join("/");
}
},
//已选,待确认的值
inputValue() {
let items = this.innerColumns.map((item, index) => item[this.innerIndex[index]])
let res = []
//区分是不是对象数组
if (items[0] && Object.prototype.toString.call(items[0]) === '[object Object]') {
//对象数组返回id集合
items.forEach(element => {
res.push(element && element['id'])
});
} else {
//非对象数组返回元素集合
items.forEach((element, index) => {
res.push(element)
});
}
return res
}
},
methods: {
@@ -274,7 +196,6 @@ export default {
if (this.hasInput) {
this.showByClickInput = false
}
this.setDefault()
this.$emit('update:show', false)
this.$emit('close')
}
@@ -284,13 +205,14 @@ export default {
if (this.hasInput) {
this.showByClickInput = false
}
this.setDefault()
this.$emit('update:show', false)
this.$emit('cancel')
},
setDefault() {
let arr = [0]
if (this.lastIndex.length == 0) {
// 点击工具栏的确定按钮
confirm() {
//如果用户有没有触发过change
if (!this.currentActiveValue.length) {
let arr = [0]
//如果有默认值&&默认值的数组长度是正确的,就用默认值
if (Array.isArray(this.defaultIndex) && this.defaultIndex.length == this.innerColumns.length) {
arr = [...this.defaultIndex];
@@ -298,23 +220,13 @@ export default {
//否则默认都选中第一个
arr = Array(this.innerColumns.length).fill(0);
}
} else {
arr = deepClone(this.lastIndex)
}
this.setLastIndex(arr)
this.setIndexs(arr)
},
// 点击工具栏的确定按钮
confirm() {
// 如果用户有没有触发过change
if (!this.currentActiveValue.length) {
this.setDefault()
this.setLastIndex(arr)
this.setIndexs(arr)
}
this.$emit('update:modelValue', this.inputValue)
if (this.hasInput) {
this.showByClickInput = false
}
this.setLastIndex(this.innerIndex)
this.$emit('update:show', false)
this.$emit('confirm', {
indexs: this.innerIndex,
@@ -334,7 +246,7 @@ export default {
// 通过对比前后两次的列索引,得出当前变化的是哪一列
for (let i = 0; i < value.length; i++) {
let item = value[i]
if (item !== undefined && item !== (this.lastIndex[i] || 0)) { // 把undefined转为合法假值0
if (item !== (this.lastIndex[i] || 0)) { // 把undefined转为合法假值0
// 设置columnIndex为当前变化列的索引
columnIndex = i
// index则为变化列中的变化项的索引
@@ -345,14 +257,13 @@ export default {
this.columnIndex = columnIndex
const values = this.innerColumns
// 将当前的各项变化索引,设置为"上一次"的索引变化值
// this.setLastIndex(value)
this.setLastIndex(value)
this.setIndexs(value)
//如果是非自带输入框才会在change时候触发v-model绑值的变化
//否则会非常的奇怪,用户未确认,值就变了
// if (!this.hasInput) {
// this.$emit('update:modelValue', this.inputValue)
// }
if (!this.hasInput) {
this.$emit('update:modelValue', this.inputValue)
}
this.$emit('change', {
// #ifndef MP-WEIXIN || MP-LARK
// 微信小程序不能传递this,会因为循环引用而报错
@@ -407,25 +318,10 @@ export default {
// 设置整体各列的columns的值
setColumns(columns) {
// console.log(columns)
const prevColumns = this.innerColumns
this.innerColumns = deepClone(columns)
// 如果在设置各列数据时,没有被设置默认的各列索引defaultIndex,那么用0去填充它,数组长度为列的数量
if (this.innerIndex.length === 0) {
this.innerIndex = new Array(columns.length).fill(0)
} else {
// 修复异步columns加载时defaultIndex位置不更新的问题 (issue #841)
// 当某列从空数组变为有数据时,picker-view不会因为:value未变化而重新滚动到指定位置
// 需要通过先清空再赋值的方式强制触发picker-view的滚动更新
const hasColumnsChangedFromEmpty = columns.some(
(col, i) => col && col.length > 0 && (!prevColumns[i] || prevColumns[i].length === 0)
)
if (hasColumnsChangedFromEmpty) {
const targetIndex = deepClone(this.innerIndex)
this.innerIndex = []
this.$nextTick(() => {
this.innerIndex = targetIndex
})
}
}
},
// 获取各列选中值对应的索引
@@ -446,20 +342,21 @@ export default {
</script>
<style lang="scss" scoped>
@import "../../libs/css/components.scss";
.u-picker {
position: relative;
&-input {
position: relative;
.input-cover {
opacity: 0;
position: absolute;
top: 0;
bottom: 0;
left: 0;
&-input {
position: relative;
.input-cover {
opacity: 0;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index:1;
}
z-index:1;
}
}
&__view {
@@ -498,7 +395,7 @@ export default {
@include flex;
justify-content: center;
align-items: center;
background-color: var(--up-card-bg-color, #ffffff);
background-color: rgba(255, 255, 255, 0.87);
z-index: 1000;
}
}