Commit fd62a4a9 by yanju

personal-center and topic

parent b6248061
/**
* 格式化日期
* @param { Date } date 传入一个日期对象
* @returns { string } dateString 返回格式化后的日期字符串
*/
const format = (date) => {
const dateObj = new Date(date);
const year = dateObj.getFullYear();
const month = dateObj.getMonth() > 10 ? `${dateObj.getMonth() + 1}` : `0${dateObj.getMonth() + 1}`;
const day = dateObj.getDate() > 9 ? `${dateObj.getDate()}` : `0${dateObj.getDate()}`;
return `${year}-${month}-${day}`
};
export default class MyDate {
constructor() {
// 当前日期
const date = new Date();
const year = date.getFullYear(),
month = date.getMonth() + 1,
day = date.getDate();
// 表头
this.weeks = ['日', '一', '二', '三', '四', '五', '六'];
// 当前选择的日期
this.current = {
year,
month,
};
// 输入日期
this.dates = [];
// 今天
this.today = new Date(year, month - 1, day);
this.getDateArray()
}
// 改变日期
changeDate(date = new Date()) {
this.current = {
year: date.getFullYear(),
month: date.getMonth() + 1
};
this.getDateArray()
}
// 获得当前日期数组
getDateArray() {
this.dates = [];
// 当前选择日期所在月的第一天及这一天是星期几
const firstDayOfCurrentMonth = new Date(this.current.year, this.current.month - 1);
const firstDayOfWeek = firstDayOfCurrentMonth.getDay();
// 内层遍历起始点
let weekLoopStart = -firstDayOfWeek + 1;
// 行数据
for (let row = 0; row < 6; row++) {
const rowDate = [];
// 列数据
for (let weekDay = weekLoopStart; weekDay <= 7 + weekLoopStart - 1; weekDay++) {
const targetDate = new Date(this.current.year, this.current.month - 1, weekDay);
const day = targetDate.getDate();
const month = targetDate.getMonth() + 1;
rowDate.push({
date: targetDate,
value: format(targetDate),
label: day,
key: weekDay,
isCurrentMonth: month === this.current.month,
isToday: +targetDate === +this.today
})
}
weekLoopStart += 7;
this.dates.push(rowDate)
}
}
}
<template>
<div>
<div class="container">
<label class="input-label">
<span class="iconfont icon-el-icon-date"></span>
<input class="date-input"
type="text"
placeholder="选择日期"
v-model="selectedDate"
autocomplete="false"
ref="input"
@focus="toggleDateContainer(true)"
@blur=" toggleDateContainer(false)">
<span class="iconfont icon-el-icon-circle-close"
v-show="!!selectedDate"
@click.prevent="selectedDate = ''">
</span>
</label>
<div class="date-container" :class="{'container-visible': containerVisible}" @mousedown.prevent>
<div class="date-header">
<button type="button" class="btn last-year-btn" style="transform: rotate(90deg)">
<span class="iconfont yun-icon--down_arrow" @click="changeMonth(-12)"></span>
</button>
<button type="button" class="btn last-month-btn" style="transform: rotate(90deg)" @click="changeMonth(-1)">
<span class="iconfont yun-icon--down_arrow"></span>
</button>
<span role="button" class="header-text">{{year}}</span>
<span role="button" class="header-text">{{month}}</span>
<button type="button" class="btn next-year-btn" style="transform: rotate(-90deg)" @click="changeMonth(12)">
<span class="iconfont yun-icon--down_arrow"></span>
</button>
<button type="button" class="btn next-month-btn" style="transform: rotate(-90deg)" @click="changeMonth(1)">
<span class="iconfont yun-icon--down_arrow"></span>
</button>
</div>
<div class="date-content">
<table class="date-table">
<thead>
<tr>
<th v-for="data in thead" :key="data">
<span>{{data}}</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, rowIndex) in tbody" :key="'row-' + rowIndex">
<td v-for="cell in row" :key="cell.key" @mousedown="selectDate(cell)">
<span :class="tableCellClass(cell)">{{cell.label}}</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</template>
<script>
import BDate from './Date';
export default {
name: 'DatePicker',
data() {
return {
datePicker: new BDate(),
selectedDate: '',
clearIconVisible: false,
containerVisible: false,
}
},
mounted() {
},
methods: {
// 改变月份
changeMonth(count) {
const changedDate = new Date(this.year, this.month + count - 1);
this.datePicker.changeDate(changedDate);
},
// 选择日期
selectDate(selectedDate) {
this.selectedDate = selectedDate.value;
console.log( selectedDate)
this.$refs.input.blur();
},
// 设定日期单元格样式
tableCellClass(cell) {
return {
'not-current-month': !cell.isCurrentMonth,
today: cell.isToday,
selected: cell.value === this.selectedDate
}
},
// 显示/隐藏日期选择框
toggleDateContainer(visibility) {
this.containerVisible = visibility;
}
},
computed: {
year() {
return this.datePicker.current.year;
},
month() {
return this.datePicker.current.month;
},
thead() {
return this.datePicker.weeks;
},
tbody() {
return this.datePicker.dates;
}
}
}
</script>
<style scoped lang="scss">
.hover {
cursor: pointer;
transition: all 0.2s linear;
&:hover {
color: #409eff;
}
}
.clear {
appearance: none;
-webkit-appearance: none;
outline: none;
background: none;
border: none;
}
.not-current-month {
color: #c0c4cc
}
.today {
color: #409eff;
}
.selected {
color: #fff;
background: #409eff;
border-radius: 50%;
}
.container {
display: inline-block;
position: relative;
}
.input-label {
position: relative;
display: inline-block;
font-size: 14px;
color: #606266;
cursor: pointer;
.icon-el-icon-date {
position: absolute;
left: 8px;
top: 50%;
transform: translateY(-50%);
color: #c0c4cc;
font-size: 14px;
}
.date-input {
@extend .clear;
display: inline-block;
width: 302px;
height: 48px;
line-height: 36px;
padding: 0 30px;
font-size: 14px;
border-radius: 4px;
border: 1px solid transparent;
color: #606266;
user-select: none;
transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
cursor: pointer;
background-color: #F4F8FA;
&:focus {
border: 1px solid #409eff;
background-color: #fff;
}
}
.icon-el-icon-circle-close {
display: none;
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
color: #c0c4cc;
font-size: 14px;
}
&:hover .icon-el-icon-circle-close {
display: block;
}
}
.date-container {
position: absolute;
left: 0;
top: 46px;
color: #606266;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
background: #fff;
border-radius: 4px;
line-height: 30px;
margin: 5px 0;
transition: all 0.5s ease;
border: 1px solid #e4e7ed;
height: 0;
overflow: hidden;
will-change: height;
opacity: 0;
transform: translateZ(0);
}
.container-visible {
height: 320px;
opacity: 1;
}
.date-header {
font-size: 16px;
font-weight: 500;
padding: 0 5px;
margin: 10px 0;
line-height: 30px;
text-align: center;
cursor: pointer;
color: #606266;
overflow: hidden;
.btn {
@extend .clear;
padding: 6px 10px 0;
margin: 0;
@extend .hover;
color: #303133;
.iconfont {
font-size: 8px;
}
}
.last-year-btn, .last-month-btn {
float: left
}
.next-year-btn, .next-month-btn {
float: right
}
.header-text {
margin: 0 5px;
}
}
.date-content {
width: 300px;
font-size: 12px;
padding: 0 10px;
margin: 10px 0;
.date-table {
width: 100%;
border-spacing: 0;
th {
color: #606266;
font-weight: 400;
border-bottom: 1px solid #ebeef5;
padding: 2px 5px;
user-select: none;
}
td {
padding: 4px;
font-weight: 700;
@extend .hover;
span {
display: inline-block;
width: 30px;
height: 30px;
}
}
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment