一、注册部分
1、v-model 双向绑定收集表单数据到data中
(data===vc._data,最后会通过Object.defineProperty中的getter与setter,收集的数据会放到vc身上)
2、注册手机验证码接口/api/user/passport/sendCode/phone ,phone手机号码位必选项
(1)配置axios
//注册页面 验证码 /api/user/passport/sendCode/phone 这里需要传递一个参数phone手机号【验证后的】给服务器
export const reqSendCode=(phone)=>{
//用户没有输入电话的情况,控制台会有错误
return phone ? axs({method:'get',url:`/api3/user/passport/sendCode/${phone}`}) : '';//传递手机号 这里走的/api3代理
}
--配置引入的axios实例对象axs,使用模块化分别暴露,暴露函数(函数返回axios请求实例对象)
--这里我们url路径上使用的/api3,走的是'/api3'的代理,处理跨域问题。
--函数接收参数,并通过模板字符串写入url路径
(2)使用vuex对应组件小仓库
async getYanZhenCode({commit},phone){
let response=await reqSendCode(phone);//传递参数【手机号】
if(response.code===200){
commit('GETYANZHENCODE',response.data);//成功就联系mutations把服务器返回的验证码传递过去
return 'ok';//调用函数返回一个成功的promise对象,告诉对应调用此函数的dispatch【的组件】,我注册成功了
}
else{
return Promise.reject(new Error('err'));//返回一个失败的promise对象
}
}
--导入请求函数reqSendCode,actions对象中配置async函数使用await等待请求出结果并拿到服务器返回的整个数据对象,调用reqSendCode函数发起请求返回一个带有状态 带有数据的promise对象【成功或失败】
--await等待请求出结果以后,根据服务器返回的状态code返回相应的状态的promise对象,失败会抛出错误【调用此async函数时返回】
--async函数返回一个普通的类型数据时,就是返回一个成功状态的promise对象
async function fn(){
return await 'ok';
}
或
async function fn1(){
return 'ok';
}
--以上两种情况都会返回一个成功的promise对象,并且该promise对象所携带的参数就是async函数所返回的普通数据类型的数据
(3)点击 button获取验证码按钮回调
async getCode(e){//点击一次后将其变为disabled的30秒不能点击状态 let reg=/^[\d]{11}$/;//手机号长度校验 if(reg.test(this.phone)) {//手机号长度够了才可以走后面的 请求 try { // let {phone}=this ;//从组件实例身上解构赋值 手机号这个数据 //手机号有了,不为空,就执行后面的联系actions请求并传入手机号 // phone && (await this.$store.dispatch('RegisterVc/getYanZhenCode',this.phone)); await this.$store.dispatch('RegisterVc/getYanZhenCode', this.phone);//联系actions发请求,把电话传递给服务器 this.code = this.yanZhenCode;//使用映射过来的数据 e.target.disabled = true;//禁用 e.target.style.cursor = 'not-allowed'; let s = 10, timer = null; timer = setInterval(() => { this.btnCodeText = s; s--; if (s < 0) { e.target.disabled = false;//解除禁用 this.btnCodeText = '获取验证码'; e.target.style.cursor = 'pointer'; clearInterval(timer); } }, 1000);//每一秒执行一次定时器中的函数 } catch (err) { // alert(err.message) console.log(err) } } else{ alert('手机号码不符合规定') } },
--这里回调主要是联系actions对应函数,发请求,传递手机号过去
--在这里使用了正则校验输入的号码长度
--使用try catch捕获dispatch联系actions中函数返回的状态的错误
--e.target.dispatch=true 禁用
--这里请求成功服务器会返回数据 验证码【正常情况下是服务器发送短信到对应手机号码的用户手机上】
使用:axios 、vuex、脚手架代理、模块化、模板字符串、 async与await、Promise、dispatch、v-model、正则表达式、定时器、事件对象、点击事件、methods配置项、mapState映射组件仓库数据
3、点击注册按钮部分
注册部分要传递 手机号码 ,验证码 ,密码(三个必选项)到服务器
(1)配置axios实例
//用户注册 /api/user/passport/register 传手机号,密码,验证码给服务器 ,如果手机号未被注册会被存入数据库中
export const reqUserRegister=(data)=>{//接收actions中调用此函数返回过来的表单参数
return axs({
method:'post',
url:'/api3/user/passport/register',
data,//传给服务器
})
}
--这里我们使用axios中data属性传递给服务器
--路径中的/api3,走的是 'api3'代理,解决跨域
(2)使用对应组件vuex小仓库(集中式状态管理)
async getUserRegister(_,user) {//因为只是把注册表单数据传递给服务器 存入数据库中,不会返回数据,不需要使用commit联系mutations,使用占位符占一个store位置。
let response=await reqUserRegister(user)
if(response.code===200){//根据服务器返回的状态
return 'ok'; //async函数返回一个普通类型数据时,都是一个成功的promise对象返回
}
else{
return Promise.reject(new Error('err'));
}
}
--(在dispatch联系actions此函数传)这里接收表单用户数据信息,并传给reqUserRegister函数
--根据服务器返回的数据状态,async返回返回相应成功或失败(抛出错误)的promise对象
(3)点击注册后的回调
这里主要就是拿收集好的表单用户数据,通过dispatch联系actions对应async函数时传入参数
async userRegister(){
//解构实例身上收集的表单数据
let {phone,code,password,password1} =this;
//表单数据都不为空,就走后面,联系actions发请求传参数【表单用户注册数据】 对象属性属性值的简写形式传参 ,联系actions请求函数会返回一个成功或失败的promise对象
try{
(phone && code && password===password1) && await this.$store.dispatch('RegisterVc/getUserRegister',{phone,code,password});//这里要传递参数
//成功以后【服务器将表单用户注册数据存入数据库中】进行路由跳转到登陆页面
this.$router.push({
name:'login'
})
}
catch(err) {//请求传参给服务器失败【服务器没有把用户信息存入数据库中】,可能是用户电话已被注册
alert(err.message)
}
}
--根据dispatch联系actions对象中对应async函数所返回的成功或失败的promise对象【抛出错误】使用try catch捕获错误 ,成功进行路由跳转【编程式路由导航】(服务器就会把用户数据存入数据库中)。
--这里服务器不会给我们返回数据,只是根据所传递的参数【手机号码,验证码,密码】给我们注册【数据库中操作】
使用:axios、vuex、 事件回调、dispatch
二、登录部分
1、
已经注册成功的用户信息【账号密码】传入服务器后会被存入数据库中。 登录时,发请求把账号和密码传给服务器,服务器拿着账号与密码到数据库查询比对,如果一致的话进行下一步【看具体要干什么】--路由跳转到Home首页【收集用户名与密码】 【配置axios 带参】 【配置vuex】 【点击登录按钮发请求】 --请求方式要正确 这里是post方式【写错的话就是201 错误了】 --所传递的参数要与接口文档参数名称要一致【不一致的话会返回202 参数不正确】 --别忘走代理 这里走的是api3代理 解决跨域 --成功的话,服务器会返回数据【包括token字符串令牌】 【请求路径错了会报错,返回失败的promise对象】 【请求方式写错了,不会报错,但会返回201 错误】 【请求成功了,用户信息有误,会根据信息的错误类型返回相应数据以及状态码】 【登陆业务】 ----【token服务器返回的,用户身份唯一标识】(就像身份证) ----【一般情况下登录后,只会返回一个token令牌】 ----【我们登陆后就是拿着token令牌到服务器要数据】 【注意】vuex存储数据不是持久化的,存的数据一刷新就没了 △△△△△△
(1)配置axios 传递参数
//登录 /api/user/passport/login 传给服务器参数账号与密码为必选项
export const reqUserLogin=(data)=>{
return axs({
method:'post',//请求类型不要写错
url:'/api3/user/passport/login',//走的是api3的代理
data,
})
}
这里使用axios中data传参方式
//用户登录 【服务器返回用户唯一身份标识token】【以后就拿着token令牌到服务器(验证)要对应用户数据】
async getUserLogin({commit},user){
let response= await reqUserLogin(user);//传参给服务器
if(response.code===200){//请求成功,服务器返回token令牌
commit('GETUSERLOGIN',response.data.token);//联系mutations,并传服务器返回的数据过去
return 'ok';
}
else{
return Promise.reject(new Error('err'));//状态码不是200【没有成功】,返回一个失败状态的promise对象到此async函数的调用处
}
},
--登录服务器会返回数据【token令牌】--用户的唯一身份标识、以后需要拿着token给服务器要对应用户数据
--请求成功 联系mutations并把token传递过去
--然后mutations对应函数把传递过来的token存入state中
(3)点击登录发请求【传用户信息】
//登陆的回调
async isLogin(){
let {phone,password}=this;//解构赋值
//前面两个都有就走后面,联系actions发请求,并把用户登录表单数据传给服务器
try{
(phone && password) && await this.$store.dispatch('RegisterOrLoginVc/getUserLogin',{phone,password})//这里传递的参数要与接口文档中的参数名一致
//登录成功进行路由跳转
this.$router.push({
name:'home',
})
localStorage.setItem('token',this.token);//存在本地储存当中
console.log(this.userRz)
}
catch(err) {
alert(err.message);
}
}
--点击登录按钮传收集的用户名与密码到dispatch所联系的actions对应请求的函数中,发请求
--await等待函数返回状态【根据请求成功与失败,函数返回成功与失败的promise对象】
--在这里我们mapState映射了小仓库state数据token,并存储在本地存储当中【请求成功我们存在state中的】
--成功进行路由跳转【到Home首页】
2、登录后获取用户信息
--到这里的时候我们点击了登录按钮,登陆成功已经获取到了token令牌【用户唯一身份标识,以后拿着用于象服务器请求相应用户身份的数据信息】,并存在浏览器本地储存当中
--本地储存中有token的话,就表示用户点击了登录按钮,并且登录成功【就应该是一个登录的状态】
//登陆成功后 获取用户信息 /api/user/passport/auth/getUserInfo
export const reqUserInfo=()=>{
return axs({method:'get',url:'/api3/user/passport/auth/getUserInfo'})
}
想要获取用户的信息,我们就要拿着登陆时服务器返回的token令牌【我们存在本地储存中】在请求拦截器config.headers.token请求头的字段设置请求头,这里我是从本地储存中拿的token令牌字符串【重点】
//登录后 获取用户信息
async getUserInfo({commit}){
let response=await reqUserInfo();//返回一个成功或失败的promise对象
if(response.code===200){
commit('GETUSERINFO',response.data);//请求成功 联系mutations储存服务器返回的数据
console.log(response.data)
return 'ok';
}
//else if (response.code===208){//用户未登录【退出登录时,挂载发请求,带的是uuid字段请求 头】会报错,我们在这里处理
//return ;//在这里不用单独处理错误 全局路由守卫调用的地方【使用await才可以】 catch会捕获到错误【token过期,或者请求头没有token】
//}
else{//请求不返回code为200的成功状态码,【请求头没有token,或token失效】
return Promise.reject(new Error('err'));
}
}
--函数解构store对象中的commit联系mutations将服务器返回的登录后的用户信息传递过去
--mutations中把用户信息放到state中
因为登陆成功后路由跳转到Home首页,我们在首页挂载完成时【mounted钩子中】,使用dispatch联系actions中对应获取用户登录信息的请求函数
//登录成功后,路由跳转到首页 联系actions发请求 拿用户信息
await this.$store.dispatch('RegisterOrLoginVc/getUserInfo');
【注意】:每次挂载都会发请求【如果有token字段的请求头(我们拿的是本地储存当中的)--用户已登陆】,获取用户信息,如果本地存储中没有token令牌表示用户未登录【请求头中就不会有token字段】服务器就不会返回用户数据,页面相应使用用户信息的地方就不会被渲染上。【服务器会拿着我么请求头中传过去的token进行校验】
--Header组件,根据用户信息数据name的有无,决定(登录|注册)与(用户名|退出登录)的显示与隐藏【如果有用户登录后的用户信息数据中name,表示用户已经登录,就需要展示(用户名|退出登录)】,请求头没有传token字段,服务器就不会返回用户数据信息,更拿不到数据中的name属性,这里使用了v-if="!userName" 【有了就是true,我们给他取反让(登录|注册)隐藏】,与v-else--header组件这里是根据用户信息数据显示的,用户信息数据想要有的话,就必须使用对应获取用户信息的接口 ,发请求【并在请求头上携带token字段--服务器校验用户身份】
这里因为只在Home组件挂载完成时,发请求【有无token请求头 有就带上表示用户已登录】,拿用户数据放到注册与登录小仓库中,所以我们在Home组件每次刷新,Header组件中的用户信息都不会丢失【这里就当用户已登录请求头中有token】
三·、退出登录部分
要退出登录,发请求给服务器,服务器会删除对应的token【当用户退出登录后,服务器会使其之前颁发的令牌(token)无效化,这就意味着,退出登陆后,我们在拿着服务器之前颁发的token令牌作为请求头字段的话发请求(获取用户数据),就不会成功获取对应用户息】
--发请求告诉服务器要退出登录,服务器删除对应token
--删除本地存储中的token【发请求后,此token就已经无效了,就不需要放到本地存储中了】
--删除注册与登录组件小仓库中的userInfo用户信息【这里是在mutations中操作的state删除的】
--根据actions中的退出函数,返回的状态,使用try 与catch捕获,没有捕获到错误,表示code===200,退出登录成功,进行路由跳转到Home首页。
四、路由守卫
--用户登录以后【就不能登录了--不能够出现登录界面--用户在url地址输入login不能让他跳到登录界面】 --用户没有登录,就不能跳转到购物车
路由守卫的第三个参数next【放行】 next(false): 取消当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。 next('/home')一个路由地址: 通过一个路由地址跳转到一个不同的地址,就像你调用 router.push() 一样。
<1>组件内路由守卫【用户已登录,不允许通过router-link或者编程式路由导航以及手动修改url跳转到登录页面】
//组件内路由守卫 用户已登录时,就不让他再次进入登录界面了
beforeRouteEnter(to,from,next){
if (localStorage.getItem('token')){//有token
next(false);//如果用户已登陆,用户在url地址中输入login跳转,会阻断跳转 【没有登录的时候本地存储中没有token,就可以进入login组件】
// console.log(to,from,next);
}
}
用户已登陆,要让Header组件展示用户信息【发请求】
--每个路由组件挂载的时候,发请求带token,拿用户信息
--在App组件挂载完成时,发请求拿用户信息【刷新才有】
--在Header组件挂载完成时,发请求拿用户数据也可以
--全局路由守卫,当要to的路由组件时,判断有无用户信息,有直接next,没有发请求带token拿用户数据信息,再next
<2>使用全局前置路由守卫【控制控制已登陆的用户不允许跳到login组件】
//全局前置路由守卫
router.beforeEach(async (to,from,next)=>{
//to:到哪去 from:从哪来 next:next()放行 ,next(path)--放行到指定路由组件
//登录以后,就不允许用户跳到login组件
//判断用户是否登录
// next();
// let token=store.state.RegisterOrLoginVc.token;//用户登录成功之后就会将服务器返回的token存在注册与登录组件的小仓库中
let token=localStorage.getItem('token');
let name=store.state.RegisterOrLoginVc.userInfo.name;//不能使用整个对象判断是否有用户数据,拿对象中的每个属性判断【空对象也是true】
if(token){//小仓库中有token,用户已登陆
//判断用户是否是去login登录或register注册组件 【登录后就不允许过去】
if (to.path==='/login' || to.path==='/register'){
next('/home');//不让去,回到home首页
}
else{//用户去的是除了登录与注册组件的其他路由组件
//在这里我们解决每一个路由组件挂载时带着token拿用户数据【放到注册与登录组件的仓库中userInfo】这一重复性操作
//判断注册与登录组件小仓库中是否有用户数据--为了展示Header组件对应的用户数据
if (name){//有用户数据,可以展示Header中的对应用户数据【用户名 | 退出登录】
console.log('@@',name);
next();
// store.state.RegisterOrLoginVc.userInfo={};
}
// else {
// next();//如果使用Header组件挂载发请求,获取用户数据使用
// }
else {//没有用户数据,Header中的用户信息展示不上
//发请求【请求头带着token字段】,拿用户数据
try {
let res=await store.dispatch('RegisterOrLoginVc/getUserInfo');//拿用户数据,放在注册与登录组件小仓库中
console.log('@@',res)
//等待用户数据放进去之后 放行
next();
}
catch(err) {//请求用户数据失败【请求时没有带token请求头字段 或 token过期】
//删除本地储存中的token,以及用户数据【注册与登录组件小仓库中的】
await store.dispatch('RegisterOrLoginVc/getUserLogout');//这里必须使用await
next('/login')
alert('认证过期或用户未登录')
}
}
}
}
else{//未登录
//未登录 不允许用户去:交易页【trade】 ,支付页【pay ,paysuccess】 ,个人中心【center】
let toPath=to.path;//用户要去的路径 //路径带有center就算为个人中心【因为有二级路由组件】
if(toPath==='/trade' || toPath==='/pay' || toPath==='/paysuccess' || toPath.indexOf('/center')>=0){
//用户未登录想要去这些路由组件,就先跳到登陆界面让用户登陆
next(`/login?wanto=${toPath}`);//跳到登陆页面之后,如果用户登陆了,就在跳到用户想要去的地方。 这里利用路由传参把要to的路径【传给login路由组件】
}
else{//非交易页 支付页 个人中心就可以去 放行
next();
}
}
点击登陆成功路由跳转的路径。
let toPath=this.$route.query.wanto || '/home';//如果有用户要to的路由地址,就跳到用户要去的地方【用户未登陆点击一个要去的地方存在query中】,没有就默认跳转到home首页
--判断用户是否登陆【本地储存中的token】
--如果用户登陆,不允许跳到登陆或注册路由组件【根据to】
--如果用户登陆,要去非登陆与注册组件【判断有无用户数据信息】,有就放行,没有就发请求拿用户数据信息【这里请求如果被catch捕获,可能是token过期,或者请求头没带token字段(用户手动删除)】,我们就发请求删除token(用户数据,本地存储的token)
五、交易页Trade【购物车点击结算】
要登录,有token
--购物车点击结算进行路由跳转
--Trade路由组件挂载发请求,拿数据【mock的用户收货地址】【请求服务器的购物商品清单--里面包含订单编号】
--拿着数据进行渲染
--收货地址点击变为默认地址,排他思维【给回调函数传存放整个收货地址数据的数组,以及点击的那个收货地址所对应的数组元素v-for遍历出来的】
--右下角展示当前点击默认收货地址【先计算出来,数组方法find条件是isDefault===1,数组find方法不会像filter方法一样返回数组 里面放的满足条件的对象,find方法直接会返回满足条件的数组元素】
computed:{
...mapState('TradeVc',['addressinfo']),//映射用户收货地址数据
//计算出当前的默认收货地址
defaultAddress(){
return this.addressinfo.find(item=>{
return item.isDefault===1;//等于1,就是默认的地址,最下面展示这个 ,会返回满足条件的数组元素【数组的形式返回】 ,可以用find()
}) || {};//默认返回一个空对象
},
点击提交订单
--发请求【带上挂载时请求商品请求数据中的订单编号】【收货人姓名,电话,收货地址,支付方式,买家留言,商品清单数组】,服务器会返回订单号。
--路由跳转到Pay路由组件,传一个订单号过去。
六、支付页Pay【交易页点击提交订单】
挂载完成,发请求【拿着路由跳转传的订单号,传给服务器】拿支付页的相关数据展示【会返回一个生成支付二维码的字符串】。
注意生命周期钩子函数不能使用async与await ,我们把发请求单独放在methods中定义的函数【async函数】,挂载时就调用这个函数。
微信支付业务
(1)二维码
安装引入qrcode 会将二维码字符串,生成二维码。
npm install --save qrcodees6中的模块化引入
import QRCode from 'qrcode'
// With promises
QRCode.toDataURL('I am a pony!')//会返回一个带有状态的promise对象,成功的话就带有二维码图片
.then(url => {
console.log(url)
})
.catch(err => {
console.error(err)
})
// With async/await
const generateQR = async text => {
try {
console.log(await QRCode.toDataURL(text))//会返回一个带有状态的promise对象,成功的话就带有二维码图片
} catch (err) {
console.error(err)
}
}
会返回一个带有状态的promise对象,里面带有生成的二维码图片。
(2)点击立即支付【弹窗】
element-ui的按需引入 ,资源不会过大。
npm i element-ui
npm install babel-plugin-component -D
配置bable.config.js文件
--使用弹窗组件
import {MessageBox} from 'element-ui';
Vue.prototype.$alert=MessageBox.alert;//在vm的beforeCreate()生命周期钩子中
Vue.prototype.$msgbox = MessageBox;//在vm的beforeCreate()生命周期钩子中
<el-button type="text" class="btn" @click="open">立即支付</el-button> --使用
el组件的相关配置,官网每个组件对应都会有相关配置参考。
组件实例vc.__proto__.__proto__=== Vue.prototype ;
也就是VueComponent构造函数原型对象的__proto__指向Vue的原型对象【所以vc组件实例对象可以使用Vue身上的属性与方法】
点击【立即支付】弹窗弹出 ,支付二维码展示,我们需要知道用户的支付状态--服务器知道【发请求问服务器】。如果只发一次请求【在这个时候用户还没有支付?】,所以我们要不断的发请求【询问服务器用户支付状态】,就要用到定时器。
请求返回状态码200,用户支付成功
--清除我们开启的定时器
--状态码为200时,存一个状态码【为了在后面判断用户点击我已支付时的--依据】
--关闭弹窗
--路由跳转到支付成功界面
用户点击弹窗【支付遇到了问题】或【我已支付】
参考element组件的配置属性【官网中】 beforeClose(type,elVc,done){} //type:返回用户点击的那个按钮 cancel用户点击支付遇到问题 , confirm用户点击我已支付 //elVc:element-ui组件实例 //done:关闭弹窗 --首先根据type判断用户点击了哪个按钮 --如果type 为cancel用户点击支付遇到问题 :弹出提示框提示用户,清除定时器【停止发请求】,关闭弹窗 --如果type 为confirm用户点击我已支付 :这时就需要知道用户是否支付成功,因为我们不断发请求,询问服务器用户是否支付成功,如果用户支付成功【根据服务器返回的数据code状态码200,清除定时器,停止发请求,存一个成功的状态码△,关闭弹窗,路由跳转】,存到data中的状态码就派上了用场【就是根据这个判断】,如果data中的状态码为200【表示用户支付成功】,清除定时器【停止发请求】,关闭弹窗,路由跳转。
<el-button type="text" class="btn" @click="open">立即支付</el-button>
data(){
return{
payInfo:{},//请求返回的数据为对象形式,在这里初始为一个空对象
timer:null,//待存定时器
paystatusCode:'',//待存支付成功状态码200 ,以后点击我已支付按钮的时候,根据这个是否为200,判断用户是否支付成功,【路由跳转】
}
},
//查询订单支付状态 /api/payment/weixin/queryPayStatus/{orderId} ,弹窗弹出,用户要支付的时候,就要不断发请求问服务器 用户的支付状态
export const reqPayStatus=(orderId)=>{
return axs({method:'get',url: `/api3/payment/weixin/queryPayStatus/${orderId}`});//不要忘记走代理
}
methods配置对象中
async open() {
let qrCodeurl=await QRcode.toDataURL(this.payInfo.codeUrl);//返回一个带有状态的promise对象 【带有二维码】,把二维码,发到弹出框中
this.$alert(`<img src=${qrCodeurl} alt=""/>`, '微信支付', {
dangerouslyUseHTMLString: true,
center:true,//对应组件都有相关的配置项
showCancelButton:true,//显示取消按钮
cancelButtonText:'提交问题',//取消的文本
confirmButtonText:'支付成功',//确定按钮文本
showClose:false,//隐藏关闭按钮
beforeClose:(type,elVc,done)=>{//官网中找的对应组件配置都有
// type :cancel用户点击支付遇到问题 , confirm用户点击我已支付
//elVc:element-ui这个弹框组件
//done() :关闭弹窗
if(type==='cancel'){//用户点击支付遇到问题
alert('请联系后台管理员老师');//提示用户
clearInterval(this.timer);//清除定时器【停止发请求】
this.timer=null;
done();//关闭弹窗
}
//状态码不为200【用户不支付成功】,不会执行后面的
else if(type==='confirm' && this.paystatusCode===200){//用户点击我已支付 ,根据状态码判断用户是否支付【状态码不是200,点击按钮 无效】
clearInterval(this.timer);
this.timer=null;
done();//关闭弹窗
this.$router.push({name:'paysuccess'});
}
}
});
//弹窗弹出以后,要知道用户的支付状态 ,服务器知道,所以就要不断发请求 询问服务器用户支付状态
//因为要不断向服务器询问 支付状态 使用定时器
this.timer=setInterval(async ()=>{
let response=await this.$Api.reqPayStatus(this.$route.query.dingdanId);//返回带有状态带有数据的promise对象【在这里服务器不会返回数据】
console.log(response)
if(response.code===200){//状态码为200表示支付成功
//清除定时器 不在发请求
clearInterval(this.timer);
this.timer=null;
//把状态码200存起来
this.paystatusCode=200;
//隐藏弹窗
this.$msgbox.close();
//路由跳转
this.$router.push({name:'paysuccess'})
}
},1000);
}
还有就是用户登录了不能随便去交易页【trade】,支付页【pay】,支付成功页【paysuccess】
用户去交易页【必须从购物车去】 用户去支付界面【只能从交易页去】 用户去支付成功界面【只能从pay支付页面去】使用独享路由守卫或者组件内路由守卫。
写在对应路由【trade】配置项中:
beforeEnter(to,from,next){
//用户想要去交易页,必须从购物车去【】看用户是否是从购物车来的】
if(from.path==='/shopcart'){
next();//只管交易页
}
else {
next(false);//还是为当前页 来的路径不是'/shopcart',就会被阻断,并且路径还是from的path
}
}
补充组件内路由守卫【detail组件为例】:
//组件内路由守卫 同一个路由路径,但是后面的参数更新,就会调用
beforeRouteUpdate(to,from,next){// 在当前路由改变,但是该组件被复用时调用 /detail/12 /detail/9 共用的/detail后面的值变,就会触发【路径从/detail/12 跳到/detail/9】就会调用此组件内路由守卫
console.log('@更新')
},