技术栈及三方库Vite+Vue3+TS+Pinia+Sass+Pug+Axios
安装依赖
构建Vite框架
# npm 6.x npm create vite@latest my-vue-app --template vue-ts
# npm 7+, extra double-dash is needed: npm create vite@latest my-vue-app -- --template vue-ts
安装pinia axios sass pug
npm i vue-router pinia
npm i element-plus axios
npm i sass pug -D
运行 npm run dev
一、项目初始化
1、创建公共文件base.sass定义全局样式
2、创建页面JingDong.vue、MailList.vue
3、定义路由
知识点配置导航守卫
全局导航守卫,所有页面,只要跳转进入某个页面,可以放行,也可以拦住不让访问
to要去的页面的路由对象,from是来自于哪里
beforeEach如果返回true就放行,如果返回false就拦截
//配置路由需要什么导入什么 ,
import { createRouter, createWebHashHistory } from 'vue-router'
import { getVal } from "../utils/storage";
const routes = [{
path: '/',
redirect: '/jd'
}, {
path: '/jd',
component: () => import('../pages/JingDong.vue')
}, {
path: '/mail-list',
component: () => import('../pages/MailList.vue')
}]
const router = createRouter({
routes,
//路由模式
history: createWebHashHistory()
})
// 全局导航守卫,所有页面,只要跳转进入某个页面,可以放行,也可以拦住不让访问
// to要去的页面的路由对象,from是来自于哪里
// beforeEach如果返回true就放行,如果返回false就拦截
router.beforeEach((to, from) => {
if (to.path === '/jd') return true
const token = getVal('token', '')
return !!token
// return token ? true : false
})
export default router
二、JingDong.vue、字段写入MailList.vue页面中
<template>
<div class="jd">
<div @click="$router.push('/mail-list?type=to')">
<p>收件人</p>
<h2 v-if="formData.to.name">{{ formData.to.name }}</h2>
<h2 v-else>选择收件人</h2>
</div>
<div @click="$router.push('/mail-list?type=from')">
<p>寄件人</p>
<h2 v-if="formData.from.name">{{ formData.from.name }}</h2>
<h2 v-else>选择寄件人</h2>
</div>
<div @click="show = true">
<p>期望上门时间</p>
<p>{{ formData.dateTime.label }} {{ formData.dateTime.startTime }}-{{ formData.dateTime.endTime }}</p>
</div>
<date-time v-if="show" :modelValue="formData.dateTime" />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { getVal, setVal } from '../utils/storage'
import defaultData from './default-data'
import DateTime from '../components/DateTime.vue'
// 选项式API
export default defineComponent({
components: { DateTime },
data() {
return {
formData: getVal('jd', defaultData),
show: false
}
},
// Vue3把destroy改成了unmount
beforeUnmount() {
setVal('jd', this.formData)
}
})
</script>
MailList.vue页面
知识点
正则的分组,小括号的分组匹配内容,可以在替换时用$加数字编号来时用
return str.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
<template>
<ul>
<li v-for="d in list" :key="d.name" @click="onClick(d)">
<p>{{ d.name }} - {{ hidePhone(d.phone) }}</p>
<p>{{ d.address }}</p>
<span v-if="formData[type].phone === d.phone">已勾选</span>
</li>
</ul>
</template>
<script>
import { getVal, setVal } from '../utils/storage'
import defaultData from './default-data'
export default {
data() {
return {
list: [{
name: '老王',
phone: '13677778888',
address: '北京昌平南口21号'
}, {
name: '老李',
phone: '13800138001',
address: '北京海淀中关村科技大厦'
}],
type: this.$route.query.type,
formData: getVal('jd', defaultData)
}
},
methods: {
hidePhone(str) {
// 正则的分组,小括号的分组匹配内容,可以在替换时用$加数字编号来时用
return str.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
},
onClick(d) {
this.formData[this.type] = d
setVal('jd', this.formData)
this.$router.push('jd')
}
},
}
</script>
存取数据页面storage.ts
const STORAGE_KEY = 'homework-storage'
function getData() {
return JSON.parse(localStorage.getItem(STORAGE_KEY) || '')
}
function setVal(key: string, val: any) {
const data = getData()
data[key] = val
localStorage.setItem(STORAGE_KEY, JSON.stringify(data))
}
function getVal(key: string, defaultVal: any) {
const data = getData()
return data[key] === undefined ? defaultVal : data[key]
}
export {
setVal,
getVal
}
把数据得默认值写入default-data.js文件中
const formData = {
// 收件人
to: { name: '', phone: '', address: '' },
// 寄件人
from: { name: '', phone: '', address: '' },
type: '上门取件', // 自送服务点
dateTime: getDateTime(),
info: {
weight: 1,
type: '',
remark: ''
},
checked: false
}
export default formData
上门取件默认值逻辑
默认取件时间是今天的下一个小时,上班时间早8点到晚6点
new Date()取当前时间,今天 ?月?日
取当前小时,如果小于7点,当做7点
取当前小时,如果大于晚上17点,明天来吧
/*
默认取件时间是今天的下一个小时,上班时间早8点到晚6点
new Date()取当前时间,今天 ?月?日
取当前小时,如果小于7点,当做7点
取当前小时,如果大于晚上5点,明天来吧
*/
function fillZero(n) {
return n < 10 ? '0' + n : n;
}
function getDateTime() {
const date = new Date()
const thisYear = date.getFullYear()
const thisMonthIndex = date.getMonth()
const thisDate = date.getDate()
// 开始的小时,截止的小时,取件的月份,取件的日,
let startHour, endHour, startMonth, startDate, label
const h = date.getHours() // 0-23
if (h >= 0 && h < 7) {
startHour = 8
startMonth = thisMonthIndex + 1
startDate = thisDate
label = '今天'
}
if (h > 17 && h <= 23) {
startHour = 8
const nextDate = new Date(thisYear, thisMonthIndex, thisDate + 1)
startMonth = nextDate.getMonth() + 1
startDate = nextDate.getDate()
label = '明天'
}
if (h >= 7 && h <= 17) {
startHour = h + 1
startMonth = thisMonthIndex + 1
startDate = thisDate
label = '今天'
}
endHour = startHour + 1
return {
label,
date: `${fillZero(startMonth)}-${fillZero(startDate)}`,
startTime: `${fillZero(startHour)}:00`,
endTime: `${fillZero(endHour)}:00`
}
}
创建一个utils 文件夹 storage文件内写入存储逻辑
const STORAGE_KEY = 'homework-storage'
function getData() {
return JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}')
}
function setVal(key: string, val: any) {
const data = getData()
data[key] = val
localStorage.setItem(STORAGE_KEY, JSON.stringify(data))
}
function getVal(key: string, defaultVal: any) {
const data = getData()
return data[key] === undefined ? defaultVal : data[key]
}
export {
setVal,
getVal
}
获取时间逻辑
<template>
<div class="date-time-mask">
<div class="date-time">
<div class="t">
期望上门时间
<button>X</button>
</div>
<div class="b">
<ul class="l">
<li
v-for="d in dateList"
:key="d.label"
:style="{ 'color': d.label === label ? 'white' : 'gray', 'background': d.label === label ? 'black' : 'white' }"
@click="label = d.label; date = d.date"
>{{ d.label }}</li>
</ul>
<ul class="r">
<li
v-for="d in timeList"
:key="d"
@click="onClick(d)"
>{{ d }}</li>
</ul>
</div>
</div>
</div>
</template>
<script>
function fillZero(n) {
return n < 10 ? '0' + n : n;
}
export default {
props: ['modelValue'],
data() {
return {
// 左边的备选项
dateList: [],
label: '', // 今天、明天、后天
date: '',
startTime: '',
endTime: ''
}
},
created() {
this.label = this.modelValue.label
this.date = this.modelValue.date
this.startTime = this.modelValue.startTime
this.endTime = this.modelValue.endTime
const date = new Date()
if (date.getHours() <= 17) {
this.dateList.push({
label: '今天',
date: fillZero(date.getMonth() + 1) + ':' + fillZero(date.getDate())
})
}
const thisYear = date.getFullYear()
const thisMonthIndex = date.getMonth()
const thisDate = date.getDate()
const nextDay1 = new Date(thisYear, thisMonthIndex, thisDate + 1)
this.dateList.push({
label: '明天',
date: fillZero(nextDay1.getMonth() + 1) + ':' + fillZero(nextDay1.getDate())
})
const nextDay2 = new Date(thisYear, thisMonthIndex, thisDate + 2)
this.dateList.push({
label: '后天',
date: fillZero(nextDay2.getMonth() + 1) + ':' + fillZero(nextDay2.getDate())
})
},
computed: {
timeList() {
const arr = [];
for (let i = 8; i < 18; i++) {
arr.push(`${fillZero(i)}:00-${fillZero(i + 1)}:00`)
}
if (this.label === '今天') {
const h = new Date().getHours()
if (h > 7) arr.splice(0, h - 7)
}
return arr
}
},
methods: {
onClick(d) {
console.log({
label: this.label,
date: this.date,
startTime: d.split('-')[0],
endTime: d.split('-')[1]
})
this.$emit('change', {
label: this.label,
date: this.date,
startTime: d.split('-')[0],
endTime: d.split('-')[1]
})
}
}
}
</script>
<style lang="sass">
.date-time-mask
position: fixed
top: 0
right: 0
bottom: 0
left: 0
background: rgba(0,0,0,.6)
.date-time
position: fixed
right: 0
bottom: 0
left: 0
height: 50vh
background: white
.b
display: flex
.l
flex: 1
.r
flex: 2
</style>