vue3+ts 实现简单日历 周和月的样式

一:周选择器   

 vue代码如下:

        <div class="calendar-body" v-if="viewType == 'week'">
            <div class="calendar-module-item" v-for="(_item, _index) in currentWeekList" :key="_index">
              <div class="week-normal">
                <div :class="[_item.select ? 'select-day' : '']">
                  <div class="calendar-head-item">{{ _item.label }}</div>
                  <div class="day" @click="dayClickHandle(_item)">{{ _item.day }}</div>
                </div>
              </div>
            </div>
          </div>

样式部分:

    .calendar {
      background: #fff;
      // 周选择样式
      .calendar-body {
        display: flex;
        align-items: center;
        justify-content: space-around;
        .calendar-module-item {
          position: relative;
          width: 7%;
          height: 5em;
          text-align: center;
          line-height: 35px;

          &:not(:last-child) {
            margin-right: 1px;
          }

          .week-normal {
            height: 30px;
            color: #666666;
            align-items: center;
            justify-content: space-around;
          }
          .select-day {
            background-color: #1866fe;
            width: 100%;
            border-radius: 20px 20px 20px 20px;
            height: 230%;
            color: #fff;
          }
          .day {
            font-size: 14px;
            font-weight: 600;
            padding-bottom: 1%;
            cursor: pointer;
          }
        }
      }
}

ts代码:

    const state = reactive({
      viewType: 'week',  // 切换周或者月选择器
      currentMonth: '',  // 当前月份展示 
      isToday: true,  // 是否今日 
      currentWeekList: [],  //周数据
      typeOptions: [
        { label: '周', value: 'week' }, { label: '月', value: 'month' }
      ],
      dataListMonth: [],
      WeekNum: [
        { label: "日", value: 0, fullName: "星期日" },
        { label: "一", value: 1, fullName: "星期一" },
        { label: "二", value: 2, fullName: "星期二" },
        { label: "三", value: 3, fullName: "星期三" },
        { label: "四", value: 4, fullName: "星期四" },
        { label: "五", value: 5, fullName: "星期五" },
        { label: "六", value: 6, fullName: "星期六" },
      ],
    } as any); 

 //获取这周的时间数据
    const getCurrentWeek = (time: any) => {
      const dateTime = new Date(time);
      const Date2 = dateTime.getTime(); //毫秒数
      const weekList = new Array(6); //放置周数据
      const day2week = ['日', '一', '二', '三', '四', '五', '六'];
      const week = dateTime.getDay(); //获取传入的time日期为星期几
      const dayTime = 3600 * 24 * 1000; //一天的毫秒数
      for (let i = 0; i <= 6; i++) {
        weekList[i] = {
          label: day2week[i],
          day: new Date(Date2 - (week - i) * dayTime).getDate(),
          select: (week - i) * dayTime === 0,
        };
      }
      return weekList;
    };
    const putListToWeek = () => {
      const date = getFormatterDate(new Date());
      state.currentWeekList = getCurrentWeek(date);
    };

 onMounted(() => {
    putListToWeek();
    });

二:月选择器

vue代码如下:

 <!-- 月数据 -->
          <div class="calendar-body-month" v-else>
            <div class="week">
              <div class="calendar-month-item" v-for="(key, _index) in WeekNum" :key="_index">{{ key.label }}</div>
            </div>
            <div class="day">
              <div class="day-item" v-for="(item, ind) in dataListMonth" :key="ind">
                <div class="day" :class="[val.select ? 'select-day-item' : '']" v-for="(val, index) in item" @click="dayClickHandle(val)" :key="index">{{ val.day }}</div>
              </div>
            </div>
          </div>

 css样式:

     // 月选择样式
      .calendar-body-month {
        width: 100%;
        .week {
          width: 100%;
          display: flex;
          align-items: center;
          justify-content: space-around;
          margin-bottom: 1.5%;
          .calendar-month-item {
            position: relative;
            width: 7%;
            height: 2em;
            text-align: center;
            line-height: 35px;
          }
        }
        .day {
          // width: 100%;
          .day-item {
            display: flex;
            align-items: center;
            justify-content: space-around;
            width: 100%;
            .day {
              text-align: center;
              width: 20%;
              margin-bottom: 1.2%;
              cursor: pointer;
              height: 2em;
              line-height: 2em;
              color: #666666;
              font-size: 14px;
              font-weight: 600;
            }
            .select-day-item {
              background-color: #1866fe;
              border-radius: 20px 20px 20px 20px;
              color: #fff;
            }
          }
        }
      }

ts代码:

  // 获取本月的时间数据
    const getCurrentMonth = (year: any, month: any) => {
      var stratDate: any = new Date(year, month - 1, 1),
        endData: any = new Date(year, month, 1);
      var days = (endData - stratDate) / (1000 * 60 * 60 * 24);
      var list = []
      for (var i = 1; i <= days; i++) {
        const d = i
        const day = d
        const week =
          new Date(month + '/' + i + '/' + year).getDay() == 0 ? '日' : new Date(month + '/' + i + '/' + year).getDay() == 1 ? '一' : new Date(month + '/' + i + '/' + year).getDay() == 2 ? '二' : new Date(month + '/' + i + '/' + year).getDay() == 3 ? '三' : new Date(month + '/' + i + '/' + year).getDay() == 4 ? '四' : new Date(month + '/' + i + '/' + year).getDay() == 5 ? '五' : new Date(month + '/' + i + '/' + year).getDay() == 6 ? '六' : ''
        list.push({
          day,
          week,
          d,
          select: false,
        })
        state.dataListMonth = list
      }


      // 获取某月第一天对应的星期几
      let currentIndex = state.WeekNum.findIndex((item: any) => item.label == state.dataListMonth[0].week);
      // 往总天数中添加currentIndex个对象用于错位
      let addList = Array.from({ length: currentIndex }).map((_, index) => {
        return {
          d: "",
          day: "",
          week: "",
          select: false,
        }
      });
      // 合并
      let mergeArr = [...addList, ...state.dataListMonth];
      let resultList = [];
      let index = 0;
      // 将数组分为长度为7的数组方便页面循环
      while (index < days) {
        resultList.push(mergeArr.slice(index, index += 7));
      }
      state.dataListMonth = resultList;
      if (state.dataListMonth[state.dataListMonth.length - 1].length < 7) {
        do {
          state.dataListMonth[state.dataListMonth.length - 1].push({
            d: "",
            day: "",
            week: "",
            select: false,
          })
        } while (state.dataListMonth[state.dataListMonth.length - 1].length < 7);
      }
    };

   onMounted(() => {
      // 获取本月时间
      var date = new Date();
      var year = date.getFullYear(); //获取完整的年份(4位)
      var month1 = date.getMonth() + 1; //获取当前月份(0-11,0代表1月)
      getCurrentMonth(year, month1)//传入参数年和月
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3 + TypeScript 中,实现切换日历日期动态渲染对应数据可以使用 Vue3 的 Composition API 和 TypeScript 的类型检查功能。 具体实现步骤如下: 1. 创建一个日历组件,通过 props 属性传递选中的日期,同时定义一个 data 属性用于存储获取到的数据。 ```typescript <template> <div> <calendar :selectedDate="selectedDate" @change="handleChange" /> <div v-for="item in data" :key="item.id">{{ item.title }}</div> </div> </template> <script lang="ts"> import { defineComponent, ref } from 'vue'; import { getSomeData } from '@/api'; export default defineComponent({ name: 'CalendarDemo', props: { selectedDate: { type: Date, required: true, }, }, setup(props) { const data = ref([]); const handleChange = async (date: Date) => { const res = await getSomeData(date); data.value = res.data; }; return { data, handleChange, }; }, }); </script> ``` 2. 在日历组件中,当用户选择日期时,触发 change 事件,并将选中的日期作为参数传递给事件处理函数。 ```typescript <template> <div> <input type="date" v-model="date" @change="handleChange" /> </div> </template> <script lang="ts"> import { defineComponent, watch } from 'vue'; export default defineComponent({ name: 'Calendar', props: { selectedDate: { type: Date, required: true, }, }, setup(props, { emit }) { const date = ref(props.selectedDate.toISOString().slice(0, 10)); watch( () => props.selectedDate, (val) => { date.value = val.toISOString().slice(0, 10); }, ); const handleChange = () => { const selectedDate = new Date(date.value); emit('change', selectedDate); }; return { date, handleChange, }; }, }); </script> ``` 3. 在事件处理函数中,调用后端 API 获取对应日期的数据,并更新 data 属性的值。 ```typescript const handleChange = async (date: Date) => { const res = await getSomeData(date); data.value = res.data; }; ``` 4. 在组件中使用 ref 和 reactive 来定义响应式数据,使用 watch 来监听 props 或响应式数据的变化,并在变化时执行相应的操作。 ```typescript const data = ref([]); watch( () => props.selectedDate, (val) => { fetchData(val); }, ); const fetchData = async (date: Date) => { const res = await getSomeData(date); data.value = res.data; }; ``` 以上是 Vue3 + TypeScript 实现切换日历日期动态渲染对应数据的示例代码,具体实现方式可能因为业务需求而有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值