1、发送验证码
- 校验手机号
- 使用vant上的form实例里的validate方法
- 点击发送验证码请求
- 成功提示
- 倒计时
const form = ref<FormInstance>()
const time = ref(0)
+let timeId: number
const send = async () => {
if (time.value > 0) return
await form.value?.validate('mobile')
await sendMobileCode(mobile.value, 'login')
Toast.success('发送成功')
time.value = 60
// 倒计时
clearInterval(timeId)
timeId = window.setInterval(() => {
time.value--
if (time.value <= 0) window.clearInterval(timeId)
}, 1000)
}
onUnmounted(() => {
window.clearInterval(timeId)
})
2、svg矢量图打包
- 安装插件:install vite-plugin-svg-icons -D
- 使用插件:
// 在vite.config.ts中添加
import { VantResolver } from 'unplugin-vue-components/resolvers'
+import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
+import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
Components({
dts: false,
resolvers: [VantResolver({ importStyle: false })]
}),
+ createSvgIconsPlugin({
+ // 指定图标文件夹,绝对路径(NODE代码)
+ iconDirs: [path.resolve(process.cwd(), 'src/icons')]
+ })
],
// 导入到main.ts
import router from './router'
+import 'virtual:svg-icons-register'
import 'vant/lib/index.css'
//使用svg精灵地图
<svg aria-hidden="true">
<!-- #icon-文件夹名称-图片名称 -->
<use href="#icon-login-eye-off" />
</svg>
3、倒计时
点击获取短信验证码按钮通过time是否等于0来进行切换。
// 校验是否在倒计时状态
const time = ref(0)
const send = async () => {
// 已经倒计时time的值大于0,此时不能发送验证码
if (time.value > 0) return
}
// 校验手机表单项,使用form组件
<van-field
v-model="mobile"
name="mobile"
:rules="mobileRules"
placeholder="请输入手机号"
type="tel"
></van-field>
const form = ref<FormInstance>()
const time = ref(0)
const send = async () => {
if (time.value > 0) return
// 验证不通过报错,阻止程序继续执行
await form.value?.validate('mobile')
}
// 发送短信验证码
const send = async () => {
if (time.value > 0) return
await form.value?.validate('mobile')
await sendMobileCode(mobile.value, 'login')
Toast.success('发送成功')
}
// 最后要在组件上卸载关闭定时器
onUnmounted(() => { window.clearInterval(timeId)})
4、密码登录
点击眼睛密码显示与隐藏
- 定义开关 show - false
- 点击icon切换
<van-field
v-if="isPass"
v-model="password"
:rules="passwordRules"
placeholder="请输入密码"
:type="show ? 'text' : 'password'"
>
<template #button>
<cp-icon @click="show = !show" :name="`login-eye-${show ? 'on' : 'off'}`"></cp-icon>
</template>
</van-field>
<van-field v-else placeholder="短信验证码">
<template #button>
<span class="btn-send">发送验证码</span>
</template>
</van-field>
5、token拦截
vueRouter3和vueRouter4的区别
// token 拦截
const whiteList = ['/login']
router.beforeEach((to) => {
const userStore = useUserStore()
if (!userStore.user?.token && !whiteList.includes(to.path)) return '/login'
})
6、切换页面标题—使用路由元信息,这个在路由后置守卫里面实现
router.afterEach((to) => {
document.title = to.meta.title || ''
})
6、增加nprogress模块提升体验
// 安装插件
pnpm add nprogress
pnpm add @types/nprogress -D
// 引入插件
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// 路由前置守卫开启
router.beforeEach((to) => {
+ NProgress.start()
//路由后置守卫关闭
router.afterEach((to) => {
// 修改标题
document.title = `${to.meta.title || ''}-优医问诊`
NProgress.done()
})
//配置插件 修改颜色
NProgress.configure({
showSpinner: false
})
//main.css 修改进度条背景色
#nprogress .bar {
background-color: var(--cp-primary) !important;
}
7、vant徽标的使用
<van-badge :content="user?.orderInfo.receivedNumber || ''">
<cp-icon name="user-shipped" />
<p>待发货</p>
</van-badge>
8、骨架屏的使用
// 骨架屏使用vant的Skeleton组件,通过判断数据是否渲染进行显示
<van-skeleton title :row="3" />
9、退出登录
- 设置点击事件
- 确认框提示
- 确认后清空token(pinia)
- 跳转到登录界面
10、身份证脱敏
身份证脱敏即对身份证号里面的11位数字进用 * 替换。
// 方法一、用提取字符串方式实现
const id = '340918199312225311
const temp = id.substring(4, 15)
console.log(id.replace(temp, '********'))
// 方法二、正则表达式
const id = '340918199312225311'
id.replace(/^(.{6}).+(.{4})$/, '\$1********\$2')
在上面的这正则里面(.{6})表示6位通配符,(.{4})表示4位通配符, .+取6到4位之间数字,2表示第二组, 2 => 340918********5311
11、v-model语法糖
// Vue3中v-model之xxx.sync语法糖完整写法
// 父组件Parent
<template>
<div>
<h1>playground1234567</h1>
<son-com :money="money" @update:money="money = money - $event"></son-com>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import SonCom from './SonCom.vue'
const money = ref(100)
</script>
<style scoped></style>
// 子组件
<template>
<div>
<button @click="costMoney">来消费啊</button>
{{ money }}
</div>
</template>
<script setup lang="ts">
defineProps<{
money: number
}>()
const emit = defineEmits<{
(e: 'update:money', val: number): void
}>()
const costMoney = () => {
emit('update:money', 10)
}
</script>
<style scoped></style>
// vue3中的v-model语法糖简写版
// 父组件
<template>
<div>
<h1>playground1234567</h1>
<son-com v-model:money="money"></son-com> // 这里做了简写
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import SonCom from './SonCom.vue'
const money = ref(100)
</script>
<style scoped></style>
// 子组件
<template>
<div>
<button @click="costMoney">来消费啊</button>
{{ money }}
</div>
</template>
<script setup lang="ts">
const props = defineProps<{
money: number
}>()
const emit = defineEmits<{
(e: 'money', val: number): void
}>()
const costMoney = () => {
emit('money', props.money + 10)
}
</script>
<style scoped></style>