vue3项目第三天学习总结

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的区别 6440bcdd345417b1338b6957773f3a5.png

// 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位之间数字,1表示第一组,1表示第一组,2表示第二组, 11 ******** 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>