点单/选择日期功能(无样式)

技术栈及三方库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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端-JC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值