前端Vue项目:旅游App-(12)home-Calendar:日期选择日历动态显示时间
Posted karshey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端Vue项目:旅游App-(12)home-Calendar:日期选择日历动态显示时间相关的知识,希望对你有一定的参考价值。
文章目录
目标
点击时间:
弹出日历供选择:
动态显示数据:
过程与代码
安装依赖
先安装一个很好用的日期库:
npm install dayjs
结构样式
目标:数据先是静态的。
html:
<div class="section time-range">
<div class="start">
<span>入住</span>
<div class="time">
6月13日
</div>
</div>
<div class="stay">共一晚</div>
<div class="end">
<span>离店</span>
<div class="time">
6月14日
</div>
</div>
</div>
css:
.search-box
// search-box里的每个部分都加上section
// 都有类似的样式
.section
display: flex;
padding: 0 20px;
color: #999;
.location
height: 44px;
display: flex;
align-items: center;
padding: 0 20px;
color: #53565c;
.city
// flex:1 === flex:1 1 auto 除了position之外的剩余部分都属于city
flex: 1;
.position
width: 74px;
display: flex;
align-items: center;
.text
font-size: 12px;
img
width: 20px;
margin-left: 5px;
.time-range
display: flex;
justify-content: space-between;
span
font-size: 16px;
color: #53565c;
注意,我们令跟搜索有关的为search-box:
search-box里每个部分都添加section这个类:因为每个部分的样式都是相似的,比如都是flex布局,padding都是0 20px。
动态数据:默认数据今天明天
一般搜索票的默认数据:
- 开始时间:今天
- 结束时间:明天
如果我们直接使用new Date,得到的会是:Tue Jan 10 2023 22:05:28 GMT+0800 (中国标准时间)
而我们想要显示的是MM月DD日。显然我们需要写一个格式化的函数。一般这种工具类的代码会放在utils里。
formatMonthDay.js:
import dayjs from 'dayjs'
export function formatMonthDay(date)
return dayjs(date).format('MM月DD日')
在home中获取今天和明天:要响应式
const today = new Date()
const startDay = ref(formatMonthDay(today))
const endDay = ref(formatMonthDay(today.setDate(today.getDate() + 1))) //明天写法
效果:
添加日历
Calendar 日历 - Vant 4 (gitee.io)
查看文档,对应的属性和事件分别为:
- :value=“date”:date为数组结构,数组第一项为开始时间,第二项为结束时间。
- showCalendar:是否显示日历
- type=range:选择日期范围的日历(属性)
- confirm:日期选择完成后触发(事件)
- show-confirm:为true则点击确认后再触发confirm事件,否则直接触发(属性)
代码:
<div class="section time-range" :value="date" @click="showCalendar = true">
<div class="start">
<span>入住</span>
<div class="time">
startDay
</div>
</div>
<div class="stay">共一晚</div>
<div class="end">
<span>离店</span>
<div class="time">
endDay
</div>
</div>
</div>
<!-- 日历 -->
<van-calendar v-model:show="showCalendar" type="range" @confirm="onConfirm" />
js:
// 日历
const date = ref('');
const showCalendar = ref(false);
const formatDate = (date) => `$date.getMonth() + 1/$date.getDate()`;
const onConfirm = (values) =>
const [start, end] = values;
showCalendar.value = false;
date.value = `$formatDate(start) - $formatDate(end)`;
;
效果:
点击后显示:
修改样式
修改弹出的日期高度:–van-calendar-popup-height
圆角弹窗:
动态数据:显示日历中选择的数据
让页面显示的数据是在日历里选择的数据。
html中都使用模板字符串:
js:
// 日历
const date = ref('1');
const showCalendar = ref(false);
const formatDate = (date) => `$date.getMonth() + 1/$date.getDate()`;
const onConfirm = (values) =>
const [start, end] = values;
showCalendar.value = false;
startDay.value = formatMonthDay(start)
endDay.value = formatMonthDay(end)
date.value = getDiffDate(start, end)
;
注意,可以封装获取日期差的方法:
// end-start
export function getDiffDate(start, end)
return dayjs(end).diff(start, 'day')
效果:
效果
达成。
总代码
修改或添加的文件
formatDate.js
封装跟日期相关的方法。
import dayjs from 'dayjs'
// 格式化“x月x日”
export function formatMonthDay(date)
return dayjs(date).format('MM月DD日')
// end-start
export function getDiffDate(start, end)
return dayjs(end).diff(start, 'day')
home.vue
增加日期选择、日历。
<template>
<div class="home">
<div class="nav-bar">
<div class="title">旅游App</div>
<div class="banner">
<img src="@/assets/img/home/banner.webp" alt="">
</div>
</div>
<div class="search-box">
<div class="section location">
<div class="city">
<router-link to="/city"> cityStore.currentCity.cityName </router-link>
</div>
<div class="position">
<div class="text">我的位置</div>
<img src="@/assets/img/home/icon_location.png" alt="">
</div>
</div>
<div class="section time-range" :value="date" @click="showCalendar = true">
<div class="start">
<span>入住</span>
<div class="time">
startDay
</div>
</div>
<div class="stay">共 date 晚</div>
<div class="end">
<span>离店</span>
<div class="time">
endDay
</div>
</div>
</div>
<!-- 日历 -->
<van-calendar :round="false" v-model:show="showCalendar" type="range" @confirm="onConfirm"
:show-confirm="false" />
</div>
</div>
</template>
<script setup>
import useCityStore from '../../store/modules/city';
import formatMonthDay, getDiffDate from '@/utils/formatDate'
import ref from 'vue';
const cityStore = useCityStore()
// 日期
const today = new Date()
const startDay = ref(formatMonthDay(today))
const endDay = ref(formatMonthDay(new Date().setDate(today.getDate() + 1))) //明天写法
// 日历
const date = ref('1');
const showCalendar = ref(false);
const formatDate = (date) => `$date.getMonth() + 1/$date.getDate()`;
const onConfirm = (values) =>
const [start, end] = values;
showCalendar.value = false;
startDay.value = formatMonthDay(start)
endDay.value = formatMonthDay(end)
date.value = getDiffDate(start, end)
;
</script>
<style lang="less" scoped>
.home
.nav-bar
.title
height: 46px;
// flex居中,以后左右有东西可以直接加
display: flex;
align-items: center;
justify-content: center;
color: var(--primary-color);
font-size: 16px;
font-weight: 700;
.banner
// 图片本身大很多,让它大小刚好
img
width: 100%;
.search-box
--van-calendar-popup-height: 100%;
// search-box里的每个部分都加上section
// 都有类似的样式
.section
display: flex;
padding: 0 20px;
color: #999;
.location
height: 44px;
display: flex;
align-items: center;
padding: 0 20px;
color: #53565c;
.city
// flex:1 === flex:1 1 auto 除了position之外的剩余部分都属于city
flex: 1;
.position
width: 74px;
display: flex;
align-items: center;
.text
font-size: 12px;
img
width: 20px;
margin-left: 5px;
.time-range
display: flex;
justify-content: space-between;
span
font-size: 16px;
color: #53565c;
</style>
main.js
引入日历组件。
以上是关于前端Vue项目:旅游App-(12)home-Calendar:日期选择日历动态显示时间的主要内容,如果未能解决你的问题,请参考以下文章
前端Vue3+Vant4项目:旅游App-项目总结与预览(已开源)