vue3+vite+tdesign實(shí)現(xiàn)日歷式可編輯的排課班表填寫功能
近期,在項(xiàng)目開發(fā)中,我們面臨實(shí)現(xiàn)一個(gè)日歷式、可編輯排班填寫功能的需求。初步方案采用tdesign的Calendar組件,盡管其支持編輯功能,但在提取每日排班信息時(shí)操作繁瑣,因此該方案被棄用。隨后,我們決定自主研發(fā)該功能,盡管看似直觀,開發(fā)過程中仍面臨諸多挑戰(zhàn)。本文旨在總結(jié)此次開發(fā)經(jīng)歷,希望對(duì)有類似需求的開發(fā)者有所幫助。
本篇文章開發(fā)環(huán)境的安裝就不進(jìn)行詳細(xì)闡述,著重闡述如何使用vue3+tdesign實(shí)現(xiàn)日歷式可編輯的排班填寫功能。

一、安裝tdesign
使用npm安裝
npm i tdesign-vue-next
二、實(shí)現(xiàn)年份、月份下拉框
對(duì)于年份和月份下拉框選擇,這里未使用tdesign自帶的日期選擇組件,但使用了他的select下拉框組件,另外這里還使用到了dayjs,用于獲取不同年份。
1.安裝dayjs
npm install dayjs
2.年份下拉框樣式
這個(gè)實(shí)現(xiàn)起來比較簡(jiǎn)單一些,其實(shí)就是使用tdesign的select選擇器這個(gè)組件就行。
<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'
//當(dāng)前年份
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.獲取所有年份
以上代碼中只是實(shí)現(xiàn)了下拉框的具體樣式,其實(shí)下拉框的內(nèi)容還是空的,下面就是如何使用dayjs實(shí)現(xiàn)獲取所有的年份。因?yàn)橐笤趧傔M(jìn)行頁(yè)面時(shí)需顯示當(dāng)前年份,所以在v-model綁定的year這里,就需要使用dayjs來獲取目前所處的年份,具體如下:
//這個(gè)代碼十分重要,沒有這個(gè)dayjs無法使用
const context = getCurrentInstance()?.appContext.config.globalProperties
const dayjs = context?.$dayjs
//當(dāng)前年份
const year = ref(dayjs().format('YYYY年'))獲取所有年份這里具體寫了一個(gè)方法,大概得步驟就是,首先先寫一個(gè)生成年份數(shù)組的方法,然后確定當(dāng)前的年份,規(guī)定一下過去的年份和未來年份數(shù)量,使用剛剛的方法進(jìn)行加減即可,具體代碼如下:
// 生成年份數(shù)組的函數(shù)
const generateYears = (startYear, endYear) => {
const years = []
for (let i = startYear; i <= endYear; i++) {
years.push({
label: `${i}年`,
value: i
})
}
return years
}
//獲取當(dāng)前年份-月份的數(shù)據(jù)
const getYearData = () => {
//當(dāng)前年份
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.獲取月份
獲取月份這里我未使用以上方式進(jìn)行開發(fā),因?yàn)樵路輸?shù)據(jù)涉及的少,所以在前端這里我寫了一個(gè)JSON數(shù)據(jù),直接進(jìn)行復(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'
//當(dāng)前月份
const month = ref(dayjs().format('MM月'))
//所有月份
const optionsMonth = ref([])
//選擇月份
const handleMonthChange = val => {}
//獲取當(dāng)前年份-月份的數(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'
}
]三、周期顯示
上述闡述了年份和月份下拉框的實(shí)現(xiàn),做日歷的話還缺少周期數(shù),接下來是實(shí)現(xiàn)具體的周期,這個(gè)樣式的話相對(duì)來說比較簡(jiǎn)單,涉及到flex布局、ul和li列表,另外周期數(shù)據(jù)其實(shí)也是固定的,和月份一樣也是做了一個(gè)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([])
//獲取當(dāng)前周期的數(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)容了,首先先來實(shí)現(xiàn)日歷的具體樣式,他的需求功能是,每天中對(duì)應(yīng)一個(gè)下拉框,下來框是可選擇排班的人員,然后下方就是對(duì)應(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([])
//當(dāng)前選擇人員
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ù)
上述代碼寫完我們會(huì)發(fā)現(xiàn),頁(yè)面上其實(shí)啥也沒有,具體原因是源于還沒做數(shù)據(jù)的獲取,接下來就是如何獲取下來框值班人,因?yàn)槲疫@里的axios是進(jìn)行了封裝之后的,所以這里我展示獲取數(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([])
//當(dāng)前選擇人員
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.獲取每天值班人
這個(gè)步驟應(yīng)該是上述方案之前的,在開發(fā)時(shí)記得先做這個(gè)步驟,然后再開始獲取下拉框的數(shù)據(jù)。因?yàn)檫@個(gè)步驟沒做好頁(yè)面上是啥也看不到的,接下來我們就開始吧
<script setup>
import { ref, getCurrentInstance, onMounted, computed } from 'vue'
import { getAllDutyPerson, getMonthDutyPerson, modifyDutyPerson } from '@/api/schedule-write.js'
const dayList = ref([])
// 當(dāng)前年月入?yún)?
const yearMonthPara = ref(dayjs().format('YYYY-MM'))
//當(dāng)前月份的天數(shù)
const currentMonth = ref(dayjs().month())
//當(dāng)前年份
const currentYear = ref(dayjs().year())
//處理當(dāng)前月份天數(shù)和當(dāng)前年份
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')
}))
)
//獲取當(dāng)前月份所有值班人員
const getMonthDutyPersonData = params => {
return new Promise((resolve, reject) => {
getMonthDutyPerson(params)
.then(res => {
if (res.code === 200 && res.data) {
// console.log(res, '當(dāng)月:')
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, '當(dāng)月值班人員')
}
})
.catch(error => {
reject(error)
})
})
}
onMounted(() => {
getMonthDutyPersonData(yearMonthPara.value)
})3.處理選擇每個(gè)年份、月份所對(duì)應(yīng)的周期及天數(shù)
做完了以上的東西后,我們就可以在頁(yè)面中看到日歷了,但是在選擇每個(gè)年份和月份后我們會(huì)發(fā)現(xiàn)下面所對(duì)應(yīng)的天數(shù)一直都是當(dāng)月的天數(shù),比如我當(dāng)前月份是一月,有三十一天,但是我在選擇2月份后他的天數(shù)依舊31天,但實(shí)際上2月份只有28天,另外他的每個(gè)一號(hào)都是對(duì)應(yīng)在周一,其實(shí)這是不對(duì)的,存在一定的bug。接下來就來解決這個(gè)問題。
<script setup>
import { ref, getCurrentInstance, onMounted, computed } from 'vue'
import { getAllDutyPerson, getMonthDutyPerson, modifyDutyPerson } from '@/api/schedule-write.js'
// 定義一個(gè)函數(shù)來獲取指定日期的第一天是星期幾
const getWeekdayOfFirstDay = date => {
const firstDayOfMonth = dayjs(date).startOf('month')
return firstDayOfMonth.day() // 返回星期幾(0-6,0表示星期日)
}
// 定義一個(gè)函數(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()
})以上的問題寫了一個(gè)解決方法,我們還需要再點(diǎn)擊選擇年份和月份的點(diǎn)擊事件中進(jìn)行修改
//選擇年份
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, '所選當(dāng)月的日期~~~選擇年份')
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, '所選當(dāng)月的日期~~~選擇年份')
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)
}接下來還需要修改的一個(gè)地方就是樣式的綁定
<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>
// 每個(gè)月的第一天
const dayOfWeekFirst = ref(0)五、全部代碼、效果展示
綜上實(shí)現(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
//當(dāng)前年份
const year = ref(dayjs().format('YYYY年'))
//當(dāng)前月份
const month = ref(dayjs().format('MM月'))
// 當(dāng)前年月入?yún)?
const yearMonthPara = ref(dayjs().format('YYYY-MM'))
//所有年份
const optionsYear = ref([])
//所有月份
const optionsMonth = ref([])
//所有星期
const optionWeek = ref([])
// 每個(gè)月的第一天
const dayOfWeekFirst = ref(0)
// 當(dāng)前月份的天數(shù)
const currentMonth = ref(dayjs().month())
// 當(dāng)前年份
const currentYear = ref(dayjs().year())
// 當(dāng)前月份的天數(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, '所選當(dāng)月的日期~~~選擇年份')
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, '所選當(dāng)月的日期~~~選擇年份')
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
}
//獲取當(dāng)前年份-月份的數(shù)據(jù)
const getYearData = () => {
//當(dāng)前年份
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)
})
})
}
//獲取當(dāng)前月份所有值班人員
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, '當(dāng)月值班人員')
}
})
.catch(error => {
reject(error)
})
})
}
// 定義一個(gè)函數(shù)來獲取指定日期的第一天是星期幾
const getWeekdayOfFirstDay = date => {
const firstDayOfMonth = dayjs(date).startOf('month')
return firstDayOfMonth.day() // 返回星期幾(0-6,0表示星期日)
}
// 獲取當(dāng)前月份的第一天
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;
}
/*定義滾動(dòng)條軌道*/
&::-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實(shí)現(xiàn)日歷式可編輯的排課班表的文章就介紹到這了,更多相關(guān)vue3 vite tdesign日歷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue和uniapp頁(yè)面實(shí)現(xiàn)自動(dòng)滾動(dòng)到最底部
這篇文章主要介紹了vue和uniapp頁(yè)面實(shí)現(xiàn)自動(dòng)滾動(dòng)到最底部方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Vue實(shí)現(xiàn)英文字母大小寫在線轉(zhuǎn)換功能
在Web開發(fā)中,字符串處理是常見的需求之一,特別是在國(guó)際化應(yīng)用中,對(duì)于文本的格式化處理尤為重要,本文將介紹如何使用Vue.js來構(gòu)建一個(gè)簡(jiǎn)單的在線英文字母大小寫轉(zhuǎn)換工具,需要的朋友可以參考下2024-09-09
vuex中遇到的坑,vuex數(shù)據(jù)改變,組件中頁(yè)面不渲染操作
這篇文章主要介紹了vuex中遇到的坑,vuex數(shù)據(jù)改變,組件中頁(yè)面不渲染操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-11-11
vue實(shí)現(xiàn)靜態(tài)頁(yè)面點(diǎn)贊和取消點(diǎn)贊功能
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)靜態(tài)頁(yè)面點(diǎn)贊和取消點(diǎn)贊的功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
vue v-for循環(huán)出來的數(shù)據(jù)動(dòng)態(tài)綁定值問題
這篇文章主要介紹了vue v-for循環(huán)出來的數(shù)據(jù)動(dòng)態(tài)綁定值問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
解決Element-ui radio單選框label布爾/數(shù)值的一個(gè)坑
這篇文章主要介紹了解決Element-ui radio單選框label布爾/數(shù)值的一個(gè)坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
vue?過濾、模糊查詢及計(jì)算屬性?computed詳解
計(jì)算屬性是vue里面為了簡(jiǎn)化在模板語法中對(duì)響應(yīng)式屬性做計(jì)算而存在的,這篇文章主要介紹了vue?過濾、模糊查詢(計(jì)算屬性?computed),需要的朋友可以參考下2022-11-11

