- 注冊
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')
