vue 实现移动端年周时间选择
- 使用组件
- 样式实现
- 代码实现
使用组件
Vant 是有赞前端团队开源的移动端组件库,点击跳转
样式实现
代码实现
<template>
<div id="root">
<van-nav-bar left-arrow @click-left="returnHandle()">
<template #title>
<span class="nav-title">统计分析</span>
</template>
</van-nav-bar>
<div class="statistical-top">
<div class="top-time">
<div class="top-time-left">
时间:{{time}}
</div>
<div class="top-time-right">
<div class="top-time-right-arrow" @click="arrowtitleHanlde" style="flex:1" >
<span :class="arrowTitle?'top-time-right-arrow-title':' top-time-right-arrow-title-active'">{{arrowTitledetail}}</span>
</div>
<div @click="arrowtimeHanlde" class="top-time-right-arrow" style="flex:1.1">
<span :class="arrowTime?'top-time-right-arrow-time':' top-time-right-arrow-time-active'">{{arrowTimedetail}}</span>
</div>
</div>
</div>
</div>
<!-- columns -->
<van-action-sheet v-model="arrowTitle">
<van-picker
title="查询数据"
show-toolbar
:columns="columns"
@confirm="onConfirm"
@cancel="onCancel"
@change="onChange"
/>
</van-action-sheet>
<van-action-sheet v-model="arrowTime">
<van-picker
class="week"
show-toolbar
title="选择日期"
:columns="columns4"
@change="onChange5"
@confirm="onConfirm5"
@cancel="onCancel5"
/>
</van-action-sheet>
</div>
</template>
<script>
export default {
data() {
return {
columns4: [],
year: [2021, 2022, 2023, 2024, 2025, 2026]
}
},
created() {
this.arrowTitledetail = this.columns[0]
this.time = this.renderTime(this.currentDate).nTime
this.week()
},
methods: {
formatDig(num) {
return num > 9 ? '' + num : '0' + num
},
formatDate(mill) {
var y = new Date(mill)
let raws = [
this.formatDig(y.getMonth() + 1),
this.formatDig(y.getDate()),
''
]
let format = ['月', '日']
return String.raw({ raw: raws }, ...format)
},
* createWeeks(year) {
const oneday = 24 * 3600 * 1000
let start = new Date(year, 0, 1)
let end = new Date(year, 11, 31)
let firstDay = start.getDay() || 7
let lastDay = end.getDay() || 7
let startTime = +start
let endTime = startTime + (7 - firstDay) * oneday
let _endTime = end - (7 - lastDay) * oneday
yield [startTime, endTime]
startTime = endTime + oneday
endTime = endTime + 7 * oneday
while (endTime < _endTime) {
yield [startTime, endTime]
startTime = endTime + oneday
endTime = endTime + 7 * oneday
}
yield [startTime, +end]
},
week() {
let arr = []
for (let j = 0; j < this.year.length; j++) {
console.log(this.year[j])
let obj = {
text: this.year[j] + '年',
children: []
}
let index = 1
for (let i of this.createWeeks(this.year[j])) {
let start = i[0]
let end = i[1]
let obj1 = {
text: `第${this.formatDig(index++)}周 ${this.formatDate(start)}-${this.formatDate(end)}`,
time: `${this.formatDate(start)}-${this.formatDate(end)}`
}
console.log(`第${this.formatDig(index++)}周 ${this.formatDate(start)}-${this.formatDate(end)}`)
obj.children.push(obj1)
}
arr.push(obj)
}
console.log(arr)
this.columns4 = arr
},
onConfirm5(value, index) {
console.log(`当前值:${value}, 当前索引:${index}`)
this.arrowTime = !this.arrowTime
},
onChange5(picker, value, index) {
console.log(`当前值:${value}, 当前索引:${index}`)
// this.arrowTimedetail = value
console.log(value)
this.arrowTimedetail = value.join('')
let str = value[1].split(' ')[0]
this.time = value[0] + str
},
onCancel5() {
console.log('取消')
this.arrowTime = !this.arrowTime
}
}
}
</script>
<style lang="less" scoped>
#root::before{
content: ' ';
position: fixed;
z-index: -1;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #f5f5f5;;
background-size: 100% auto;
}
#root{
width: 100%;
height: 100%;
background-color: #f5f5f5;
position: relative;
}
.nav-title{
color: #fff;
font-weight: 700
}
.van-nav-bar{
background-color: #254454;
}
/deep/ .van-nav-bar .van-icon {
color: #fff!important;
}
.statistical-top{
height: 200px;
background-color: #fff;
font-size: 15px;
color: #333333;
font-weight: 500;
box-sizing: border-box;
padding: 10px;
.top-time{
display: flex;
align-items: center;
justify-content: space-between;
.top-time-left{
flex: 1;
}
.top-time-right{
flex: 1.3;
display: flex;
align-items: center;
justify-content: space-around;
font-size: 14px;
.top-time-right-arrow{
position: relative;
flex: 1;
text-align: center;
color: #666666;
.top-time-right-arrow-time,
.top-time-right-arrow-time-active{
position: relative;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
margin-right: 8px;
padding: 3px 20px 3px 5px;
background-color: #f5f5f5;
border-radius: 5px;
line-height: 20px;
}
.top-time-right-arrow-title,.top-time-right-arrow-title-active{
position: relative;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
margin-right: 8px;
padding: 3px 20px 3px 5px;
background-color: #f5f5f5;
border-radius: 5px;
line-height: 20px;
}
.top-time-right-arrow-title::before,.top-time-right-arrow-time::before,
{
position: absolute;
top: 10px;
left: 80%;
content: '';
width: 0;
height: 0;
border-right: 5px solid transparent;
border-left: 5px solid transparent;
border-bottom: 5px solid #666;
}
.top-time-right-arrow-title-active::before,.top-time-right-arrow-time-active::before{
position: absolute;
top: 10px;
left: 80%;
content: '';
width: 0;
height: 0;
border-right: 5px solid transparent;
border-left: 5px solid transparent;
border-bottom: 5px solid #666;
transform: rotate(180deg);
transition: background-color .3s;
}
.top-time-right-arrow-time::before,
.top-time-right-arrow-time-active::before{
left: 85%;
}
}
}
}
}
/deep/ .van-picker__confirm{
color: #12B0BC;
}
/deep/ .week{
.van-picker__columns{
justify-content: space-around;
.van-picker-column:nth-child(1){
flex: 1;
}
.van-picker-column:nth-child(2){
flex: 2;
}
}
}
</style>