1、需求:在主页面中点击新增按钮,弹出弹窗,此时弹窗中有一个确定按钮,需实现该确定按钮在当天0点前指点点击2次,超过2次置灰,过了零点复原。
思路:首先弹窗通过v-if显示与隐藏弹窗子组件,使用父传子及子传父将弹窗弹窗开启关闭标识符来控制弹窗的开启与关闭。
第二步:针对一天内按钮只能点击2次需求,首先我们要拿到当前的系统日期及明天日期,并转化为“2024-09-01”格式,为后续通过Date.parse()转化为总毫秒数做对比,来实现点击次数,但此时容易忽略一个问题,即弹窗是通过v-if实现的,每一次进来都会重新渲染,在子组件中定义的点击次数变量会清零,所以此时需要进行状态管理,这里使用的是pinia来实现的,将点击次数等数据存储在pinia中,然后在弹窗组件中使用即可。(也可通过将点击次数数据存储在本地存储中,通过判断本地存储中有无点击次数来判断起始数字即可)
第三步:针对过0点之后复原问题。同样的在pinia中获取当前系统日期,并在组件中将上一次点击时的“明天日期”存储在pinia中,然后在pinia中写方法进行比对,当二者一致时,进行复原即可。(这里应计算大于等于,后续优化)
按钮置灰同样道理。
2、父组件
<a-button class="btn" type="primary" @click="add">新增</a-button>
<modal v-if="openFlag == true" :openFlag="openFlag" @close="handle"></modal>import { ref } from 'vue';
import modal from '@/layout/SpecialFaceToFace/modal/modal.vue';
// 新增
let openFlag = ref(false);
function add() {openFlag.value = true;
}
3、子组件
<template><!-- 弹窗 --><a-modal v-model:open="open" title="分配信息" :closable="closable"><!-- 底部自定义按钮 --><template #footer><a-button key="back" @click="handleCancel">取消</a-button><a-button key="submit" type="primary" @click="handleOk" :disabled="useStore.isDisabled">确定</a-button></template></a-modal>
</template><script lang="ts" setup>import { ref, defineProps, defineEmits, onMounted } from 'vue';import { useSpecialStore } from '@/store/modules/SpecialModal';const useStore = useSpecialStore();// 取消弹窗叉号let closable = false;// 接收弹窗开启标识const re = defineProps(['openFlag']);const emits = defineEmits(['close']);onMounted(() => {// 开启弹窗open.value = re.openFlag;// 实现第二天确认按钮点击次数及置灰复原useStore.compareDay();});// 日期处理比较const getTomorrowDate = () => {const today = new Date();// 格式化当天日期const newTotade = today.toISOString().split('T')[0]; //"2024-08-31"// 获取明天日期// 创建一个新的日期对象const tomorrow = new Date(today);tomorrow.setDate(tomorrow.getDate() + 1); //"2024-08-31T14:15:30.000Z"const newTomorrow = tomorrow.toISOString().split('T')[0]; //"2024-08-31"if (Date.parse(newTotade) < Date.parse(newTomorrow) && useStore.clickCount < 2) {useStore.clickCount++;console.log('次数', useStore.clickCount);useStore.useTomorrow = newTomorrow;} else {message.warning('一天内只能点击2次');// 确定按钮置灰useStore.isDisabled = true;}};// 确定事件const handleOk = () => {// 点击次数控制getTomorrowDate();open.value = false;// 将关闭标识传给父组件emits('close', open.value);};// 取消事件const handleCancel = () => {open.value = false;// 将关闭标识传给父组件emits('close', open.value);};
</script>
4、pinia
import { defineStore } from 'pinia';
import { ref } from 'vue';
export const useSpecialStore = defineStore('SpecialModal', () => {// 弹窗确认按钮点击次数const clickCount = ref(0);// 确定按钮是否只读const isDisabled = ref(false);// 存储的是昨天的明天日期const useTomorrow = ref('');// 复原确认按钮点击次数及置灰const compareDay = () => {// 获取当前日期const day = new Date();// 格式化当天日期const newDay = day.toISOString().split('T')[0]; //"2024-09-01"if (Date.parse(useTomorrow.value) <= Date.parse(newDay)) {clickCount.value = 0;isDisabled.value = false;} else {return;}};return {clickCount,isDisabled,useTomorrow,compareDay,};
});