Vue+Element-ui日歷排班自定義實例代碼
前言
在日常開發(fā)需求中,可能會遇到給員工進行排班的需求,如果只是在table表格中顯示,會顯得枯燥、不直觀,今天我們就來寫一個可以自定義的日歷排班功能,用的是vue2+element-ui。
效果圖如下:
(圖一):日歷中顯示排班數(shù)據(jù),排班數(shù)據(jù)可以使用鼠標進行拖動,改變排班的順序。
(圖二):可以對日期范圍進行批量、多班次排班
(圖三):可以對單日排班信息進行操作,顯示單日排班時間的具體信息等。
下面是代碼部分:
<template> <div id="app"> <div class="calender-class"> <div class="batch-add-Work-class"> <el-button class="add-btn-class" size="small" type="primary" @click="batchAddDrawer = true">批量排班</el-button> </div> <el-calendar> <!-- 這里使用的是 2.5 slot 語法,對于新項目請使用 2.6 slot 語法--> <template slot="dateCell" slot-scope="{date, data}"> <div class="day-content-class"> <template v-if="viewDate[data.day]"> <div class="header-class"> <div class="day-class"> {{ data.day.split('-').slice(1).join('-') }} </div> <div class="handle-class"> <el-button icon="el-icon-edit" size="mini" circle @click="handleWorkInfo(viewDate[data.day], data)"></el-button> </div> </div> <div class="paiban-class"> <div v-for="(dayValue, i) in viewDate[data.day]" :class="['draggable-div' + i, 'each-paiban-class', setWorkClass(dayValue.sort)]" draggable="true" @dragstart="handleDragStart($event, dayValue, data.day)" @dragover.prevent="handleDragOver($event)" @dragenter="handleDragEnter($event, dayValue)" @dragend="handleDragEnd()"> <i :class="[setIconClass(dayValue.shiftName), 'paiban-icon-class']"></i> <div class="paiban-name-class">{{ dayValue.groupName }}</div> </div> </div> </template> <template v-else> <div class="header-class"> <div class="day-class"> {{ data.day.split('-').slice(1).join('-') }} </div> <div class="handle-class"> <el-button icon="el-icon-edit" size="mini" circle @click="handleWorkInfo(viewDate[data.day], data)"></el-button> </div> </div> <div class="no-work-class"> <div class="icon-class"><i class="el-icon-date"></i></div> <div class="tips-class"> 暫無排班 </div> </div> </template> </div> </template> </el-calendar> </div> <!-- 批量排班抽屜彈窗 --> <div> <el-drawer title="批量排班" :visible.sync="batchAddDrawer" size="40%"> <div class="demo-drawer__content"> <el-form :model="batchAddForm"> <el-form-item label="排班日期" label-width="80px"> <el-date-picker v-model="batchAddForm.batchDate" value-format="yyyy-MM-dd" type="daterange" range-separator="至" start-placeholder="開始日期" end-placeholder="結(jié)束日期"> </el-date-picker> </el-form-item> <el-button type="primary" icon="el-icon-plus" circle @click="addDomain"></el-button> <el-form-item label-width="80px" v-for="(data, index) in batchAddForm.classData" :label="'排班' + (index + 1) + ':'" :key="data.key"> <p></p> <span>班次:</span> <el-radio-group v-model="data.shiftName"> <el-radio label="早">早</el-radio> <el-radio label="中">中</el-radio> <el-radio label="晚">晚</el-radio> </el-radio-group> <p></p> <span>班別:</span> <el-radio-group class="margin-left:80px" v-model="data.groupName"> <el-radio label="甲">甲</el-radio> <el-radio label="乙">乙</el-radio> <el-radio label="丙">丙</el-radio> </el-radio-group> <el-button class="remove-domain-class" @click.prevent="removeDomain(data)" type="danger" icon="el-icon-delete" circle></el-button> </el-form-item> </el-form> </div> <div class="demo-drawer__footer"> <el-button @click="handleBatchClose">取 消</el-button> <el-button type="primary" @click="batchAddWork()"> 確定 </el-button> </div> </el-drawer> </div> <!-- 單獨排班 --> <div> <el-drawer :title="'【' + hanleDay.day + '】排班'" :visible.sync="drawer" size="40%"> <div class="add-work-class"> <el-button class="add-btn-class" type="primary" @click="innerDrawer = true">添加</el-button> <el-drawer title="添加排班" :append-to-body="true" :before-close="handleClose" :visible.sync="innerDrawer"> <div class="demo-drawer__content"> <el-form :model="addForm"> <el-form-item label="班次:" label-width="80px"> <el-radio-group v-model="addForm.shiftName"> <el-radio label="早">早</el-radio> <el-radio label="中">中</el-radio> <el-radio label="晚">晚</el-radio> </el-radio-group> </el-form-item> <el-form-item label="班別:" label-width="80px"> <el-radio-group v-model="addForm.groupName"> <el-radio label="甲">甲</el-radio> <el-radio label="乙">乙</el-radio> <el-radio label="丙">丙</el-radio> </el-radio-group> </el-form-item> </el-form> </div> <div class="demo-drawer__footer"> <el-button @click="handleClose">取 消</el-button> <el-button type="primary" @click="addWork()"> 確定 </el-button> </div> </el-drawer> </div> <el-table :data="workInfoList"> <el-table-column property="date" label="日期" width="100"></el-table-column> <el-table-column property="shiftName" label="班次"></el-table-column> <el-table-column property="groupName" label="班別"></el-table-column> <el-table-column property="startTime" label="開始時間" width="160"></el-table-column> <el-table-column property="endTime" label="結(jié)束時間" width="160"></el-table-column> <el-table-column fixed="right" label="操作" width="120"> <template slot-scope="scope"> <el-button @click.native.prevent="deleteRow(scope, workInfoList)" type="text" size="small"> 移除 </el-button> </template> </el-table-column> </el-table> </el-drawer> </div> </div> </template> <script> import moment from 'moment' export default { data() { return { viewDate: { "2023-06-20": [ { "id": "2023-06-20" + Math.random(1000), "ruleName": "三班兩運轉(zhuǎn)", "shiftName": "早", "groupName": "甲", "startTime": "2023-06-20 08:30", "endTime": "2023-06-20 20:30", "isNotHoliday": 0, "classId": 1, "date": "2023-06-20", "sort": 1 }, { "id": "2023-06-20" + Math.random(1000), "ruleName": "三班兩運轉(zhuǎn)", "shiftName": "中", "groupName": "乙", "startTime": "2023-06-20 20:30", "endTime": "2023-06-21 08:30", "isNotHoliday": 0, "classId": 1, "date": "2023-06-20", "sort": 2 }, ], "2023-06-21": [ { "id": "2023-06-21" + Math.random(1000), "ruleName": "三班兩運轉(zhuǎn)", "shiftName": "早", "groupName": "甲", "startTime": "2023-06-20 08:30", "endTime": "2023-06-20 20:30", "isNotHoliday": 0, "classId": 1, "date": "2023-06-20", "sort": 1 }, { "id": "2023-06-21" + Math.random(1000), "ruleName": "三班兩運轉(zhuǎn)", "shiftName": "中", "groupName": "乙", "startTime": "2023-06-20 08:30", "endTime": "2023-06-20 20:30", "isNotHoliday": 0, "classId": 1, "date": "2023-06-20", "sort": 2 }, { "id": "2023-06-21" + Math.random(1000), "ruleName": "三班兩運轉(zhuǎn)", "shiftName": "晚", "groupName": "丙", "startTime": "2023-06-20 08:30", "endTime": "2023-06-20 20:30", "isNotHoliday": 0, "classId": 1, "date": "2023-06-20", "sort": 3 }, ], }, thisDay: null, thisDayWork: null, ending: null, dragging: null, batchAddDrawer: false, // 批量添加 batchAddForm: { batchDate: [], classData: [{ shiftName: '早', groupName: '甲', }] }, // 單日添加 addForm: { shiftName: '早', groupName: '甲', sort: 1, }, drawer: false, innerDrawer: false, hanleDay: '', workInfoList: [] }; }, watch: { 'addForm.shiftName'(newVal, oldVal) { switch (newVal) { case '早': this.addForm.sort = 1 break; case '中': this.addForm.sort = 2 break; case '晚': this.addForm.sort = 3 break; default: break; } } }, computed: { }, methods: { handleDragStart(e, item, thisDay) { this.dragging = item this.thisDay = thisDay this.thisDayWork = this.viewDate[thisDay] }, handleDragEnd() { if (this.ending.id === this.dragging.id) { return } let newItems = [...this.thisDayWork] const src = newItems.indexOf(this.dragging) const dst = newItems.indexOf(this.ending) newItems.splice(src, 1, ...newItems.splice(dst, 1, newItems[src])) this.$set(this.viewDate, this.thisDay, newItems) this.$nextTick(() => { this.dragging = null this.ending = null }) console.log("?? ~ file: App.vue:286 ~ handleDragEnd ~ this.viewDate:", this.viewDate) }, handleDragOver(e) { // 首先把div變成可以放置的元素,即重寫dragenter/dragover e.dataTransfer.dropEffect = 'move'// e.dataTransfer.dropEffect="move";//在dragenter中針對放置目標來設(shè)置! }, handleDragEnter(e, item) { e.dataTransfer.effectAllowed = 'move'// 為需要移動的元素設(shè)置dragstart事件 this.ending = item }, // 獲取時間范圍中的所有日期 enumerateDaysBetweenDates(startDate, endDate) { let daysList = []; let SDate = moment(startDate); let EDate = moment(endDate); daysList.push(SDate.format("YYYY-MM-DD")); while (SDate.add(1, "days").isBefore(EDate)) { daysList.push(SDate.format("YYYY-MM-DD")); } daysList.push(EDate.format("YYYY-MM-DD")); return daysList; }, setSortValue(value) { let sort = 1 switch (value) { case '早': sort = 1 break; case '中': sort = 2 break; case '晚': sort = 3 break; default: break; } return sort }, setWorkClass(value) { let classValue = 'no-work-class' switch (value) { case 1: classValue = 'zao-work-class' break; case 2: classValue = 'wan-work-class' break; case 3: classValue = 'ye-work-class' break; default: break; } return classValue; }, setIconClass(value) { let classValue = 'el-icon-sunrise' switch (value) { case "早": classValue = 'el-icon-sunrise' break; case "中": classValue = 'el-icon-sunny' break; case "晚": classValue = 'el-icon-moon' break; default: break; } return classValue; }, // 編輯單日排班 handleWorkInfo(info, data) { this.hanleDay = data this.drawer = true if (info && info.length > 0) { this.workInfoList = info } else { this.workInfoList = [] } }, handleClose() { this.innerDrawer = false; }, // 添加單日排班 addWork() { let info = { "id": this.hanleDay.day + Math.random(1000), "ruleName": "三班兩運轉(zhuǎn)", "shiftName": this.addForm.shiftName, "groupName": this.addForm.groupName, "startTime": this.hanleDay.day + " 08:30", "endTime": this.hanleDay.day + " 20:30", "isNotHoliday": 0, "classId": 1, "date": this.hanleDay.day, "sort": this.addForm.sort } this.workInfoList.push(info) this.$set(this.viewDate, this.hanleDay.day, this.workInfoList) this.$forceUpdate() this.innerDrawer = false; }, // 清除單日排班數(shù)據(jù) deleteRow(row, tableData) { let index = row.$index tableData.splice(index, 1); if (tableData.length > 0) { this.$set(this.viewDate, this.hanleDay.day, tableData) } else { this.$delete(this.viewDate, this.hanleDay.day); } }, addDomain() { this.batchAddForm.classData.push({ shiftName: '早', groupName: '甲', key: Date.now() }); }, removeDomain(item) { if (this.batchAddForm.classData.length > 1) { var index = this.batchAddForm.classData.indexOf(item) if (index !== -1) { this.batchAddForm.classData.splice(index, 1) } } else { this.$message({ message: '請至少安排一個排班', type: 'error' }); } }, // 批量添加排班數(shù)據(jù) batchAddWork() { let dateList = this.batchAddForm.batchDate let classList = this.batchAddForm.classData let list = [] if (dateList && dateList.length > 0) { list = this.enumerateDaysBetweenDates(dateList[0], dateList[1]) } list.forEach((item) => { let workList = [] classList.forEach((work) => { let info = { "id": item + Math.random(1000), "ruleName": "三班兩運轉(zhuǎn)", "shiftName": work.shiftName, "groupName": work.groupName, "startTime": item + " 08:30", "endTime": item + " 20:30", "isNotHoliday": 0, "classId": 1, "date": item, "sort": this.setSortValue(work.shiftName) } workList.push(info) }) this.$set(this.viewDate, item, workList) }) this.batchAddDrawer = false }, handleBatchClose() { this.batchAddDrawer = false } } } </script> <style> #app { width: 100%; height: 100%; margin: 0; padding: 0; } .el-table__fixed-right { height: 100% !important; } .calender-class { width: 100%; height: 100%; } .is-selected { color: #1989FA; } .el-calendar__body { height: 85vh; } .el-calendar-table { height: 100%; } .el-calendar-day { height: 100% !important; } .day-content-class { height: 100px; display: flex; flex-direction: column; } .header-class { flex: 1; display: flex; height: 28px; flex-direction: row; justify-content: space-between; } .day-class { flex: 4; } .handle-class { flex: 1; } .paiban-class { flex: 4; display: flex; flex-direction: row; justify-content: center; align-items: flex-end; } .paiban-icon-class { font-size: 22px; margin: 8px 0 10px 0; } .paiban-name-class { padding-top: 10px; } .each-paiban-class { text-align: center; max-width: 50px; margin: 5px 5px 0 5px; border-radius: 5px; padding: 0 0 5px 0; flex: 1; } .zao-work-class { background-color: #d9ffd9; color: #11be11; } .wan-work-class { background-color: #fff0bd; color: #fccb2c; } .ye-work-class { background-color: #ddeffb; color: #2dabff; } .no-work-class { text-align: center; color: #cacaca; } .icon-class { font-size: 20px; margin-bottom: 20px; } /* 側(cè)邊彈窗 */ .add-btn-class { margin: 10px; float: right; } </style>
總結(jié)
到此這篇關(guān)于Vue+Element-ui日歷排班的文章就介紹到這了,更多相關(guān)Vue Element-ui日歷排班內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue 中 a標簽上href無法跳轉(zhuǎn)的解決方式
今天小編大家分享一篇Vue 中 a標簽上href無法跳轉(zhuǎn)的解決方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11vue如何將html內(nèi)容轉(zhuǎn)為圖片并下載到本地
這篇文章主要介紹了vue如何將html內(nèi)容轉(zhuǎn)為圖片并下載到本地,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01vue中實現(xiàn)子組件相互切換且數(shù)據(jù)不丟失的策略詳解
項目為數(shù)據(jù)報表,但是一個父頁面中有很多的子頁面,而且子頁面中不是相互關(guān)聯(lián),但是數(shù)據(jù)又有聯(lián)系,所以本文給大家介紹了vue中如何實現(xiàn)子組件相互切換,而且數(shù)據(jù)不會丟失,并有詳細的代碼供大家參考,需要的朋友可以參考下2024-03-03vue報錯"vue-cli-service‘不是內(nèi)部或外部命令,也不是...”的解決辦法
這篇文章主要介紹了vue報錯"vue-cli-service‘不是內(nèi)部或外部命令,也不是...”的解決辦法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01vue項目登錄頁面實現(xiàn)記住用戶名和密碼的示例代碼
本文主要介紹了vue項目登錄頁面實現(xiàn)記住用戶名和密碼的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07