Commit 0fa8be33 by pangchong

feat: 全局下拉框和日期组件修改

parent e539d854
...@@ -9,6 +9,7 @@ declare module 'vue' { ...@@ -9,6 +9,7 @@ declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
// 全局组件 // 全局组件
GlobalButton: typeof import('./src/components/global-button/global-button.vue')['default'] GlobalButton: typeof import('./src/components/global-button/global-button.vue')['default']
GlobalDate: typeof import('./src/components/global-date/global-date.vue')['default']
GlobalEmpty: typeof import('./src/components/global-empty/global-empty.vue')['default'] GlobalEmpty: typeof import('./src/components/global-empty/global-empty.vue')['default']
GlobalField: typeof import('./src/components/global-field/global-field.vue')['default'] GlobalField: typeof import('./src/components/global-field/global-field.vue')['default']
GlobalIcon: typeof import('./src/components/global-icon/global-icon.vue')['default'] GlobalIcon: typeof import('./src/components/global-icon/global-icon.vue')['default']
......
<template>
<!-- 全局日期控件 -->
<view class="date">
<up-datetime-picker
:show="show"
v-model="defaultValue"
:mode="mode"
@confirm="confirm"
closeOnClickOverlay
@close="show = false"
@cancel="show = false"
:cancelText="cancelText"
:confirmText="confirmText"
:cancelColor="cancelColor"
:confirmColor="confirmColor"
></up-datetime-picker>
<view class="date-content" :class="getPickerClass" @tap="show = true" :style="getStyle">
<text class="date-value">{{ getLabelValue }}</text>
<view class="date-icon">
<view class="date-icon-close" v-if="clearable && !showPlaceholder && !disabled" @tap.stop="clear">
<up-icon name="close-circle-fill" color="#c0c4cc" size="36rpx"></up-icon>
</view>
<global-icon icon="calendar" color="#86909C"></global-icon>
</view>
</view>
</view>
</template>
<script setup>
import { computed, ref, watch } from 'vue'
import Day from '@/utils/dayjs'
const es = defineEmits(['update:modelValue', 'change'])
const ps = defineProps({
//日历模式date,time,year-month
mode: {
type: String,
default: 'date'
},
//显示为空的value值
emptyValue: {
type: [String, Number],
default: ''
},
modelValue: {
type: [String, Number],
default: ''
},
clearable: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: '请选择'
},
disabled: {
type: Boolean,
default: false
},
pickAlign: {
type: String,
default: 'left'
},
format: {
type: String,
default: 'YYYY-MM-DD'
},
cancelText: {
type: String,
default: '取消'
},
confirmText: {
type: String,
default: '确认'
},
cancelColor: {
type: String,
default: '#909193'
},
confirmColor: {
type: String,
default: '#165dff'
}
})
//获取下拉框样式
const getStyle = computed(() => {
let pickAlign = 'flex-start'
if (ps.pickAlign == 'center') {
pickAlign = 'center'
} else if (ps.pickAlign == 'right') {
pickAlign = 'flex-end'
}
return {
justifyContent: pickAlign
}
})
//下拉框显示的内容
const labelValue = ref('')
const getLabelValue = computed(() => {
if (labelValue.value) {
return Day(labelValue.value).format(ps.format)
} else {
return ps.placeholder
}
})
//获取下拉框class
const showPlaceholder = computed(() => {
return !labelValue.value || labelValue.value == ps.emptyValue
})
const getPickerClass = computed(() => {
return {
disabled: ps.disabled,
placeholder: showPlaceholder.value
}
})
const show = ref(false)
//设置初始值
const defaultValue = ref()
watch(
() => ps.modelValue,
() => {
if (ps.modelValue != ps.emptyValue) {
labelValue.value = parseInt(ps.modelValue)
defaultValue.value = parseInt(ps.modelValue)
} else {
defaultValue.value = Day().valueOf()
}
},
{ immediate: true }
)
//点击确定按钮
const confirm = (e) => {
show.value = false
labelValue.value = e.value
defaultValue.value = e.value
es('update:modelValue', String(defaultValue.value))
es('change', String(defaultValue.value))
}
//点击清空按钮
const clear = () => {
labelValue.value = ''
defaultValue.value = ''
es('update:modelValue', ps.emptyValue)
es('change', ps.emptyValue)
}
</script>
<style lang="scss" scoped>
.date {
flex: auto;
&-content {
display: flex;
align-items: center;
line-height: 48rpx;
&.placeholder {
.date-value {
color: $uni-text-3;
}
}
&.disabled {
background: #f5f7fa;
}
}
&-value {
color: $uni-text-4;
margin-right: 8rpx;
}
&-icon {
display: flex;
align-items: center;
&-close {
margin-left: 4rpx;
}
}
}
</style>
<template> <template>
<!-- 全局下拉框 --> <!-- 全局下拉框控件 -->
<picker <view class="picker">
:mode="mode" <up-picker
:range="getRange" :show="show"
@change="onChange" :columns="[getColumns]"
:disabled="disabled" :keyName="labelField"
:value="mode == 'selector' ? getPickerValue : getVal" @confirm="confirm"
style="flex: auto" closeOnClickOverlay
> @close="show = false"
<view class="picker" :class="{ placeholder: !!getVal, disabled }" :style="getStyle"> @cancel="show = false"
<text class="picker-value">{{ getVal }}</text> :defaultIndex="[defaultIndex]"
:cancelText="cancelText"
:confirmText="confirmText"
:cancelColor="cancelColor"
:confirmColor="confirmColor"
></up-picker>
<view class="picker-content" :class="getPickerClass" @tap="show = true" :style="getStyle">
<text class="picker-value">{{ getLabelValue }}</text>
<view class="picker-icon"> <view class="picker-icon">
<view class="picker-icon-close" v-if="clearable && selectedValue && !disabled" @tap.stop="clear"> <view class="picker-icon-close" v-if="clearable && !showPlaceholder && !disabled" @tap.stop="clear">
<up-icon name="close-circle-fill" color="#c0c4cc" size="36rpx"></up-icon> <up-icon name="close-circle-fill" color="#c0c4cc" size="36rpx"></up-icon>
</view> </view>
<up-icon name="arrow-right" color="#86909C" size="36rpx" v-if="mode == 'selector'"></up-icon> <up-icon name="arrow-right" color="#86909C" size="36rpx"></up-icon>
<global-icon icon="calendar" color="#86909C" v-else></global-icon> </view>
</view> </view>
</view> </view>
</picker>
</template> </template>
<script setup> <script setup>
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import * as dictData from './dictData' import * as dictData from './dictData'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import Day from '@/utils/dayjs'
const es = defineEmits(['update:modelValue', 'change']) const es = defineEmits(['update:modelValue', 'change'])
const ps = defineProps({ const ps = defineProps({
// selector,date
mode: {
type: String,
default: 'selector'
},
//显示为空的value值 //显示为空的value值
emptyValue: { emptyValue: {
type: [String, Number], type: [String, Number],
...@@ -49,7 +49,9 @@ const ps = defineProps({ ...@@ -49,7 +49,9 @@ const ps = defineProps({
}, },
options: { options: {
type: Array, type: Array,
default: () => [] default: () => {
return []
}
}, },
clearable: { clearable: {
type: Boolean, type: Boolean,
...@@ -74,8 +76,25 @@ const ps = defineProps({ ...@@ -74,8 +76,25 @@ const ps = defineProps({
disabled: { disabled: {
type: Boolean, type: Boolean,
default: false default: false
},
cancelText: {
type: String,
default: '取消'
},
confirmText: {
type: String,
default: '确认'
},
cancelColor: {
type: String,
default: '#909193'
},
confirmColor: {
type: String,
default: '#165dff'
} }
}) })
//获取下拉框样式
const getStyle = computed(() => { const getStyle = computed(() => {
let pickAlign = 'flex-start' let pickAlign = 'flex-start'
if (ps.pickAlign == 'center') { if (ps.pickAlign == 'center') {
...@@ -87,8 +106,26 @@ const getStyle = computed(() => { ...@@ -87,8 +106,26 @@ const getStyle = computed(() => {
justifyContent: pickAlign justifyContent: pickAlign
} }
}) })
//获取options //下拉框显示的内容
const getOptions = computed(() => { const labelValue = ref('')
const getLabelValue = computed(() => {
return labelValue.value || ps.placeholder
})
//获取下拉框class
const showPlaceholder = computed(() => {
return !labelValue.value || labelValue.value == ps.emptyValue
})
const getPickerClass = computed(() => {
return {
disabled: ps.disabled,
placeholder: showPlaceholder.value
}
})
const show = ref(false)
//设置下拉框打开的默认值
const defaultIndex = ref(0)
//获取下拉框的内容Columns
const getColumns = computed(() => {
if (ps.dictkey) { if (ps.dictkey) {
return cloneDeep(dictData[ps.dictkey]) return cloneDeep(dictData[ps.dictkey])
} else { } else {
...@@ -104,75 +141,58 @@ const getOptions = computed(() => { ...@@ -104,75 +141,58 @@ const getOptions = computed(() => {
} }
} }
}) })
const selectedValue = ref('') //显示的内容 //监听设置labelValue的值
watch( watch(
[() => ps.modelValue, () => ps.options], [() => ps.modelValue, () => ps.options],
() => { () => {
if (ps.mode == 'selector') { const option = getColumns.value.find((option) => String(option[ps.valueField]) === String(ps.modelValue))
const option = getOptions.value.find((option) => String(option[ps.valueField]) === String(ps.modelValue)) const index = getColumns.value.findIndex((option) => String(option[ps.valueField]) === String(ps.modelValue))
if (option) { if (option) {
selectedValue.value = option[ps.labelField] labelValue.value = option[ps.labelField]
defaultIndex.value = index
} else { } else {
selectedValue.value = '' labelValue.value = ''
} defaultIndex.value = 0
} else {
selectedValue.value = ps.modelValue
} }
}, },
{ immediate: true } { immediate: true }
) )
//点击确定按钮
const getRange = computed(() => { const confirm = (e) => {
return getOptions.value.map((option) => option[ps.labelField]) show.value = false
}) const index = e.indexs[0]
const onChange = (event) => { labelValue.value = getColumns.value[index][ps.labelField]
if (ps.mode == 'selector') { es('update:modelValue', getColumns.value[index][ps.valueField])
const index = event.detail.value es('change', getColumns.value[index][ps.valueField])
selectedValue.value = getOptions.value[index][ps.labelField]
const value = getOptions.value[index][ps.valueField] !== '' ? getOptions.value[index][ps.valueField] : ps.emptyValue
es('update:modelValue', value)
es('change', value)
} else {
selectedValue.value = String(Day(event.detail.value).valueOf())
es('update:modelValue', selectedValue.value || ps.emptyValue)
es('change', selectedValue.value || ps.emptyValue)
}
} }
const getVal = computed(() => { //点击清空按钮
if (ps.mode == 'selector') {
return selectedValue.value || ps.placeholder
} else {
//日期
return uni.$tool.timeStampFormat(selectedValue.value, { format: 'YYYY-MM-DD' }) || ps.placeholder
}
})
const getPickerValue = computed(() => {
const index = getOptions.value.findIndex((option) => String(option[ps.valueField]) === String(ps.modelValue))
return index > 0 ? index : 0
})
//清空值
const clear = () => { const clear = () => {
selectedValue.value = '' labelValue.value = ''
defaultIndex.value = 0
es('update:modelValue', ps.emptyValue) es('update:modelValue', ps.emptyValue)
es('change', ps.emptyValue) es('change', ps.emptyValue)
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.picker { .picker {
line-height: 48rpx; flex: auto;
&-content {
display: flex; display: flex;
align-items: center; align-items: center;
&-value { line-height: 48rpx;
color: $uni-text-4;
margin-right: 8rpx;
}
&.placeholder { &.placeholder {
.picker-value {
color: $uni-text-3; color: $uni-text-3;
} }
}
&.disabled { &.disabled {
background: #f5f7fa; background: #f5f7fa;
} }
}
&-value {
color: $uni-text-4;
margin-right: 8rpx;
}
&-icon { &-icon {
display: flex; display: flex;
align-items: center; align-items: center;
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
<up-input border="none" inputAlign="right" clearable v-model="formData.acType" disabled disabledColor="#fff"></up-input> <up-input border="none" inputAlign="right" clearable v-model="formData.acType" disabled disabledColor="#fff"></up-input>
</up-form-item> </up-form-item>
<up-form-item label="日期" :borderBottom="true" required prop="eventTime"> <up-form-item label="日期" :borderBottom="true" required prop="eventTime">
<global-picker pickAlign="right" clearable v-model="formData.eventTime" mode="date" :emptyValue="-1"></global-picker> <global-date pickAlign="right" clearable v-model="formData.eventTime" :emptyValue="-1"></global-date>
</up-form-item> </up-form-item>
<up-form-item label="事件描述" :borderBottom="true" labelPosition="top"> <up-form-item label="事件描述" :borderBottom="true" labelPosition="top">
<up-textarea <up-textarea
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
></up-textarea> ></up-textarea>
</up-form-item> </up-form-item>
<up-form-item label="完成时限" :borderBottom="true"> <up-form-item label="完成时限" :borderBottom="true">
<global-picker pickAlign="right" clearable mode="date" :emptyValue="-1" placeholder="请选择日期"></global-picker> <global-date pickAlign="right" clearable :emptyValue="-1" placeholder="请选择日期"></global-date>
</up-form-item> </up-form-item>
</view> </view>
<view class="form"> <view class="form">
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
></up-textarea> ></up-textarea>
</up-form-item> </up-form-item>
<up-form-item label="完成时限" :borderBottom="true"> <up-form-item label="完成时限" :borderBottom="true">
<global-picker pickAlign="right" clearable mode="date" :emptyValue="-1" placeholder="请选择日期"></global-picker> <global-date pickAlign="right" clearable :emptyValue="-1" placeholder="请选择日期"></global-date>
</up-form-item> </up-form-item>
</view> </view>
</up-form> </up-form>
......
...@@ -79,6 +79,9 @@ ...@@ -79,6 +79,9 @@
<up-form-item label="计划完成时间" :borderBottom="true"> <up-form-item label="计划完成时间" :borderBottom="true">
<global-picker pickAlign="right" clearable mode="date" :emptyValue="-1" placeholder="请选择日期"></global-picker> <global-picker pickAlign="right" clearable mode="date" :emptyValue="-1" placeholder="请选择日期"></global-picker>
</up-form-item> </up-form-item>
<up-form-item label="计划完成时间" :borderBottom="true">
<global-select pickAlign="right" v-model="selectValue" clearable></global-select>
</up-form-item>
</view> </view>
</view> </view>
</up-form> </up-form>
...@@ -87,11 +90,16 @@ ...@@ -87,11 +90,16 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref, watch } from 'vue'
const goTo = () => { const goTo = () => {
uni.navigateTo({ url: 'edit-decompose' }) uni.navigateTo({ url: 'edit-decompose' })
} }
const selectValue = ref('')
watch(selectValue, (value) => {
console.log(value)
})
//开关
const value = ref(true) const value = ref(true)
const change = (e) => { const change = (e) => {
console.log(e) console.log(e)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment