Skip to content

Commit 6026448

Browse files
committed
blog
1 parent 7c3eeb2 commit 6026448

2 files changed

Lines changed: 221 additions & 0 deletions

File tree

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
---
2+
layout: post
3+
title: "vue.js学习入门——编写日期选择器组件"
4+
categories: javascript
5+
description: "vue.js学习入门——编写日期选择器组件"
6+
main-class: 'dev'
7+
color: '#637a91'
8+
tags:
9+
- "vue.js"
10+
twitter_text: "vue.js学习入门——编写日期选择器组件"
11+
introduction: "vue.js学习入门——编写日期选择器组件"
12+
---
13+
14+
日期选择器是一种比较常用的组件,其制作原理也基本上是
15+
对javascript的Date对象的应用。如下图所示就是一个简单的日历选择器。
16+
![日历组件](../assets/img/2017-06-24.jpg)
17+
18+
### 日期选择器组件需求
19+
20+
* 显示点击按纽显示日历,选中某日期,日历隐藏
21+
* 显示日历与星期对应,显示日期的同时显示当前日期的价格
22+
* 能显示今天的日期添加蓝色,hover状态的日期添加浅蓝色
23+
* 添加下个月,上个月按纽
24+
25+
### 设计思路
26+
27+
* 在模版中可以使用`v-for`指令来一个个日期div, 在data中设置priceDates数组保存日历价格对象,数组的个数为当前月的日数。
28+
* 每月的日数可以通过下个月的1号的前一天来确定是28,29,30还是31
29+
* 日期放到对应的星期列上,只需知道一个月第一天是星期几即可实现一一对应。
30+
* 得出当月1号是周几,即可将1号的div放置到对应星期列上,这里可以使用margin-left来设置,也可以在priceDates数组中插入空对象元素。
31+
* 通过在模版中绑定样式类来添加当前日期以及空白的样式
32+
33+
### 具体实现
34+
35+
具体实现代码如下:
36+
37+
```
38+
<template>
39+
<div>
40+
<h3>check-in date-picker</h3>
41+
<div>
42+
<input type="text" :value="pickedDate">
43+
<button @click="openPicker">date-picker</button>
44+
<span>当日最低价格为:{{price}}</span>
45+
<div v-if="datePickerShow" class="date-picker-container">
46+
<p>
47+
<button @click="closePicker">close</button>
48+
<button @click="nextMonth">next month</button>
49+
<button @click="lastMonth">last month</button>
50+
<span>{{currentDate.year}}</span>
51+
<span>{{month}}</span>
52+
</p>
53+
<div class="week">
54+
<div v-for="(item, index) in week">周{{item}}</div>
55+
</div>
56+
<div class="dates">
57+
<div v-for="(item, index) in priceDates" :class="{today: item.isToday, noblank: item.date!==''}"
58+
@click="pickDate(item.date, item.price)">
59+
<span>{{item.date}}</span><br>
60+
<span>{{item.price}}</span>
61+
</div>
62+
</div>
63+
</div>
64+
</div>
65+
</div>
66+
</template>
67+
<script>
68+
export default {
69+
name: 'check-in',
70+
data: function () {
71+
return {
72+
datePickerShow: false,
73+
pickedDate: '',
74+
price: '',
75+
week: ['日', '一', '二', '三', '四', '五', '六'],
76+
priceDates: [],
77+
currentDate: {
78+
year: '',
79+
month: 0,
80+
date: ''
81+
}
82+
}
83+
},
84+
computed: {
85+
month: function () {
86+
const months = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二']
87+
return months[this.currentDate.month] + '月'
88+
}
89+
},
90+
methods: {
91+
openPicker: function () {
92+
this.priceDates = []
93+
const now = new Date()
94+
const year = now.getFullYear()
95+
const month = now.getMonth()
96+
const date = now.getDate()
97+
this.currentDate.year = year
98+
this.currentDate.month = month
99+
this.currentDate.date = date
100+
now.setDate(1)
101+
// now已经变为当月第一天
102+
const firstDay = now.getDay() // 当月第一天是星期几
103+
now.setMonth(month + 1)
104+
now.setDate(1)
105+
// now 变为下一个月第一天
106+
const lastDate = new Date(now - 24 * 3600 * 1000).getDate() // 当月最后一天是几号
107+
var dates = []
108+
for (let i = 0; i < firstDay; i++) {
109+
dates.push('')
110+
this.priceDates.push({date: '', price: '', isToday: false})
111+
}
112+
for (let i = 1; i < lastDate + 1; i++) {
113+
dates.push('' + i)
114+
this.priceDates.push({
115+
date: '' + i,
116+
price: '¥' + (500 + Math.random().toFixed(2) * 400),
117+
isToday: this.currentDate.month === month && i === this.currentDate.date
118+
})
119+
}
120+
console.log(this.priceDates)
121+
this.datePickerShow = true
122+
},
123+
lastMonth: function () {
124+
if (this.currentDate.month !== 0) {
125+
this.currentDate.month--
126+
} else {
127+
this.currentDate.month = 11
128+
this.currentDate.year--
129+
}
130+
const now = new Date()
131+
const month = now.getMonth()
132+
now.setMonth(this.currentDate.month)
133+
now.setDate(1)
134+
const firstDay = now.getDay() // 当月第一天是星期几
135+
const lastDate = new Date(now - 24 * 3600 * 1000).getDate() // 当月最后一天是几号
136+
this.priceDates = []
137+
for (let i = 0; i < firstDay; i++) {
138+
this.priceDates.push({date: '', price: '', isToday: false})
139+
}
140+
for (let i = 1; i < lastDate + 1; i++) {
141+
this.priceDates.push({
142+
date: '' + i,
143+
price: '¥' + (500 + Math.random().toFixed(2) * 400),
144+
isToday: this.currentDate.month === month && i === this.currentDate.date
145+
})
146+
}
147+
},
148+
nextMonth: function () {
149+
if (this.currentDate.month !== 11) {
150+
this.currentDate.month++
151+
} else {
152+
this.currentDate.month = 0
153+
this.currentDate.year++
154+
}
155+
const now = new Date()
156+
const month = now.getMonth()
157+
now.setMonth(this.currentDate.month)
158+
now.setDate(1)
159+
const firstDay = now.getDay() // 当月第一天是星期几
160+
const lastDate = new Date(now - 24 * 3600 * 1000).getDate() // 当月最后一天是几号
161+
this.priceDates = []
162+
for (let i = 0; i < firstDay; i++) {
163+
this.priceDates.push({date: '', price: '', isToday: false})
164+
}
165+
for (let i = 1; i < lastDate + 1; i++) {
166+
this.priceDates.push({
167+
date: '' + i,
168+
price: '¥' + (500 + Math.random().toFixed(2) * 400),
169+
isToday: this.currentDate.month === month && i === this.currentDate.date
170+
})
171+
}
172+
},
173+
closePicker: function () {
174+
this.datePickerShow = false
175+
},
176+
pickDate: function (date, price) {
177+
this.datePickerShow = false
178+
this.pickedDate = this.currentDate.year + '-' + (this.currentDate.month + 1) + '-' + date
179+
this.price = price
180+
}
181+
}
182+
}
183+
</script>
184+
185+
<style lang="less" scoped>
186+
.date-picker-container{
187+
width: 370px;
188+
border: solid #eee 1px;
189+
box-shadow: #efefef 1px 1px -1px -1px;
190+
padding: 0 8px;
191+
.week{
192+
width: 350px;
193+
height: 20px;
194+
div{
195+
width: 50px;
196+
height: 20px;
197+
float: left;
198+
text-align: center;
199+
word-spacing: 0;
200+
}
201+
}
202+
.dates{
203+
&>div{
204+
width: 50px;
205+
display: inline-block;
206+
text-align: center;
207+
}
208+
.today{
209+
background-color: #4db3ff;
210+
}
211+
.noblank{
212+
cursor: pointer;
213+
&:hover{
214+
background-color: #6dd3ff;
215+
}
216+
}
217+
}
218+
}
219+
</style>
220+
```
221+

assets/img/2017-06-24.jpg

101 KB
Loading

0 commit comments

Comments
 (0)