在uniapp中开发年份弹出选择组件

多层组件嵌套

<template>
    <view class="">
        <view class="zq-imitate-input" @click="toggleContent">
            <text v-if="valueStr.length > 0">{
   
   { valueStr }}</text>
            <text v-else>{
   
   { datePlaceholder }}</text>
            <text v-if="valueStr.length > 0" class="zq-imitate-input-clearable" @click.stop="onClearable">
                <uni-icons type="clear" size="22" color="rgb(192, 196, 204)"></uni-icons>
            </text>
        </view>
        <zqBodyPopup ref="zqBodyPopupRef" :key="'time-popup-'" mode="bottom" :overlayOpacity="0">
            <!-- 关闭按钮 -->
            <uni-icons type="closeempty" size="20" class="upper-close-icon" @click="closeUpper"></uni-icons>
            <YearTimeItem ref="YearTimeItemRef" :yearValue="yearValue" @onChangeSelect="onChangeYearItem"></YearTimeItem>
            <view class="zq-button-group">
                <button>重置</button>
                <button type="primary" @click='changeValueBtn'>确定</button>
            </view>
        </zqBodyPopup>
        
    </view>
</template>

<script lang="ts" setup>
import { ref, reactive, watch, onMounted, computed } from "vue";
import zqBodyPopup from '../zq-body-popup/zq-body-popup.vue'
import YearTimeItem from './zq-select-year.vue'
import { isArray } from "../../utils/tool";


const zqBodyPopupRef = ref();
const YearTimeItemRef = ref('')
const open = () => {
    zqBodyPopupRef.value.open();
};

const emits = defineEmits(['update:modelValue', 'yeartimePickermodelValue'])

const props = defineProps({
    quick: {
        type: Object,
        default: () => {
            return {}
        },
    },
    // 标记的日期
    markDays: {
        type: Array,
        default: () => {
            return []; //例如["2023-05-01", "2023-05-03", "2023-04-13"]
        }
    },
    modelValue: {
        type: Object,
        default: () => {
            return {}
        },
    },
    allValue: {
        type: Object,
        default: () => {
            return {}
        },
    },
})
// const localdata = ref([{
//     value: 'LE',
//     text: '小于等于',
// },
// {
//     value: 'GE',
//     text: '大于等于',
// },
// {
//     value: 'EQ',
//     text: '等于',
// },
// ])
const modelV = ref([]);
const popupShow = ref('')
// const zqBodyPopupRef = ref()
const dates = ref([])  // 当前月的日期数据
const currentDataVal = ref('')
const futureDataVal = ref('')
const choose = ref('')
// const valueStr = ref('')
const showUpper = ref(false);
const placeholderStr = ref('请选择年份');
// yeartimeValue.value.operator=
// modelV.value.yearhangeTime = props.quick.modelValue
// modelV.value.operator = props.quick.gl ? props.quick.gl : "GE"
const yearValue = ref('')
const toggleContent = () => {
    // console.log(modelV.value, '===');
    yearValue.value = modelV.value
    choose.value = modelV.value
    let time = choose.value ? new Date(choose.value) : new Date()
    currentDataVal.value = Math.floor(time.getFullYear() / 10) * 10
    futureDataVal.value = currentDataVal.value * 1 + 9

    zqBodyPopupRef.value.open();

    // uni.hideKeyboard();
}
// computed
const valueStr = computed(() => {
    console.log(props.allValue, '---props.allValue');

    if (props.allValue.operator === 'BETWEEN') {
        return props.allValue.rangeValue.join(' 至 ')
    } else {
        return props.allValue.dateValue
    }





    // if (modelV.value) {
    // 	return modelV.value?.join('-')
    // } else {
    // 	return ''
    // }
})
const datePlaceholder = computed(() => {
    if (props.allValue.operator === 'BETWEEN') {
        return `开始年份   -   结束年份`
    } else {
        return '选择年份';
    }
})
// watch
watch(
    () => props.modelValue,
    (newV) => {
        console.log(newV,props.modelValue, '---newV');

        // if (newV && Object.keys(newV).length > 0) {
        if (isArray(newV)) {
            modelV.value = newV
        } else {
            console.error('zq-pagelist time 类型 value(modelValue) 值,传入应为 Array 类型')
        }
        // }
    },
    {
        deep: true,
        immediate: true,
    }
)
// 标记日期
const isMarkDay = (y, key) => {
    console.log(y, key, '当前遍历的日期项', y, key);
    let flag = false;
    // console.log('传递过来需要标记的日期项', this.markDays);
    props.markDays.forEach(item => {
        let dy = `${y}`
        if (item == dy) {
            flag = true
        }
    })
    return flag;
}
// // 点击回调
const selectOne = (i, event) => {
    let date = `${i + event}`;
    let selectD = new Date(date).getTime();
    let curTime = new Date().getTime();

    choose.value = date

}
watch(modelV.value, (newV) => {
    emits('yeartimePickermodelValue', newV);
}, {
    deep: true,
    immediate: true,
})

const changeMonth = (type) => {
    if (type == 'pre') {
        currentDataVal.value = currentDataVal.value - 10;
        futureDataVal.value = futureDataVal.value - 10;
    } else {
        currentDataVal.value = currentDataVal.value + 10;
        futureDataVal.value = futureDataVal.value + 10;
    }
}
// 点击确定返回值
const changeValueBtn = () => {
    modelV.value.yearhangeTime = tempYear.value
    // console.log(modelV.value,'---modelV.value');
    const temp = ['']
    // if(modelV.value.operator == 'LE') {
    temp[0] = modelV.value.yearhangeTime
    // }
    emits('update:modelValue', temp);
    zqBodyPopupRef.value.close()

}
// 
const tempYear = ref('')
const onChangeYearItem = (e) => {
    console.log(e, '---onChangeYearItem');
    tempYear.value = e
    // modelV.value.yearhangeTime = e
    // emits('yeartimePickermodelValue', modelV.value);

}
const closeUpper = () => {
    zqBodyPopupRef.value.close();
}
// imitate-input中的clearable属性
const onClearable = () => {
	emits('update:modelValue', ['']);
}
</script>

<style scoped lang="scss">
.year-select {
    :deep(.uni-select) {
        background-color: var(--UI-BG-5);
    }
}


.zq-quicks-checkbox-popup-box {
    position: fixed;
    background-color: #fff;
    z-index: 999;
    right: 0;
    bottom: 0;
    margin-top: 10upx;
    // width: 100%;
    // width: 100vh !important;

    .checkbox-popup-con {
        background-color: rgba(0, 0, 0, 0.4);
        border-radius: 20upx 20upx 0 0;
        margin-bottom: 10upx;
        padding: 20upx;
        box-sizing: border-box;

        :deep(.checkbox__inner) {
            display: none !important;
        }

        :deep(.checklist-box) {
            width: 50% !important;
            display: flex;
            align-items: center;
            height: 3vh;
            margin: 0 !important;
            padding: 0 !important;
        }
    }

}

.uni-date-editor--x .uni-date__icon-clear[data-v-9802168a] {
    padding-right: 3px;
    display: flex;
    align-items: center;
    cursor: pointer;
}

.uni-icons[data-v-d31e1c47] {
    font-family: uniicons;
    text-decoration: none;
    text-align: center
}

.long-popup {
    ::deep .uni-scroll-view-content {
        transform: none !important;
    }
}

.calendar-wrapper {
    // width: 100vw;
    // color: #bbb7b7;
    font-size: 28rpx;
    text-align: center;
    background-color: #fff;
    padding-bottom: 10rpx;

    .header {
        display: flex;
        align-items: center;
        justify-content: center;
        // height: 88rpx;
        color: #42464A;
        font-size: 32rpx;
        font-weight: bold;

        .pre,
        .next {
            color: #4d7df9;
            font-size: 28rpx;
            font-weight: normal;
            padding: 8rpx 15rpx;
            border-radius: 10rpx;
            // border: 2rpx solid #dcdfe6;
        }

        .pre {
            margin-right: 30rpx;
        }

        .next {
            margin-left: 30rpx;
        }
    }
}

.choose {
    background-color: #4d7df9;
    color: #fff;
}

@mixin flex {
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
}

::v-deep.is-input-border[data-v-09fd5285] {
    border: none;
}

.popup-content {
    @include flex;
    align-items: center;
    justify-content: center;
    background-color: #fff;
}

.content {
    position: relative;
    overflow: hidden;
    transition: height 0.4s ease;

    .days {
        transition: top 0.3s;
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        position: relative;

        .item {
            position: relative;
            display: block;
            height: 120rpx;
            line-height: 120rpx;
            width: calc(100% / 4);

            .day {
                font-style: normal;
                display: inline-block;
                vertical-align: middle;
                width: 60rpx;
                height: 60rpx;
                line-height: 60rpx;

                // overflow: hidden;
                // border-radius: 60rpx;
                &.choose {
                    background-color: #4d7df9;
                    color: #fff;
                }
            }
        }
    }
}

.upper-close-icon {
    position: absolute;
    right: 10upx;
    top: 15px;
    z-index: 90;
}
</style>
<template>
    <view class="">
        <view class="zq-imitate-input" @click="toggleContent">
            <text v-if="valueStr.length > 0">{
   
   { valueStr }}</text>
            <text v-else>{
   
   { datePlaceholder }}</text>
            <text v-if="valueStr.length > 0" class="zq-imitate-input-clearable" @click.stop="onClearable">
                <uni-icons type="clear" size="22" color="rgb(192, 196, 204)"></uni-icons>
            </text>
        </view>
        <zqBodyPopup ref="zqBodyPopupRef" :key="'time-popup-'" mode="bottom" :overlayOpacity="0">{
   
   { yearValue }}
            <!-- 关闭按钮 -->
            <uni-icons type="closeempty" size="20" class="upper-close-icon" @click="closeUpper"></uni-icons>
            <YearTimeItem ref="YearTimeItemRef" :yearValue="yearValue" @onChangeSelect="onChangeYearItem"></YearTimeItem>
            <view class="zq-button-group">
                <button>重置</button>
                <button type="primary" @click='changeValueBtn'>确定</button>
            </view>
        </zqBodyPopup>
        
    </view>
</template>

<script lang="ts" setup>
import { ref, reactive, watch, onMounted, computed } from "vue";
import zqBodyPopup from '../../../../zq-body-popup/zq-body-popup.vue'
import YearTimeItem from '../../../../zq-input-year/zq-select-year.vue'
import { isArray } from "../../../../../utils/tool";


const zqBodyPopupRef = ref();
const YearTimeItemRef = ref('')
const open = () => {
    zqBodyPopupRef.value.open();
};

const emits = defineEmits(['update:modelValue', 'yeartimePickermodelValue'])

const props = defineProps({
    quick: {
        type: Object,
        default: () => {
            return {}
        },
    },
    // 标记的日期
    markDays: {
        type: Array,
        default: () => {
            return []; //例如["2023-05-01", "2023-05-03", "2023-04-13"]
        }
    },
    modelValue: {
        type: Object,
        default: () => {
            return {}
        },
    },
    allValue: {
        type: Object,
        default: () => {
            return {}
        },
    },
})
// const localdata = ref([{
//     value: 'LE',
//     text: '小于等于',
// },
// {
//     value: 'GE',
//     text: '大于等于',
// },
// {
//     value: 'EQ',
//     text: '等于',
// },
// ])
const modelV = ref([]);
const popupShow = ref('')
// const zqBodyPopupRef = ref()
const dates = ref([])  // 当前月的日期数据
const currentDataVal = ref('')
const futureDataVal = ref('')
const choose = ref('')
// const valueStr = ref('')
const showUpper = ref(false);
const placeholderStr = ref('请选择年份');
// yeartimeValue.value.operator=
// modelV.value.yearhangeTime = props.quick.modelValue
// modelV.value.operator = props.quick.gl ? props.quick.gl : "GE"
const yearValue = ref('')
const toggleContent = () => {
    // console.log(modelV.value, '===');
    yearValue.value = modelV.value
    choose.value = modelV.value
    let time = choose.value ? new Date(choose.value) : new Date()
    currentDataVal.value = Math.floor(time.getFullYear() / 10) * 10
    futureDataVal.value = currentDataVal.value * 1 + 9

    zqBodyPopupRef.value.open();

    // uni.hideKeyboard();
}
// computed
const valueStr = computed(() => {
    console.log(props.allValue, '---props.allValue');

    if (props.allValue.operator === 'BETWEEN') {
        return props.allValue.rangeValue.join(' 至 ')
    } else {
        return props.allValue.dateValue
    }





    // if (modelV.value) {
    // 	return modelV.value?.join('-')
    // } else {
    // 	return ''
    // }
})
const datePlaceholder = computed(() => {
    if (props.allValue.operator === 'BETWEEN') {
        return `开始年份   -   结束年份`
    } else {
        return '选择年份';
    }
})
// watch
watch(
    () => props.modelValue,
    (newV) => {
        console.log(newV,props.modelValue, '---newV');

        // if (newV && Object.keys(newV).length > 0) {
        if (isArray(newV)) {
            modelV.value = newV
        } else {
            console.error('zq-pagelist time 类型 value(modelValue) 值,传入应为 Array 类型')
        }
        // }
    },
    {
        deep: true,
        immediate: true,
    }
)
// 标记日期
const isMarkDay = (y, key) => {
    console.log(y, key, '当前遍历的日期项', y, key);
    let flag = false;
    // console.log('传递过来需要标记的日期项', this.markDays);
    props.markDays.forEach(item => {
        let dy = `${y}`
        if (item == dy) {
            flag = true
        }
    })
    return flag;
}
// // 点击回调
const selectOne = (i, event) => {
    let date = `${i + event}`;
    let selectD = new Date(date).getTime();
    let curTime = new Date().getTime();

    choose.value = date

}
watch(modelV.value, (newV) => {
    emits('yeartimePickermodelValue', newV);
}, {
    deep: true,
    immediate: true,
})

const changeMonth = (type) => {
    if (type == 'pre') {
        currentDataVal.value = currentDataVal.value - 10;
        futureDataVal.value = futureDataVal.value - 10;
    } else {
        currentDataVal.value = currentDataVal.value + 10;
        futureDataVal.value = futureDataVal.value + 10;
    }
}
// 点击确定返回值
const changeValueBtn = () => {
    modelV.value.yearhangeTime = tempYear.value
    // console.log(modelV.value,'---modelV.value');
    const temp = ['']
    // if(modelV.value.operator == 'LE') {
    temp[0] = modelV.value.yearhangeTime
    // }
    emits('update:modelValue', temp);
    zqBodyPopupRef.value.close()

}
// 
const tempYear = ref('')
const onChangeYearItem = (e) => {
    console.log(e, '---onChangeYearItem');
    tempYear.value = e
    // modelV.value.yearhangeTime = e
    // emits('yeartimePickermodelValue', modelV.value);

}
const closeUpper = () => {
    zqBodyPopupRef.value.close();
}
// imitate-input中的clearable属性
const onClearable = () => {
	emits('update:modelValue', ['']);
}
</script>

<style scoped lang="scss">
.year-select {
    :deep(.uni-select) {
        background-color: var(--UI-BG-5);
    }
}


.zq-quicks-checkbox-popup-box {
    position: fixed;
    background-color: #fff;
    z-index: 999;
    right: 0;
    bottom: 0;
    margin-top: 10upx;
    // width: 100%;
    // width: 100vh !important;

    .checkbox-popup-con {
        background-color: rgba(0, 0, 0, 0.4);
        border-radius: 20upx 20upx 0 0;
        margin-bottom: 10upx;
        padding: 20upx;
        box-sizing: border-box;

        :deep(.checkbox__inner) {
            display: none !important;
        }

        :deep(.checklist-box) {
            width: 50% !important;
            display: flex;
            align-items: center;
            height: 3vh;
            margin: 0 !important;
            padding: 0 !important;
        }
    }

}

.uni-date-editor--x .uni-date__icon-clear[data-v-9802168a] {
    padding-right: 3px;
    display: flex;
    align-items: center;
    cursor: pointer;
}

.uni-icons[data-v-d31e1c47] {
    font-family: uniicons;
    text-decoration: none;
    text-align: center
}

.long-popup {
    ::deep .uni-scroll-view-content {
        transform: none !important;
    }
}

.calendar-wrapper {
    // width: 100vw;
    // color: #bbb7b7;
    font-size: 28rpx;
    text-align: center;
    background-color: #fff;
    padding-bottom: 10rpx;

    .header {
        display: flex;
        align-items: center;
        justify-content: center;
        // height: 88rpx;
        color: #42464A;
        font-size: 32rpx;
        font-weight: bold;

        .pre,
        .next {
            color: #4d7df9;
            font-size: 28rpx;
            font-weight: normal;
            padding: 8rpx 15rpx;
            border-radius: 10rpx;
            // border: 2rpx solid #dcdfe6;
        }

        .pre {
            margin-right: 30rpx;
        }

        .next {
            margin-left: 30rpx;
        }
    }
}

.choose {
    background-color: #4d7df9;
    color: #fff;
}

@mixin flex {
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
}

::v-deep.is-input-border[data-v-09fd5285] {
    border: none;
}

.popup-content {
    @include flex;
    align-items: center;
    justify-content: center;
    background-color: #fff;
}

.content {
    position: relative;
    overflow: hidden;
    transition: height 0.4s ease;

    .days {
        transition: top 0.3s;
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        position: relative;

        .item {
            position: relative;
            display: block;
            height: 120rpx;
            line-height: 120rpx;
            width: calc(100% / 4);

            .day {
                font-style: normal;
                display: inline-block;
                vertical-align: middle;
                width: 60rpx;
                height: 60rpx;
                line-height: 60rpx;

                // overflow: hidden;
                // border-radius: 60rpx;
                &.choose {
                    background-color: #4d7df9;
                    color: #fff;
                }
            }
        }
    }
}

.upper-close-icon {
    position: absolute;
    right: 10upx;
    top: 15px;
    z-index: 90;
}
</style>
<template>
    <view class="time-box">
        <uni-data-select v-model="modelValue.operator" :localdata="curOperator" :clear="false" class="operator-select" />
        <dateTpl v-if="comb.type === 'date'" :modelValue="modelValue.value" @update:modelValue="changeValue"
            :allValue="modelValue" :quick="comb" class="time-content-box" />
        <yearTpl v-else-if="comb.type === 'year'" :modelValue="modelValue.value" @update:modelValue="changeValue"
            :allValue="modelValue" :quick="comb" class="time-content-box" />
    </view>
</template>

<script setup>
import { ref, watch, getCurrentInstance } from 'vue'
import dateTpl from './date-time/datetimePicker.vue'
import yearTpl from './year/yearTimePickchange.vue'
const operatorData_Base = [
    {
        value: 'LE',
        text: '小于等于',
    },
    {
        value: 'GE',
        text: '大于等于',
    },
    {
        value: 'EQ',
        text: '等于',
    },
    {
        value: 'BETWEEN',
        text: '介于',
    }
];

const props = defineProps({
    //v-model
    modelValue: {
        type: Object,
        default: function () {
            return {}
        },
    },
    comb: {
        type: Object,
        default: function () {
            return {}
        },
    },
});
const emits = defineEmits(['update:modelValue'])

const curOperator = ref([]); // 下拉框可选项
const init = () => {
    console.log(props, '---props.comb.operatorOptions');
    // 日期 和 年 都包含 between
    if (props.comb.operatorOptions) {
        curOperator.value = props.comb.operatorOptions;
    } else {
        // 可配置 选择项
        curOperator.value = operatorData_Base.slice();
    }
    // 父传子,数据回显
    if (props.modelValue.dateValue) {
        props.modelValue.value[0] = props.modelValue.dateValue
    }
    // modelV.value = Object.assign({}, props.modelValue)
}
init();
const changeValue = (valueArr) => {
    let tempObj = Object.assign({}, props.modelValue);
    if (props.modelValue.operator === 'BETWEEN') {
        tempObj.rangeValue = valueArr;
    } else {
        tempObj.dateValue = valueArr[0]
    }
    tempObj.value = valueArr;
    emits('update:modelValue', tempObj);
}


</script>

<style lang="scss" scoped>
.time-box {
    display: flex;

    .operator-select {
        max-width: 30%;
        margin: 0 3%;
    }

    .time-content-box {
        width: 61%;
        margin-right: 3%;
    }


    :deep .uni-select {
        background-color: #fff;
    }
}
</style>

猜你喜欢

转载自blog.csdn.net/irisMoon06/article/details/133852649
今日推荐