2021-06-06 vue年份范围选择器YearRangePicker封装
年份范围选择器YearRangePicker封装效果展示实现思路年份范围选择年份范围快捷选项点击确定按钮时将起始年份和结束年份导出实现难点如何使用相关代码因为element-ui中的el-date-picker只有月份、日期范围选择,没有年份范围选择,而我们的项目需要选择年份范围,于是我想着试一试借助el-date-picker封装一个年份范围选择器。效果展示前言:前端从后端获取可以选择的年份范围
·
因为element-ui中的el-date-picker只有月份、日期范围选择,没有年份范围选择,而我们的项目需要选择年份范围,于是我想着试一试借助el-date-picker封装一个年份范围选择器。
效果展示
前言:前端从后端获取可以选择的年份范围
- 点击下方的快捷选项,最近一年,最近三年和最近五年,年份选择框会变成相应的年份(结束年份为可以选择的最大年份)
- 点击年份选择框也可以选择年份
- 当年份不合要求(如起始年份大于结束年份,年份超出范围),再点击确定的时候会有错误提示。
实现思路
年份范围选择
利用两个el-date-picker组件作为选择器,将type设置为‘year’
两个el-date-picker间用‘至’相隔
在最右边加上确定按钮
<el-date-picker
v-model="start"
type="year"
size="small"
style="width: 100px"
placeholder="开始年份"
>
</el-date-picker>
<span style="margin-left: 5px; margin-right: 5px">至</span>
<el-date-picker
v-model="end"
type="year"
size="small"
style="width: 100px; margin-right: 5px"
placeholder="结束年份"
>
</el-date-picker>
<el-button size="small" type="primary" @click="handleClick"
>确定</el-button
>
年份范围快捷选项
用3个size为small的el-button作为快捷选项,绑定click事件
<div style="text-align: left">
<el-button
type="text"
size="small"
style="display: inline"
@click="handleShortCut(1)"
>最近一年</el-button
>
<el-button
type="text"
size="small"
style="display: inline"
@click="handleShortCut(3)"
>最近三年</el-button
>
<el-button
type="text"
size="small"
style="display: inline"
@click="handleShortCut(5)"
>最近五年</el-button
>
</div>
click事件
handleShortCut(val) {
//date类型的数据,单纯的赋值实际上是浅拷贝,指向同一个地址,所以当一个变量变化,这个地址也会跟着变,所以要用到深拷贝
Date.prototype.clone = function () {
return new Date(this.valueOf());
}
//最近x年的结束年份
this.end = this.maxYear.clone()
//最近x年的开始年份
let start = this.maxYear.clone()
start.setFullYear(start.getFullYear() - val + 1)
this.start = start.clone()
},
点击确定按钮时将起始年份和结束年份导出
确定按钮绑定事件
<el-button size="small" type="primary" @click="handleClick">确定</el-button>
在导出前判断年份范围是否合法,并给出提示
如果年份范围合法,则父组件可以绑定get-year-range事件获取起始年份和结束年份
handleClick() {
let start = this.start.getFullYear()
let end = this.end.getFullYear()
if (start < this.years[0] || end > this.years[this.years.length - 1]) {
this.$message({
type: 'error',
message: '年份超出范围,请重新选择,范围为' + this.years[0] + '~' + this.years[this.years.length - 1]
})
} else if (start > end) {
this.$message({
type: 'error',
message: '起始年份不能大于结束年份,请重新选择'
})
} else {
this.$emit('get-year-range', start, end)
}
},
实现难点
在给Date赋值和修改时,仅仅用let date=Date,这种对象赋值是传递的引用,是浅拷贝的方式,每次更改变量值,都会修改原始的Date
这边需要用深拷贝的方式拷贝Date对象
//date类型的数据,单纯的赋值实际上是浅拷贝,指向同一个地址,所以当一个变量变化,这个地址也会跟着变,所以要用到深拷贝
Date.prototype.clone = function () {
return new Date(this.valueOf());
}
//最近x年的end
this.end = this.maxYear.clone()
如何使用
在script中导入组件
在components中声明组件
在template中使用
绑定get-year-range事件(两个参数,start,end)
相关代码
<template>
<div>
<div class="year-picker-box">
<el-date-picker
v-model="start"
type="year"
size="small"
style="width: 100px"
placeholder="开始年份"
>
</el-date-picker>
<span style="margin-left: 5px; margin-right: 5px">至</span>
<el-date-picker
v-model="end"
type="year"
size="small"
style="width: 100px; margin-right: 5px"
placeholder="结束年份"
>
</el-date-picker>
<el-button size="small" type="primary" @click="handleClick"
>确定</el-button
>
<br />
<div style="text-align: left">
<el-button
type="text"
size="small"
style="display: inline"
@click="handleShortCut(1)"
>最近一年</el-button
>
<el-button
type="text"
size="small"
style="display: inline"
@click="handleShortCut(3)"
>最近三年</el-button
>
<el-button
type="text"
size="small"
style="display: inline"
@click="handleShortCut(5)"
>最近五年</el-button
>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'YearRangePicker',
components: {
},
data() {
return {
years: [],
start: null,
end: null,
minYear: null,//年份最小值
maxYear: null,//年份最大值
}
},
created() {
this.getYears();
},
methods: {
getYears() {
this.axios({
url: 'grad/yearList',
methods: 'get'
}).then(res => {
this.years = res.data.data
this.years = this.years.sort(function (a, b) {
return a - b;
})
//最小年份,最大年份
this.minYear = new Date('' + this.years[0] + '-1-1')
this.maxYear = new Date('' + this.years[this.years.length - 1] + '-1-1')
//默认为最近一年
this.end = this.maxYear
this.start = this.maxYear
})
},
isEarlyThan(dateA, dateB) {
// dateA 比 dateB 早则为 true(严格小于)
const yearA = dateA.getFullYear();
const yearB = dateB.getFullYear();
if (yearA < yearB) {
return true;
} else {
return false;
}
},
handleShortCut(val) {
//date类型的数据,单纯的赋值实际上是浅拷贝,指向同一个地址,所以当一个变量变化,这个地址也会跟着变,所以要用到深拷贝
Date.prototype.clone = function () {
return new Date(this.valueOf());
}
//最近x年的end
this.end = this.maxYear.clone()
//最近x年的start
let start = this.maxYear.clone()
start.setFullYear(start.getFullYear() - val + 1)
this.start = start.clone()
},
handleClick() {
let start = this.start.getFullYear()
let end = this.end.getFullYear()
if (start < this.years[0] || end > this.years[this.years.length - 1]) {
this.$message({
type: 'error',
message: '年份超出范围,请重新选择,范围为' + this.years[0] + '~' + this.years[this.years.length - 1]
})
} else if (start > end) {
this.$message({
type: 'error',
message: '起始年份不能大于结束年份,请重新选择'
})
} else {
this.$emit('get-year-range', start, end)
}
},
disabledDate(time) {
//查阅过官方文档后,发现需要返回boolean值
return this.isEarlyThan(time, this.minYear) || this.isEarlyThan(this.maxYear, time);
}
}
}
</script>
<style scoped>
.year-picker-box {
padding: 10px;
width: 290px;
}
</style>
更多推荐
已为社区贡献1条内容
所有评论(0)