vue3+vite+tdesign實現(xiàn)日歷式可編輯的排課班表填寫功能
近期,在項目開發(fā)中,我們面臨實現(xiàn)一個日歷式、可編輯排班填寫功能的需求。初步方案采用tdesign的Calendar組件,盡管其支持編輯功能,但在提取每日排班信息時操作繁瑣,因此該方案被棄用。隨后,我們決定自主研發(fā)該功能,盡管看似直觀,開發(fā)過程中仍面臨諸多挑戰(zhàn)。本文旨在總結(jié)此次開發(fā)經(jīng)歷,希望對有類似需求的開發(fā)者有所幫助。
本篇文章開發(fā)環(huán)境的安裝就不進行詳細闡述,著重闡述如何使用vue3+tdesign實現(xiàn)日歷式可編輯的排班填寫功能。
一、安裝tdesign
使用npm安裝
npm i tdesign-vue-next
二、實現(xiàn)年份、月份下拉框
對于年份和月份下拉框選擇,這里未使用tdesign自帶的日期選擇組件,但使用了他的select下拉框組件,另外這里還使用到了dayjs,用于獲取不同年份。
1.安裝dayjs
npm install dayjs
2.年份下拉框樣式
這個實現(xiàn)起來比較簡單一些,其實就是使用tdesign的select選擇器這個組件就行。
<template> <div class="calender-top"> <t-select v-model="year" :options="optionsYear" clearable size="medium" @change="handleYearChange" style="width: 5vw; margin-right: 1vw" /> </div> </template> <script setup> import { ref, getCurrentInstance, onMounted, computed } from 'vue' //當前年份 const year = ref('') //所有年份 const optionsYear = ref([]) //選擇年份 const handleYearChange = val => {} </script> <style lang="less" scoped> .calender-top { display: flex; align-items: center; justify-content: flex-end; padding: 1vw 0; :deep .t-popup__content { width: 5vw !important; } :deep .t-input__inner { text-align: center; font-size: 0.8vw; } } </style>
3.獲取所有年份
以上代碼中只是實現(xiàn)了下拉框的具體樣式,其實下拉框的內(nèi)容還是空的,下面就是如何使用dayjs實現(xiàn)獲取所有的年份。因為要求在剛進行頁面時需顯示當前年份,所以在v-model綁定的year這里,就需要使用dayjs來獲取目前所處的年份,具體如下:
//這個代碼十分重要,沒有這個dayjs無法使用 const context = getCurrentInstance()?.appContext.config.globalProperties const dayjs = context?.$dayjs //當前年份 const year = ref(dayjs().format('YYYY年'))
獲取所有年份這里具體寫了一個方法,大概得步驟就是,首先先寫一個生成年份數(shù)組的方法,然后確定當前的年份,規(guī)定一下過去的年份和未來年份數(shù)量,使用剛剛的方法進行加減即可,具體代碼如下:
// 生成年份數(shù)組的函數(shù) const generateYears = (startYear, endYear) => { const years = [] for (let i = startYear; i <= endYear; i++) { years.push({ label: `${i}年`, value: i }) } return years } //獲取當前年份-月份的數(shù)據(jù) const getYearData = () => { //當前年份 const currentYear = dayjs().year() // 過去的年份數(shù)量 const pastYears = 30 // 未來的年份數(shù)量 const futureYears = 50 optionsYear.value = generateYears(currentYear - pastYears, currentYear + futureYears) // console.log(optionsYear.value, '年份') } onMounted(() => { getYearData() })
4.獲取月份
獲取月份這里我未使用以上方式進行開發(fā),因為月份數(shù)據(jù)涉及的少,所以在前端這里我寫了一個JSON數(shù)據(jù),直接進行復(fù)用即可,另外樣式和年份的差不多,具體如下:
<template> <div class="calender-top"> <t-select v-model="year" :options="optionsYear" clearable size="medium" @change="handleYearChange" style="width: 5vw; margin-right: 1vw" /> <t-select v-model="month" :options="optionsMonth" clearable size="medium" @change="handleMonthChange" style="width: 5vw; margin-right: 1vw" /> </div> </template> <script setup> import { ref, getCurrentInstance, onMounted, computed } from 'vue' import { monthList } from '@/utils/year-month.js' //當前月份 const month = ref(dayjs().format('MM月')) //所有月份 const optionsMonth = ref([]) //選擇月份 const handleMonthChange = val => {} //獲取當前年份-月份的數(shù)據(jù) const getYearData = () => { optionsMonth.value = monthList } onMounted(() => { getYearData() }) </script>
monthList的具體數(shù)據(jù)顯示如下:
//規(guī)定月份列表 export const monthList = [ { label: '1月', value:'01' }, { label: '2月', value:'02' }, { label: '3月', value:'03' }, { label: '4月', value:'04' }, { label: '5月', value:'05' }, { label: '6月', value:'06' }, { label: '7月', value:'07' }, { label: '8月', value:'08' }, { label: '9月', value:'09' }, { label: '10月', value:'10' }, { label: '11月', value:'11' }, { label: '12月', value:'12' } ]
三、周期顯示
上述闡述了年份和月份下拉框的實現(xiàn),做日歷的話還缺少周期數(shù),接下來是實現(xiàn)具體的周期,這個樣式的話相對來說比較簡單,涉及到flex布局、ul和li列表,另外周期數(shù)據(jù)其實也是固定的,和月份一樣也是做了一個JSON數(shù)據(jù)。
//規(guī)定周期列表 export const weekList = [ { label: '一', value:'1' }, { label: '二', value:'2' }, { label: '三', value:'3' }, { label: '四', value:'4' }, { label: '五', value:'5' }, { label: '六', value:'6' }, { label: '日', value:'7' } ]
以下是具體樣式
<template> <ul class="canlder-weekList"> <li class="item-top" v-for="(item, index) in optionWeek" :key="index"> <h1>{{ item.label }}</h1> </li> </ul> </template> <script setup> import { ref, getCurrentInstance, onMounted, computed } from 'vue' import { weekList } from '@/utils/year-month.js' //所有星期 const optionWeek = ref([]) //獲取當前周期的數(shù)據(jù) const getYearData = () => { optionWeek.value = weekList } onMounted(() => { getYearData() }) </script> <style lang="less" scoped> .canlder-weekList { display: flex; align-items: center; // justify-content: space-between; // padding: 0 1vw; padding: 0.5vw 0 0 1vw; .item-top { // display: flex; width: 6vw; margin: 1vw 0.6vw 0 0; h1 { text-align: center; font-size: 1.2vw; font-weight: 500; color: #333; } } } </style>
四、可編輯日歷
接下來就是本篇中重要內(nèi)容了,首先先來實現(xiàn)日歷的具體樣式,他的需求功能是,每天中對應(yīng)一個下拉框,下來框是可選擇排班的人員,然后下方就是對應(yīng)的日期天數(shù)。下方是具體代碼:
<template> <div class="canlder-dayList"> <div class="item-list" v-for="(item, index) in dayList" :key="index"> <!-- <div class="name name-color">{{ item.name }}</div> --> <t-select v-model="item.name" clearable size="medium" @change="handleStuffChange($event, index)" :options="optionsName" class="name name-color" /> <!-- <div class="number number-color">{{ item.date.slice(8, 10) }}</div> --> <div class="number number-color">{{ dayjs(item.date).format('DD') }}</div> </div> </div> </template> <script setup> import { ref, getCurrentInstance, onMounted, computed } from 'vue' const dayList = ref([]) //所有人員 const optionsName = ref([]) //當前選擇人員 const handleStuffChange = (value, index) => {} onMounted(() => {}) </script> <style lang="less" scoped> .canlder-dayList { // width: 15%; display: flex; // flex-direction: column; align-items: center; justify-content: flex-start; flex-wrap: wrap; padding: 0.5vw 0 0 0.8vw; .item-list { width: 6vw; margin: 1vw 0.6vw 0 0; display: flex; flex-direction: column; align-items: center; justify-content: center; .name, .number { width: 5vw; height: 2.5vw; font-size: 0.8vw; line-height: 2.5vw; text-align: center; } .name-color { color: #333; background-color: #d8d8d8; // background-color: rgb(216, 250, 200); } .number-color { color: #fff; background-color: rgb(116, 159, 178); // background-color: rgb(138, 189, 114); } :deep .t-input { // background-color: rgb(216, 250, 200); background-color: #d8d8d8; } :deep .t-input__inner { font-size: 0.8vw; text-align: center; } } } </style>
1.獲取下拉框值班人員數(shù)據(jù)
上述代碼寫完我們會發(fā)現(xiàn),頁面上其實啥也沒有,具體原因是源于還沒做數(shù)據(jù)的獲取,接下來就是如何獲取下來框值班人,因為我這里的axios是進行了封裝之后的,所以這里我展示獲取數(shù)據(jù)的方式僅用了具體的方法。
<script setup> import { ref, getCurrentInstance, onMounted, computed } from 'vue' import { getAllDutyPerson, getMonthDutyPerson, modifyDutyPerson } from '@/api/schedule-write.js' const dayList = ref([]) //所有人員 const optionsName = ref([]) //當前選擇人員 const handleStuffChange = (event, itemIndex) => { const selectedValue = event // console.log(selectedValue, '選擇人員') const selectedOption = optionsName.value.find(option => option.value === selectedValue) // console.log(selectedOption, '所選人員') dayList.value[itemIndex].name = selectedOption.label dayList.value[itemIndex].id = selectedOption.id } //獲取所有值班人員--下拉框 const getAllDutyPersonData = params => { return new Promise((resolve, reject) => { getAllDutyPerson(params) .then(res => { if (res.code === 200 && res.data) { // console.log(res, '這是:') optionsName.value = res.data.map(item => { return { id: item.id, label: item.name, value: item.name } }) console.log(optionsName.value, '人員') } }) .catch(error => { reject(error) }) }) } onMounted(() => { getAllDutyPersonData() })
2.獲取每天值班人
這個步驟應(yīng)該是上述方案之前的,在開發(fā)時記得先做這個步驟,然后再開始獲取下拉框的數(shù)據(jù)。因為這個步驟沒做好頁面上是啥也看不到的,接下來我們就開始吧
<script setup> import { ref, getCurrentInstance, onMounted, computed } from 'vue' import { getAllDutyPerson, getMonthDutyPerson, modifyDutyPerson } from '@/api/schedule-write.js' const dayList = ref([]) // 當前年月入?yún)? const yearMonthPara = ref(dayjs().format('YYYY-MM')) //當前月份的天數(shù) const currentMonth = ref(dayjs().month()) //當前年份 const currentYear = ref(dayjs().year()) //處理當前月份天數(shù)和當前年份 const daysInMonth = ref(dayjs(`${currentYear}-${currentMonth + 1}-01`).daysInMonth()) const dayOption = ref( Array.from({ length: daysInMonth }, (_, index) => ({ name: '', date: dayjs(`${currentYear}-${currentMonth + 1}-${index + 1}`).format('YYYY-MM-DD') })) ) //獲取當前月份所有值班人員 const getMonthDutyPersonData = params => { return new Promise((resolve, reject) => { getMonthDutyPerson(params) .then(res => { if (res.code === 200 && res.data) { // console.log(res, '當月:') const mergedList = [] // 遍歷 dayOption 數(shù)組 dayOption.value.forEach(dayOpt => { const matchedData = res.data.find(dataItem => { return dayOpt.date === dataItem.date }) mergedList.push({ ...dayOpt, ...(matchedData ? { name: matchedData.name } : { name: '' }), ...(matchedData ? { id: matchedData.id } : {}) }) }) // 將合并后的數(shù)組賦值給 dayList.value dayList.value = mergedList console.log(dayList.value, '當月值班人員') } }) .catch(error => { reject(error) }) }) } onMounted(() => { getMonthDutyPersonData(yearMonthPara.value) })
3.處理選擇每個年份、月份所對應(yīng)的周期及天數(shù)
做完了以上的東西后,我們就可以在頁面中看到日歷了,但是在選擇每個年份和月份后我們會發(fā)現(xiàn)下面所對應(yīng)的天數(shù)一直都是當月的天數(shù),比如我當前月份是一月,有三十一天,但是我在選擇2月份后他的天數(shù)依舊31天,但實際上2月份只有28天,另外他的每個一號都是對應(yīng)在周一,其實這是不對的,存在一定的bug。接下來就來解決這個問題。
<script setup> import { ref, getCurrentInstance, onMounted, computed } from 'vue' import { getAllDutyPerson, getMonthDutyPerson, modifyDutyPerson } from '@/api/schedule-write.js' // 定義一個函數(shù)來獲取指定日期的第一天是星期幾 const getWeekdayOfFirstDay = date => { const firstDayOfMonth = dayjs(date).startOf('month') return firstDayOfMonth.day() // 返回星期幾(0-6,0表示星期日) } // 定義一個函數(shù)來獲取指定日期的最后一天是星期幾 const getCurrentCal = () => { currentMonth.value = dayjs().month() currentYear.value = dayjs().year() daysInMonth.value = dayjs(`${currentYear.value}-${currentMonth.value + 1}-01`).daysInMonth() dayOption.value = Array.from({ length: daysInMonth.value }, (_, index) => ({ name: '', date: dayjs(`${currentYear.value}-${currentMonth.value + 1}-${index + 1}`).format('YYYY-MM-DD') })) const specifiedDate = ref(`${year.value.toString().slice(0, 4)}-${month.value.toString().slice(0, 2)}-01`) // 使用 Day.js 解析日期并獲取該月份的第一天 const firstDayOfMonth = dayjs(specifiedDate.value).startOf('month').format('YYYY-MM-DD') console.log(firstDayOfMonth, '獲取該月份的第一天') if (dayOfWeekFirst.value == 0) { dayOfWeekFirst.value = 7 } dayOfWeekFirst.value = getWeekdayOfFirstDay(firstDayOfMonth) console.log(dayOfWeekFirst.value, '獲取該月份的第一天是星期幾') } onMounted(() => { getCurrentCal() })
以上的問題寫了一個解決方法,我們還需要再點擊選擇年份和月份的點擊事件中進行修改
//選擇年份 const handleYearChange = val => { console.log(val, '選擇年份') year.value = val currentYear.value = parseInt(year.value.toString().slice(0, 4)) currentMonth.value = parseInt(month.value.toString().slice(0, 2)) - 1 daysInMonth.value = dayjs(`${currentYear.value}-${currentMonth.value + 1}-01`).daysInMonth() dayOption.value = Array.from({ length: daysInMonth.value }, (_, index) => ({ name: '', date: dayjs(`${currentYear.value}-${currentMonth.value + 1}-${index + 1}`).format('YYYY-MM-DD') })) console.log(dayOption.value, '所選當月的日期~~~選擇年份') const specifiedDate = ref(`${year.value.toString().slice(0, 4)}-${month.value.toString().slice(0, 2)}-01`) // const specifiedDate = ref('2025-04-15'); // 使用 Day.js 解析日期并獲取該月份的第一天 const firstDayOfMonth = dayjs(specifiedDate.value).startOf('month').format('YYYY-MM-DD') console.log(firstDayOfMonth, '獲取該月份的第一天') dayOfWeekFirst.value = getWeekdayOfFirstDay(firstDayOfMonth) if (dayOfWeekFirst.value == 0) { dayOfWeekFirst.value = 7 } yearMonthPara.value = `${year.value.toString().slice(0, 4)}-${month.value.toString().slice(0, 2)}` console.log(yearMonthPara.value, '年月') //這里需要調(diào)用次方法 getMonthDutyPersonData(yearMonthPara.value) } //選擇月份 const handleMonthChange = val => { console.log(val, '選擇月份') month.value = val currentYear.value = parseInt(year.value.toString().slice(0, 4)) currentMonth.value = parseInt(month.value.toString().slice(0, 2)) - 1 daysInMonth.value = dayjs(`${currentYear.value}-${currentMonth.value + 1}-01`).daysInMonth() dayOption.value = Array.from({ length: daysInMonth.value }, (_, index) => ({ name: '', date: dayjs(`${currentYear.value}-${currentMonth.value + 1}-${index + 1}`).format('YYYY-MM-DD') })) console.log(dayOption.value, '所選當月的日期~~~選擇年份') const specifiedDate = ref(`${year.value.toString().slice(0, 4)}-${month.value.toString().slice(0, 2)}-01`) // const specifiedDate = ref('2025-04-15'); // 使用 Day.js 解析日期并獲取該月份的第一天 const firstDayOfMonth = dayjs(specifiedDate.value).startOf('month').format('YYYY-MM-DD') console.log(firstDayOfMonth, '獲取該月份的第一天') dayOfWeekFirst.value = getWeekdayOfFirstDay(firstDayOfMonth) if (dayOfWeekFirst.value == 0) { dayOfWeekFirst.value = 7 } yearMonthPara.value = `${year.value.toString().slice(0, 4)}-${month.value.toString().slice(0, 2)}` getMonthDutyPersonData(yearMonthPara.value) }
接下來還需要修改的一個地方就是樣式的綁定
<div class="canlder-dayList"> <div class="item-list" :style="index === 0 ? `margin-left: ${(dayOfWeekFirst - 1) * 6.6}vw` : ''" v-for="(item, index) in dayList" :key="index" > <!-- <div class="name name-color">{{ item.name }}</div> --> <t-select v-model="item.name" clearable size="medium" @change="handleStuffChange($event, index)" :options="optionsName" class="name name-color" /> <!-- <div class="number number-color">{{ item.date.slice(8, 10) }}</div> --> <div class="number number-color">{{ dayjs(item.date).format('DD') }}</div> </div> </div> // 每個月的第一天 const dayOfWeekFirst = ref(0)
五、全部代碼、效果展示
綜上實現(xiàn)可編輯日歷的具體步驟就結(jié)束了,下面附上全部代碼
<template> <div class="middle-content"> <div class="calender-top"> <t-select v-model="year" :options="optionsYear" clearable size="medium" @change="handleYearChange" style="width: 5vw; margin-right: 1vw" /> <t-select v-model="month" :options="optionsMonth" clearable size="medium" @change="handleMonthChange" style="width: 5vw; margin-right: 1vw" /> </div> <ul class="canlder-weekList"> <li class="item-top" v-for="(item, index) in optionWeek" :key="index"> <h1>{{ item.label }}</h1> </li> </ul> <div class="canlder-dayList"> <div class="item-list" :style="index === 0 ? `margin-left: ${(dayOfWeekFirst - 1) * 6.6}vw` : ''" v-for="(item, index) in dayList" :key="index" > <!-- <div class="name name-color">{{ item.name }}</div> --> <t-select v-model="item.name" clearable size="medium" @change="handleStuffChange($event, index)" :options="optionsName" class="name name-color" /> <!-- <div class="number number-color">{{ item.date.slice(8, 10) }}</div> --> <div class="number number-color">{{ dayjs(item.date).format('DD') }}</div> </div> </div> </div> </template> <script setup> import { ref, getCurrentInstance, onMounted, computed } from 'vue' import { monthList, weekList } from '@/utils/year-month.js' import { getAllDutyPerson, getMonthDutyPerson, modifyDutyPerson } from '@/api/schedule-write.js' const context = getCurrentInstance()?.appContext.config.globalProperties const dayjs = context?.$dayjs //當前年份 const year = ref(dayjs().format('YYYY年')) //當前月份 const month = ref(dayjs().format('MM月')) // 當前年月入?yún)? const yearMonthPara = ref(dayjs().format('YYYY-MM')) //所有年份 const optionsYear = ref([]) //所有月份 const optionsMonth = ref([]) //所有星期 const optionWeek = ref([]) // 每個月的第一天 const dayOfWeekFirst = ref(0) // 當前月份的天數(shù) const currentMonth = ref(dayjs().month()) // 當前年份 const currentYear = ref(dayjs().year()) // 當前月份的天數(shù) const daysInMonth = ref(dayjs(`${currentYear}-${currentMonth + 1}-01`).daysInMonth()) const dayOption = ref( Array.from({ length: daysInMonth }, (_, index) => ({ name: '', date: dayjs(`${currentYear}-${currentMonth + 1}-${index + 1}`).format('YYYY-MM-DD') })) ) const dayList = ref([]) //所有人員 const optionsName = ref([]) //選擇年份 const handleYearChange = val => { console.log(val, '選擇年份') year.value = val currentYear.value = parseInt(year.value.toString().slice(0, 4)) currentMonth.value = parseInt(month.value.toString().slice(0, 2)) - 1 daysInMonth.value = dayjs(`${currentYear.value}-${currentMonth.value + 1}-01`).daysInMonth() dayOption.value = Array.from({ length: daysInMonth.value }, (_, index) => ({ name: '', date: dayjs(`${currentYear.value}-${currentMonth.value + 1}-${index + 1}`).format('YYYY-MM-DD') })) console.log(dayOption.value, '所選當月的日期~~~選擇年份') const specifiedDate = ref(`${year.value.toString().slice(0, 4)}-${month.value.toString().slice(0, 2)}-01`) // const specifiedDate = ref('2025-04-15'); // 使用 Day.js 解析日期并獲取該月份的第一天 const firstDayOfMonth = dayjs(specifiedDate.value).startOf('month').format('YYYY-MM-DD') console.log(firstDayOfMonth, '獲取該月份的第一天') dayOfWeekFirst.value = getWeekdayOfFirstDay(firstDayOfMonth) if (dayOfWeekFirst.value == 0) { dayOfWeekFirst.value = 7 } yearMonthPara.value = `${year.value.toString().slice(0, 4)}-${month.value.toString().slice(0, 2)}` console.log(yearMonthPara.value, '年月') getMonthDutyPersonData(yearMonthPara.value) } //選擇月份 const handleMonthChange = val => { console.log(val, '選擇月份') month.value = val currentYear.value = parseInt(year.value.toString().slice(0, 4)) currentMonth.value = parseInt(month.value.toString().slice(0, 2)) - 1 daysInMonth.value = dayjs(`${currentYear.value}-${currentMonth.value + 1}-01`).daysInMonth() dayOption.value = Array.from({ length: daysInMonth.value }, (_, index) => ({ name: '', date: dayjs(`${currentYear.value}-${currentMonth.value + 1}-${index + 1}`).format('YYYY-MM-DD') })) console.log(dayOption.value, '所選當月的日期~~~選擇年份') const specifiedDate = ref(`${year.value.toString().slice(0, 4)}-${month.value.toString().slice(0, 2)}-01`) // 使用 Day.js 解析日期并獲取該月份的第一天 const firstDayOfMonth = dayjs(specifiedDate.value).startOf('month').format('YYYY-MM-DD') console.log(firstDayOfMonth, '獲取該月份的第一天') dayOfWeekFirst.value = getWeekdayOfFirstDay(firstDayOfMonth) if (dayOfWeekFirst.value == 0) { dayOfWeekFirst.value = 7 } yearMonthPara.value = `${year.value.toString().slice(0, 4)}-${month.value.toString().slice(0, 2)}` getMonthDutyPersonData(yearMonthPara.value) } //選擇人員 const handleStuffChange = (event, itemIndex) => { const selectedValue = event console.log(selectedValue, '選擇人員') const selectedOption = optionsName.value.find(option => option.value === selectedValue) console.log(selectedOption, '所選人員') dayList.value[itemIndex].name = selectedOption.label dayList.value[itemIndex].id = selectedOption.id } // 生成年份數(shù)組的函數(shù) const generateYears = (startYear, endYear) => { const years = [] for (let i = startYear; i <= endYear; i++) { years.push({ label: `${i}年`, value: i }) } return years } //獲取當前年份-月份的數(shù)據(jù) const getYearData = () => { //當前年份 const currentYear = dayjs().year() // 過去的年份數(shù)量 const pastYears = 30 // 未來的年份數(shù)量 const futureYears = 50 optionsYear.value = generateYears(currentYear - pastYears, currentYear + futureYears) // console.log(optionsYear.value, '年份') optionsMonth.value = monthList optionWeek.value = weekList } //獲取所有值班人員--下拉框 const getAllDutyPersonData = params => { return new Promise((resolve, reject) => { getAllDutyPerson(params) .then(res => { if (res.code === 200 && res.data) { // console.log(res, '這是:') optionsName.value = res.data.map(item => { return { id: item.id, label: item.name, value: item.name } }) console.log(optionsName.value, '人員') } }) .catch(error => { reject(error) }) }) } //獲取當前月份所有值班人員 const getMonthDutyPersonData = params => { return new Promise((resolve, reject) => { getMonthDutyPerson(params) .then(res => { if (res.code === 200 && res.data) { const mergedList = [] // 遍歷 dayOption 數(shù)組 dayOption.value.forEach(dayOpt => { const matchedData = res.data.find(dataItem => { return dayOpt.date === dataItem.date }) mergedList.push({ ...dayOpt, ...(matchedData ? { name: matchedData.name } : { name: '' }), ...(matchedData ? { id: matchedData.id } : {}) }) }) // 將合并后的數(shù)組賦值給 dayList.value dayList.value = mergedList console.log(dayList.value, '當月值班人員') } }) .catch(error => { reject(error) }) }) } // 定義一個函數(shù)來獲取指定日期的第一天是星期幾 const getWeekdayOfFirstDay = date => { const firstDayOfMonth = dayjs(date).startOf('month') return firstDayOfMonth.day() // 返回星期幾(0-6,0表示星期日) } // 獲取當前月份的第一天 const getCurrentCal = () => { currentMonth.value = dayjs().month() currentYear.value = dayjs().year() daysInMonth.value = dayjs(`${currentYear.value}-${currentMonth.value + 1}-01`).daysInMonth() dayOption.value = Array.from({ length: daysInMonth.value }, (_, index) => ({ name: '', date: dayjs(`${currentYear.value}-${currentMonth.value + 1}-${index + 1}`).format('YYYY-MM-DD') })) const specifiedDate = ref(`${year.value.toString().slice(0, 4)}-${month.value.toString().slice(0, 2)}-01`) // 使用 Day.js 解析日期并獲取該月份的第一天 const firstDayOfMonth = dayjs(specifiedDate.value).startOf('month').format('YYYY-MM-DD') console.log(firstDayOfMonth, '獲取該月份的第一天') if (dayOfWeekFirst.value == 0) { dayOfWeekFirst.value = 7 } dayOfWeekFirst.value = getWeekdayOfFirstDay(firstDayOfMonth) console.log(dayOfWeekFirst.value, '獲取該月份的第一天是星期幾') } onMounted(() => { getCurrentCal() getYearData() getAllDutyPersonData() getMonthDutyPersonData(yearMonthPara.value) }) </script> <style lang="less" scoped> .middle-content { width: 49vw; height: 88vh; overflow: auto; margin: 0 0.5vw; border-radius: 4px; border: 1px solid #e5e5e5; box-shadow: 0 0 10px 0 rgba(232, 232, 232, 0.55) inset; // display: flex; // flex-direction: column; // align-items: center; &::-webkit-scrollbar { width: 5px; } /*定義滾動條軌道*/ &::-webkit-scrollbar-track { border-radius: 5px; } /*定義滑塊*/ &::-webkit-scrollbar-thumb { border-radius: 5px; background: #a8a8a8; } .calender-top { display: flex; align-items: center; justify-content: flex-end; padding: 1vw 0; :deep .t-popup__content { width: 5vw !important; } :deep .t-input__inner { text-align: center; font-size: 0.8vw; } } .canlder-weekList { display: flex; align-items: center; // justify-content: space-between; // padding: 0 1vw; padding: 0.5vw 0 0 1vw; .item-top { // display: flex; width: 6vw; margin: 1vw 0.6vw 0 0; h1 { text-align: center; font-size: 1.2vw; font-weight: 500; color: #333; } } } .canlder-dayList { // width: 15%; display: flex; // flex-direction: column; align-items: center; justify-content: flex-start; flex-wrap: wrap; padding: 0.5vw 0 0 0.8vw; .item-list { width: 6vw; margin: 1vw 0.6vw 0 0; display: flex; flex-direction: column; align-items: center; justify-content: center; .name, .number { width: 5vw; height: 2.5vw; font-size: 0.8vw; line-height: 2.5vw; text-align: center; } .name-color { color: #333; background-color: #d8d8d8; // background-color: rgb(216, 250, 200); } .number-color { color: #fff; background-color: rgb(116, 159, 178); // background-color: rgb(138, 189, 114); } :deep .t-input { // background-color: rgb(216, 250, 200); background-color: #d8d8d8; } :deep .t-input__inner { font-size: 0.8vw; text-align: center; } } } .btn-box { display: flex; // align-items: center; justify-content: center; align-items: center; margin-top: 20px; .btn { width: 5vw; height: 4vh; background: #0289c2; border-color: #0289c2; color: #fff; } .btn-reset { margin-left: 1vw; background: #e7e7e7; border-color: #e7e7e7; color: #393939; } :deep .t-button__text { font-size: 0.8vw; } } } </style>
到此這篇關(guān)于vue3+vite+tdesign實現(xiàn)日歷式可編輯的排課班表的文章就介紹到這了,更多相關(guān)vue3 vite tdesign日歷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue axios post發(fā)送復(fù)雜對象問題
現(xiàn)在vue項目中,一般使用axios發(fā)送請求去后臺拉取數(shù)據(jù)。這篇文章主要介紹了vue axios post發(fā)送復(fù)雜對象的一點思考,需要的朋友可以參考下2019-06-06vuejs 切換導(dǎo)航條高亮(路由菜單高亮)的方法示例
這篇文章主要介紹了vuejs 切換導(dǎo)航條高亮路由高亮的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05使用webpack-obfuscator進行代碼混淆及報錯解決過程
隨著前端應(yīng)用的復(fù)雜度增加,保護客戶端的JavaScript代碼變得更為重要,webpack-obfuscator插件通過對代碼進行混淆,如變量重命名、字符串加密等,提高代碼的保密性,防止源碼被輕易查看或修改2024-10-10vue如何移動到指定位置(scrollIntoView)親測避坑
這篇文章主要介紹了vue如何移動到指定位置(scrollIntoView)親測避坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05vue.js?Table?組件自定義列寬實現(xiàn)核心方法
這篇文章主要介紹了vue.js?Table?組件自定義列寬實現(xiàn)核心方法,文圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-07-07vue-cli中實現(xiàn)響應(yīng)式布局的方法
這篇文章主要介紹了vue-cli中實現(xiàn)響應(yīng)式布局的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03