一、获取用户信息存入vuex

  1. api文件里添加获取用户信息的接口
// 该函数专门用于:根据token获取用户信息
export const reqUserInfo = () => ajax.get('/user/passport/auth/getUserInfo')
  1. store/user.js文件里编写代码获取用户信息



前端vue项目打镜像_前端vue项目打镜像


前端vue项目打镜像_前端vue项目打镜像_02


import引入reqUserInfo,将用户信息存入vuex。

二、导航守卫

  1. 概念:路由跳转时,在特定的时刻,执行的一些函数
  2. 作用:可以在路由跳转时追加特殊逻辑(路由鉴权、获取用户信息等)
  3. 导航守卫越早使用越好
  4. 分类:

全局守卫(常用)===> 校门口看门的大爷
路由独享守卫===>宿舍楼值班的老师
组件内守卫===>某个班的班主任

  1. 项目中用到导航守卫的原因

每次路由跳转、刷新页面时,都要靠守卫,获取用户信息
对某些敏感路由做出访问限制(鉴权)

  1. 导航守卫一定要有出口===>next()
  2. 找到router/index.js文件配置全局导航守卫,要有一个鉴权名单
// 路由鉴权列表
const authPath = ['/trade']


前端vue项目打镜像_验证码_03


  1. 路由鉴权:在用户没有登录的时候有些路由可以自由访问,会降低隐私权,所以需要路由鉴权

在全局导航守卫中追加几个规则

// 路由鉴权列表
const authPath = ['/trade','/pay','/paysuccess','/center']

细化鉴权:回到routes.js文件中给pay、addcart_success追加路由独享守卫

{
        name:'addcart_success',
        path:'/addcart_success',
        component:AddCartSuccess,
        // 只要命中该路由规则,beforeEnter就会执行
        // 目标:只有从/detail才能到此处
        beforeEnter: (to, from, next) => {
            if (from.path.slice(0,7) === '/detail') {
                next()
            }else{
                next('/home')
            }
      }
 },
 {
        name:'pay',
        path:'/pay',
        component:Pay,
        beforeEnter: (to, from, next) => {
            if (from.path === '/trade') {
                next()
            }else{
                next('/home')
            }
        }
  },

到PaySuccess组件文件中追加组件内守卫

// beforeRouteEnter在路由规则匹配后,马上要挂载PaySuccess组件前调用
    beforeRouteEnter(to,from,next){
      if (from.path === '/pay') {
        next()
      }else{
        next('/home')
      }
    }

三、交易路由

(一)路由鉴权,已经在全局导航守卫中实现
(二)切换地址

绑定点击事件,传入参数,接着在methods中写回调

// 切换收货地址的回调
      changeAddress(id){
        this.addressList.forEach((address)=>{
          if (address.id === id) {
            address.isDefault = '1'
          }else{
            address.isDefault = '0'
          }
        })
      },

四、支付路由

(一)弹窗+显示二维码

弹窗还是使用element-ui来实现,将支付链接转为二维码(base64格式)

async handlePay(){
        try{
          // 将支付按钮转接为二维码(base64格式的)
          let base64Url = await QRCode.toDataURL(this.payInfo.codeUrl)
          // 准备一个html字符串,弹窗中显示
          const htmlStr = `<img src="${base64Url}" style="width:200px">`
          // 弹窗配置项
          const options = {
            dangerouslyUseHTMLString: true, //编译html代码
            title:'微信扫码支付', //弹窗标题
            center:true, //格式居中
            showClose:false, //右上角的叉
            showCancelButton:true, //取消按钮
            cancelButtonText:'支付遇到问题', //取消按钮文本内容
            confirmButtonText:'已完成支付' //确认按钮文本内容
        }
          // 使用element-ui弹窗
          this.$alert(htmlStr,  {
          ...options,
          callback:async(action) => {
            if (action === 'confirm') {
              // 停止心跳
              clearInterval(this.heartbeatID)
              // 询问服务器是否支付成功
              const result = await reqPayStatus(this.payInfo.orderId)
              if (result.code === 200) {
                this.$message.success('支付成功!')
                // 支付成功跳转成功
                this.$router.push('/paysuccess')
              }else{
                this.$message.warning('你的订单并未支付成功,请点击立即支付,重新付款!')
              }
            }else{
              // 停止心跳
              clearInterval(this.heartbeatID)
              // 提示
              this.$message.warning('若支付遇到问题,请致电客服解决!')
            }
        }
        });
(二)心跳请求

在用户还未支付时使用心跳请求来发请求,直到用户支付成功或是支付遇到问题停止心跳

// 发起心跳请求
          this.heartbeatID = setInterval(async ()=>{
          // 联系服务器查看订单状态
          const result = await reqPayStatus(this.payInfo.orderId)
          // 判断订单状态
          if (result.code === 200) {
            // 支付成功
            // 停止心跳
            clearInterval(this.heartbeatID)
            // 关闭弹窗
            this.$msgbox.close()
            // 跳转到支付成功路由
            this.$router.push('/paysuccess')
          }
          },1000) 
      }catch (error){
          this.$message.warning('支付二维码生成失败,请联系管理员!')
        }
      }

五、vee-validate表单验证

vee-validate是专门用来做表单验证的vue插件

(一)、安装npm install vee-validate@"<3.0.0" --save(vue2专用)
(二)、去src/utils/reg.js中补充几个正则
// 手机号正则
export const phoneReg = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
// 验证码正则
export const codeReg = /^\d{6}$/
// 密码正则
export const pwdReg = /^\w{6,21}$/
(三)、为了方便管理,在utils/validate.js中写规则
import Vue from 'vue';
import VeeValidate, { Validator }  from 'vee-validate';
import zh_CN from 'vee-validate/dist/locale/zh_CN';
import { phoneReg,codeReg,pwdReg } from "@/utils/reg";

Vue.use(VeeValidate);
Validator.localize('zh_CN', zh_CN);

// 自定义一个校验手机的正则
Validator.extend('phone_rule',{
    getMessage: field => {
        return '手机号不合法!'
    },
    validate: value => {
        return phoneReg.test(value)
    }
})
// 验证必要性的规则
Validator.extend('required',{
     // 验证规则
     validate:(value) => { // value你输入的值
       return value
     },
     // 验证失败的回调
     getMessage:(field) => {
        return field + '必须输入!'
     }
})
// 验证码的验证规则
Validator.extend('code_rule',{
     // 验证规则
     validate:value => codeReg.test(value),
     // 验证失败的回调
     getMessage:field => '验证码必须为6位数字!',
})
// 密码的验证规则
Validator.extend('pwd_rule',{
      // 验证规则
      validate:value => pwdReg.test(value),
      // 验证失败的回调
      getMessage:filed => '密码为6到21位英文、数字、下划线!',
})
// 确认密码的验证规则
Validator.extend('ispwd',{
      // 验证规则
      validate:(value,args) => value === args[0],
      // 验证失败的回调
      getMessage:filed => '密码必须一致!',
})
// 协议同意的验证规则
Validator.extend('isagree',{
    // 验证规则
    validate:value => value,
    // 验证失败的回调
    getMessage:filed => '协议必须同意!',
})
(四)、在main.js中引入utils/validate.js
import '@/utils/validate'
(五)、验证输入项
<div class="content">
        <label>手机号:</label>
        <input
          v-validate="'required|phone_rule'"
          name="手机"
          v-model="phone"
          type="text"
          placeholder="请输入你的手机号"
        />
        <span class="error-msg">{{ errors.first('手机') }}</span>
      </div>

      <div class="content">
        <label>验证码:</label>
        <input
          v-model="code"
          type="text"
          placeholder="请输入验证码"
          v-validate="'required|code_rule'"
          name="验证码"
        />
        <button class="getcode" @click="getCode">获取验证码</button>
        <span class="error-msg">{{ errors.first("验证码") }}</span>
      </div>

      <div class="content">
        <label>登录密码:</label>
        <input
          v-model="password"
          type="text"
          placeholder="请输入你的登录密码"
          v-validate="{ required: true, pwd_rule: true }"
          name="密码"
        />
        <span class="error-msg">{{ errors.first("密码") }}</span>
      </div>

      <div class="content">
        <label>确认密码:</label>
        <input
          type="text"
          placeholder="请输入确认密码"
          v-model="re_password"
          v-validate="{ required: true, ispwd: password }"
          name="重复密码"
        />
        <span class="error-msg">{{ errors.first("重复密码") }}</span>
      </div>

      <div class="controls">
        <input
          v-model="agree"
          type="checkbox"
          v-validate="{ isagree: true }"
          name="协议"
        />
        <span>同意协议并注册《优选商城用户协议》</span>
        <span class="error-msg">{{ errors.first("协议") }}</span>
      </div>

六、懒加载

  1. 什么是懒加载?

其实就是延迟加载,即当需要用到的时候再去加载
优点:减少网络开销,节约网络流量

  1. 在路由组件中这样引入


前端vue项目打镜像_验证码_04


  1. 图片懒加载

控制台引入npm i vue-lazyload@1

在main.js文件中引入


前端vue项目打镜像_验证码_05


找到搜索页面将图片位置改为

<img v-lazy="good.defaultImg"/>

结语:今天总算是完成了这个项目,战线拉得蛮长的,在做的过程中查缺补漏,也学到了不少的新东西。一定一定要将基础打好,接下来就开启下一阶段的学习了,加油!