- 注冊
1.1 注冊頁面的布局
1.2 注冊業務邏輯的實現
1.3封裝api - 登錄
3.導航守衛 - 注冊
1.1 注冊頁面的布局
需要用到Vant的Field組件
1.views下新建一個注冊頁面 ,完成基本布局。引入Vue和Field並使用。
3.給注冊頁面添加一個單獨的路由,注冊頁面不需要底部。(注意,相關樣式需要引入不同的組件,請細心查看官方文檔,按需拿取內容) - 利用計算屬性給輸入框做條件判斷。本案例以手機號為例。
1.在views目錄下創建三個文件
1.1、一個RetrievePass.vue文件寫入注冊的代碼塊
1.2、一個Register.vue文件寫入手機驗證碼登錄
1.3、一個Login.vue文件寫入密碼登錄
RetrievePass.vue文件注冊
<template> <!-- 注冊 --> <div> <div class="zhx_retrieve"> <van-field v-model="sms" center clearable placeholder="請輸入手機號"> <template #button> <a size="small" type="primary">發送驗證碼</a> </template> </van-field> <van-cell-group> <van-field v-model="sss" placeholder="請輸入驗證碼" /> </van-cell-group> <van-cell-group> <van-field v-model="password" placeholder="請輸入密碼" /> </van-cell-group> </div> <div class="zhx_login_button"> <button>登錄</button> </div> </div> </template> <script> export default { data() { return { sms: "", sss: "", password: "", }; }, }; </script> <style> .zhx_retrieve { width: 100%; height: 25vh; } .zhx_login_button { width: 100%; height: 10vh; display: flex; align-items: center; justify-content: center; color: white; font-size: 0.8rem; } .zhx_login_button button { width: 90%; height: 7vh; background: orange; border-radius: 18px; border: none; } </style>
1.2 注冊業務邏輯的實現
注:在此之前,記住要先去路由頁面添加一個注冊頁面的路由。
1.補充了密碼以及驗證碼的計算屬性判斷
密碼:如果為空返回空,如果不符合正則,返回格式錯誤,否則表示可以直接返回空
驗證碼:如果為空返回空,否則不為五位,返回驗證碼格式錯誤,否則成功返回空
2.驗證碼
綁定點擊事件senCode
將提示信息{{buttonmsg}}放在按鈕內容中。
定義函數:(定時器注意用箭頭函數)每一秒鍾定義一次,先提前聲明時間,在計時器內讓時間減減,當時間為零時,清除定時器,同時btn的內容改為發送驗證碼,最后return。未return時,讓按鈕內的內容為時間減減+后重新發送(注意:在開啟定時器時,要讓按鈕禁止點擊,在清除定時器后再讓按鈕可點。)
Register.vue文件手機驗證碼登錄
<template> <!-- 手機驗證登錄 --> <div> <div class="zhx_login_img"> <img src="../../assets/login/Login.png" alt="" /> </div> <div class="zhx_register"> <van-field v-model="sms" center clearable placeholder="請輸入手機號"> <template #button> <a style="color: red" v-show="isShow == false" size="small" type="primary" @click="onClickSend" >發送驗證碼</a > <a style="color: gray" v-show="isShow == true" >獲取驗證碼({{ num }})</a > </template> </van-field> <van-cell-group> <van-field v-model="sss" placeholder="請輸入驗證碼" /> </van-cell-group> </div> <div class="zhx_register_pass"> <span>*未注冊的手機號將自動注冊</span> <span @click="onLogin">使用密碼登錄</span> </div> <div class="zhx_login_button"> <button @click="redister">登錄</button> </div> </div> </template> <script> import Vue from "vue"; import { Toast } from "vant"; Vue.use(Toast); export default { data() { return { sms: "", sss: "", isShow: false, num: 60, }; }, methods: { onLogin() { this.$router.push("/login"); }, onClickSend() { this.$APP .smsCode({ mobile: this.sms, sms_type: "login", }) .then((res) => { console.log(res); if (res.data.code === 200) { this.countDown(); Toast(res.data.msg); } else if (res.data.code == 201) { Toast(res.data.msg); } }); }, //倒計時 countDown() { this.isShow = true; setInterval(() => { this.num--; if (this.num <= 0) { this.isShow = false; this.num = 60; } }, 1000); }, redister() { this.$APP .login({ mobile: this.sms, sms_code: this.sss, client: 1, type: 2, }) .then((res) => { console.log(res); let token = res.data.data.remember_token; window.localStorage.setItem("token", token); this.$router.push("/home"); }); }, }, }; </script> <style scoped> .zhx_register { width: 100%; height: 15vh; } .zhx_login_img { width: 100%; height: 30vh; display: flex; align-items: center; justify-content: center; } .zhx_login_img img { width: 80%; } .zhx_login_button { width: 100%; height: 10vh; display: flex; align-items: center; justify-content: center; color: white; font-size: 0.8rem; } .zhx_login_button button { width: 90%; height: 7vh; background: orange; border-radius: 18px; border: none; } .zhx_register_pass { width: 100%; height: 12vh; display: flex; justify-content: space-around; font-size: 0.6rem; color: gray; } </style>
Login.vue文件密碼登錄
<template> <!-- 密碼登錄 --> <div class="zhx_login"> <div class="zhx_login_img"> <img src="../../assets/login/Login.png" alt="" /> </div> <div> <van-form @submit="onSubmit"> <van-field v-model="username" name="用戶名" placeholder="用戶名" :rules="[{ required: true, message: '請填寫用戶名' }]" /> <van-field v-model="password" type="password" name="密碼" placeholder="密碼" :rules="[{ required: true, message: '請填寫密碼' }]" /> </van-form> </div> <div class="zhx_login_register"> <span @click="retrieve">找回密碼</span> <div> <span @click="onRegister">注冊/驗證碼登錄</span> </div> </div> <div class="zhx_login_button"> <button @click="onClickLogin">登錄</button> </div> </div> </template> <script> export default { data() { return { username: "", password: "", }; }, methods: { onSubmit(values) { console.log("submit", values); }, retrieve() { this.$router.push("/retrieve"); }, onRegister() { this.$router.push("/register"); }, //登錄 onClickLogin() { this.$APP .login({ mobile: this.username, password: this.password, type: 1, }) .then((res) => { console.log(res); let token = res.data.data.remember_token; window.localStorage.setItem("token", token); console.log(res.data.data.is_new); this.$router.push("/home"); }); }, }, }; </script> <style scoped> .zhx_login { width: 100%; } .zhx_login_img { width: 100%; height: 30vh; display: flex; align-items: center; justify-content: center; } .zhx_login_img img { width: 80%; } .zhx_login_register { width: 100%; height: 10vh; display: flex; align-items: center; justify-content: space-around; font-size: 0.6rem; color: gray; } .zhx_login_button { width: 100%; height: 10vh; display: flex; align-items: center; justify-content: center; color: white; font-size: 0.8rem; } .zhx_login_button button { width: 90%; height: 7vh; background: orange; border-radius: 18px; border: none; } </style>
在src里創建一個api文件寫入三個js文件進行封裝
1.1、一個core.js文件封裝axios請求攔截和響應攔截
1.2、一個index.js文件封裝請求的方法
1.3、一個path.js文件封裝接口
core.jsaxios請求攔截和響應攔截
import axios from "axios" import apl from "./path" import { Loading } from 'element-ui'; const instance = axios.create({ //axios創建的實例 baseURL: 'http://120.53.31.103:84', // `baseURL` 將自動加在 `url` 前面,除非 `url` 是一個絕對 URL。 timeout: 5000, // `timeout` 指定請求超時的毫秒數(0 表示無超時時間) 如果請求話費了超過 `timeout` 的時間,請求將被中斷 headers: { 'X-Custom-Header': 'foobar' // `headers` 是即將被發送的自定義請求頭 } }); var loading = null // 添加請求攔截器 instance.interceptors.request.use(function (config) { // 在發送請求之前做些什么 loading = Loading.service(); return config; }, function (error) { // 對請求錯誤做些什么 return Promise.reject(error); }); // 添加響應攔截器 instance.interceptors.response.use(function (response) { // 對響應數據做點什么 setTimeout(function () { loading.close() }, 500) return response; }, function (error) { // 對響應錯誤做點什么 return Promise.reject(error); }); export function request(method, url, params) { //創建的request函數,把函數拋出 switch (method) { //switch判斷 case apl.METHODS.GET: //當請求的方式為GET的時候, return get(url, params) //把get方式return出去 case apl.METHODS.POST: //當請求的方式為POST的時候, return post(url, params) //把post方式return出去 } } function get(url, params) { //封裝的一個get函數 return instance.get(url, params) } function post(url, params) { //封裝的一個post函數 return instance.post(url, params) }
index.js文件請求的方法
import { request } from "../apl/core" import apl from "../apl/path" const APP = { login(params) { return request(apl.METHODS.POST, apl.URL.Login, params); }, smsCode(params) { return request(apl.METHODS.POST, apl.URL.SmsCode, params); }, change(params) { return request(apl.METHODS.POST, apl.URL.Change, params); }, } export default APP
path.js文件接口
const apl = { METHODS: { GET: "get", //get請求 POST: "post" //post請求 }, //接口路徑 URL: { //登錄 Login: "/api/app/login", //驗證碼登錄 SmsCode: "/api/app/smsCode", //修改密碼 Change: "/api/app/password" } } export default apl
在router文件里配置需要的文件
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Home', component: () => import('../views/Home.vue') }, { path: '/login', name: 'Login', component: () => import('../views/login/Login.vue') }, { path: '/register', name: 'Register', component: () => import('../views/login/Register.vue') }, { path: '/retrievePass', name: 'RetrievePass', component: () => import('../views/login/RetrievePass.vue') }, { path: '/home', name: 'Home', component: () => import('../views/Home.vue') } ] const router = new VueRouter({ // mode: 'history', base: process.env.BASE_URL, routes }) export default router
在min.js里配置自己需要的組件
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import Vant from "vant" import "vant/lib/index.css" import axios from "axios" import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI); Vue.use(Vant) Vue.prototype.$axios = axios Vue.config.productionTip = false import APP from './apl/index' Vue.prototype.$APP = APP; new Vue({ router, store, render: h => h(App) }).$mount('#app')