限制只有登錄才能訪問(wèn)首頁(yè),而不登錄只能打開(kāi)登錄界面茬祷。
這就用到路由守衛(wèi)功能清焕。
修改路由配置文件``:
import {
createRouter,
createWebHistory
} from 'vue-router'
const routes = [{
path: '/',
name: 'Home',
component: () => import(/* webpackChunkName: "home" */ '../views/home/Home.vue')
}, {
path: '/login',
name: 'Login',
component: () => import(/* webpackChunkName: "login" */ '../views/login/Login.vue')
}]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
// beforeEach:每次做路由跳轉(zhuǎn)之前都會(huì)執(zhí)行這個(gè)操作。
router.beforeEach((to, from, next) => {
// to and from are Route Object,
// to:跳轉(zhuǎn)的時(shí)候想要跳轉(zhuǎn)的頁(yè)面的信息
// from :指從哪里跳過(guò)來(lái)的信息
// next() must be called to resolve the hook}
// 中間件繼續(xù)執(zhí)行的方法
const isLogin = const isLogin = false
console.log(to, from)
/** 判斷是否登錄 */
// 必須雙循環(huán)祭犯,才能防止死循環(huán)
if (isLogin || to.name === 'Login') {
next()
} else {
// 如果沒(méi)有登錄秸妥,就跳到登錄頁(yè)面
next({
name: 'Login'
})
}
})
export default router
這樣,無(wú)論什么子路徑都會(huì)跳轉(zhuǎn)到登錄頁(yè)面沃粗。
修改是否登錄
為本地存儲(chǔ):
......
const isLogin = localStorage.isLogin // 從本地存儲(chǔ)中取isLogin
......
修改src\views\login\Login.vue
:
<template>
<div class="wrapper">
<img class="wrapper__img" src="/i18n/9_16/img/user.png" />
<div class="wrapper__input">
<input class="wrapper__input__content" placeholder="請(qǐng)輸入手機(jī)號(hào)碼" />
</div>
<div class="wrapper__input">
<input
type="password"
class="wrapper__input__content"
placeholder="請(qǐng)輸入密碼"
/>
</div>
<div class="wrapper__login-button" @click="handleLogin">登陸</div>
<div class="wrapper__login__item">
<div class="wrapper__login__item__link">立即注冊(cè)</div>
<p class="wrapper__login__item__cut">|</p>
<div class="wrapper__login__item__password">忘記密碼</div>
</div>
</div>
</template>
<script>
// 路由跳轉(zhuǎn)方法
import { useRouter } from 'vue-router'
export default {
name: 'Login',
setup () {
// 獲取路由實(shí)例
const router = useRouter()
// 登錄按鈕
const handleLogin = () => {
localStorage.isLogin = true
// 登陸之后重新做一次頁(yè)面跳轉(zhuǎn)粥惧,再訪問(wèn)下一個(gè)頁(yè)面
router.push({ name: 'Home' })
}
return { handleLogin }
}
}
</script>
<style lang="scss" scoped>
@import '@/style/viriables';
.wrapper {
position: absolute;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
&__img {
display: block;
margin: 0 auto 0.4rem auto;
width: 0.66rem;
height: 0.66rem;
}
&__input {
// box-sizing: border-box;//內(nèi)部間距
height: 0.48rem;
margin: 0 0.4rem 0.16rem 0.4rem;
background: #f9f9f9;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 0.06rem;
&__content {
line-height: 0.48rem;
background: none;
border: none;
outline: none;
width: 100%;
font-size: 0.16rem;
color: $centent-notice-fontcolor;
&::placeholder {
color: $centent-notice-fontcolor;
}
}
}
&__login-button {
line-height: 0.48rem;
margin: 0.32rem 0.4rem 0.16rem 0.4rem;
background: #0091ff;
color: #fff;
box-shadow: 0 0.04rem 0.08rem 0 rgba(0, 145, 255, 0.32);
border-radius: 0.04rem;
font-size: 0.16rem;
text-align: center;
}
&__login__item {
text-align: center;
&__link {
display: inline-block;
margin: auto 0.05rem auto 0.05rem;
text-align: center;
font-size: 0.14rem;
color: $centent-notice-fontcolor;
}
&__cut {
display: inline-block;
text-align: center;
font-size: 0.14rem;
margin: auto 0.05rem auto 0.05rem;
}
&__password {
display: inline-block;
text-align: center;
font-size: 0.14rem;
margin: auto 0.05rem auto 0.05rem;
color: $centent-notice-fontcolor;
}
}
}
</style>
實(shí)現(xiàn)一個(gè)簡(jiǎn)單的登錄邏輯。但是如果已經(jīng)登錄最盅,那么就不應(yīng)該讓用戶繼續(xù)訪問(wèn)到登錄頁(yè)面:
修改src\router\index.js
:
import {
createRouter,
createWebHistory
} from 'vue-router'
const routes = [{
path: '/',
name: 'Home',
component: () => import(/* webpackChunkName: "home" */ '../views/home/Home.vue')
}, {
path: '/login',
name: 'Login',
component: () => import(/* webpackChunkName: "login" */ '../views/login/Login.vue'),
beforeEnter: (to, from, next) => {
// 只有訪問(wèn)Login頁(yè)面之前才會(huì)執(zhí)行次函數(shù)
const isLogin = localStorage.isLogin // 從本地存儲(chǔ)中取isLogin
if (isLogin) {
// 如果登錄突雪,就跳到首頁(yè)頁(yè)面
next({
name: 'Home'
})
} else {
// 否則跳轉(zhuǎn)到登錄頁(yè)面
next()
}
}
}]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
// beforeEach:全局,每次做路由跳轉(zhuǎn)之前都會(huì)執(zhí)行這個(gè)操作涡贱。
router.beforeEach((to, from, next) => {
// to and from are Route Object,
// to:跳轉(zhuǎn)的時(shí)候想要跳轉(zhuǎn)的頁(yè)面的信息
// from :指從哪里跳過(guò)來(lái)的信息
// next() must be called to resolve the hook}
// 中間件繼續(xù)執(zhí)行的方法
const isLogin = localStorage.isLogin // 從本地存儲(chǔ)中取isLogin
console.log(to, from)
/** 判斷是否登錄 */
// 必須雙循環(huán)咏删,才能防止死循環(huán)
if (isLogin || to.name === 'Login') {
next()
} else {
// 如果沒(méi)有登錄,就跳到登錄頁(yè)面
next({
name: 'Login'
})
}
})
export default router
當(dāng)然问词,可以優(yōu)化一下寫(xiě)法:
const routes = [{
path: '/',
name: 'Home',
component: () => import(/* webpackChunkName: "home" */ '../views/home/Home.vue')
}, {
path: '/login',
name: 'Login',
component: () => import(/* webpackChunkName: "login" */ '../views/login/Login.vue'),
beforeEnter: (to, from, next) => {
// 只有訪問(wèn)Login頁(yè)面之前才會(huì)執(zhí)行次函數(shù)
const {
isLogin
} = localStorage // 從本地存儲(chǔ)中取isLogin
// 如果登錄督函,就跳到首頁(yè)頁(yè)面;否則跳轉(zhuǎn)到登錄頁(yè)面
isLogin
? next({
name: 'Home'
})
: next()
}
}]
......
// beforeEach:全局,每次做路由跳轉(zhuǎn)之前都會(huì)執(zhí)行這個(gè)操作激挪。
router.beforeEach((to, from, next) => {
// to and from are Route Object,
// to:跳轉(zhuǎn)的時(shí)候想要跳轉(zhuǎn)的頁(yè)面的信息
// from :指從哪里跳過(guò)來(lái)的信息
// next() must be called to resolve the hook}
// 中間件繼續(xù)執(zhí)行的方法
// 從本地存儲(chǔ)中取isLogin
const {
isLogin
} = localStorage
console.log(to, from);
/** 判斷是否登錄 */
// 必須雙循環(huán)辰狡,才能防止死循環(huán)
// 如果沒(méi)有登錄,就跳到登錄頁(yè)面
(isLogin || to.name === 'Login') ? next() : next({
name: 'Login'
})
})
注冊(cè)頁(yè)面的實(shí)現(xiàn)
注冊(cè)頁(yè)面和登錄頁(yè)面一致垄分。
把登錄頁(yè)面復(fù)制到注冊(cè)頁(yè)面:
新建src\views\register\Register.vue
:
<template>
<div class="wrapper">
<img class="wrapper__img" src="/i18n/9_16/img/user.png" />
<div class="wrapper__input">
<input class="wrapper__input__content" placeholder="請(qǐng)輸入手機(jī)號(hào)碼" />
</div>
<div class="wrapper__input">
<input
type="password"
class="wrapper__input__content"
placeholder="請(qǐng)輸入密碼"
/>
</div>
<div class="wrapper__login-button" @click="handleLogin">登陸</div>
<div class="wrapper__login__item">
<div class="wrapper__login__item__link">立即注冊(cè)</div>
<p class="wrapper__login__item__cut">|</p>
<div class="wrapper__login__item__password">忘記密碼</div>
</div>
</div>
</template>
<script>
// 路由跳轉(zhuǎn)方法
import { useRouter } from 'vue-router'
export default {
name: 'Register',
setup () {
// 獲取路由實(shí)例
const router = useRouter()
// 登錄按鈕
const handleLogin = () => {
localStorage.isLogin = true
// 登陸之后重新做一次頁(yè)面跳轉(zhuǎn)宛篇,再訪問(wèn)下一個(gè)頁(yè)面
router.push({ name: 'Home' })
}
return { handleLogin }
}
}
</script>
<style lang="scss" scoped>
@import '@/style/viriables';
.wrapper {
position: absolute;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
&__img {
display: block;
margin: 0 auto 0.4rem auto;
width: 0.66rem;
height: 0.66rem;
}
&__input {
// box-sizing: border-box;//內(nèi)部間距
height: 0.48rem;
margin: 0 0.4rem 0.16rem 0.4rem;
background: #f9f9f9;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 0.06rem;
&__content {
line-height: 0.48rem;
background: none;
border: none;
outline: none;
width: 100%;
font-size: 0.16rem;
color: $centent-notice-fontcolor;
&::placeholder {
color: $centent-notice-fontcolor;
}
}
}
&__login-button {
line-height: 0.48rem;
margin: 0.32rem 0.4rem 0.16rem 0.4rem;
background: #0091ff;
color: #fff;
box-shadow: 0 0.04rem 0.08rem 0 rgba(0, 145, 255, 0.32);
border-radius: 0.04rem;
font-size: 0.16rem;
text-align: center;
}
&__login__item {
text-align: center;
&__link {
display: inline-block;
margin: auto 0.05rem auto 0.05rem;
text-align: center;
font-size: 0.14rem;
color: $centent-notice-fontcolor;
}
&__cut {
display: inline-block;
text-align: center;
font-size: 0.14rem;
margin: auto 0.05rem auto 0.05rem;
}
&__password {
display: inline-block;
text-align: center;
font-size: 0.14rem;
margin: auto 0.05rem auto 0.05rem;
color: $centent-notice-fontcolor;
}
}
}
</style>
修改路由信息src\router\index.js
:
import {
createRouter,
createWebHistory
} from 'vue-router'
const routes = [{
path: '/',
name: 'Home',
component: () => import(/* webpackChunkName: "home" */ '../views/home/Home.vue')
}, {
path: '/login',
name: 'Login',
component: () => import(/* webpackChunkName: "login" */ '../views/login/Login.vue'),
beforeEnter: (to, from, next) => {
// 只有訪問(wèn)Login頁(yè)面之前才會(huì)執(zhí)行次函數(shù)
const {
isLogin
} = localStorage // 從本地存儲(chǔ)中取isLogin
// 如果登錄,就跳到首頁(yè)頁(yè)面;否則跳轉(zhuǎn)到登錄頁(yè)面
isLogin
? next({
name: 'Home'
})
: next()
}
},
{
path: '/register',
name: 'Register',
component: () => import(/* webpackChunkName: "register" */ '../views/register/Register.vue'),
beforeEnter: (to, from, next) => {
const {
isLogin
} = localStorage
isLogin
? next({
name: 'Home'
})
: next()
}
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
// beforeEach:全局薄湿,每次做路由跳轉(zhuǎn)之前都會(huì)執(zhí)行這個(gè)操作叫倍。
router.beforeEach((to, from, next) => {
// to and from are Route Object,
// to:跳轉(zhuǎn)的時(shí)候想要跳轉(zhuǎn)的頁(yè)面的信息
// from :指從哪里跳過(guò)來(lái)的信息
// next() must be called to resolve the hook}
// 中間件繼續(xù)執(zhí)行的方法
// 從本地存儲(chǔ)中取isLogin
const {
isLogin
} = localStorage
console.log(to, from)
/** 判斷是否登錄 */
// 必須雙循環(huán)豌鸡,才能防止死循環(huán)
// 如果沒(méi)有登錄,就跳到登錄頁(yè)面
const {
name
} = to
const
isLoginOrRegister = (name === 'Login' || name === 'Register');
(isLogin || isLoginOrRegister) ? next() : next({
name: 'Login'
})
})
export default router
接下來(lái)修改src\views\register\Register.vue
:
<template>
<div class="wrapper">
<img class="wrapper__img" src="/i18n/9_16/img/user.png" />
<div class="wrapper__input">
<input class="wrapper__input__content" placeholder="請(qǐng)輸入手機(jī)號(hào)碼" />
</div>
<div class="wrapper__input">
<input
type="password"
class="wrapper__input__content"
placeholder="請(qǐng)輸入密碼"
/>
</div>
<div class="wrapper__input">
<input
type="password"
class="wrapper__input__content"
placeholder="請(qǐng)?jiān)俅屋斎朊艽a"
/>
</div>
<div class="wrapper__register-button">注冊(cè)</div>
<div class="wrapper__register__item">
<div class="wrapper__register__item__link" @click="handleLoginClick">
已有賬號(hào)去登陸
</div>
</div>
</div>
</template>
<script>
// 路由跳轉(zhuǎn)方法
import { useRouter } from 'vue-router'
export default {
name: 'Register',
setup () {
// 獲取路由實(shí)例
const router = useRouter()
const handleLoginClick = () => {
router.push({ name: 'Login' })
}
return { handleLoginClick }
}
}
</script>
<style lang="scss" scoped>
@import '@/style/viriables';
.wrapper {
position: absolute;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
&__img {
display: block;
margin: 0 auto 0.4rem auto;
width: 0.66rem;
height: 0.66rem;
}
&__input {
// box-sizing: border-box;//內(nèi)部間距
height: 0.48rem;
margin: 0 0.4rem 0.16rem 0.4rem;
background: #f9f9f9;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 0.06rem;
&__content {
line-height: 0.48rem;
background: none;
border: none;
outline: none;
width: 100%;
font-size: 0.16rem;
color: $centent-notice-fontcolor;
&::placeholder {
color: $centent-notice-fontcolor;
}
}
}
&__register-button {
line-height: 0.48rem;
margin: 0.32rem 0.4rem 0.16rem 0.4rem;
background: #0091ff;
color: #fff;
box-shadow: 0 0.04rem 0.08rem 0 rgba(0, 145, 255, 0.32);
border-radius: 0.04rem;
font-size: 0.16rem;
text-align: center;
}
&__register__item {
text-align: center;
&__link {
display: inline-block;
margin: auto 0.05rem auto 0.05rem;
text-align: center;
font-size: 0.14rem;
color: $centent-notice-fontcolor;
}
}
}
</style>
同樣修改一下登錄頁(yè)面的交互:
<template>
<div class="wrapper">
<img class="wrapper__img" src="/i18n/9_16/img/user.png" />
<div class="wrapper__input">
<input class="wrapper__input__content" placeholder="請(qǐng)輸入手機(jī)號(hào)碼" />
</div>
<div class="wrapper__input">
<input
type="password"
class="wrapper__input__content"
placeholder="請(qǐng)輸入密碼"
/>
</div>
<div class="wrapper__login-button" @click="handleLogin">登陸</div>
<div class="wrapper__login__item">
<div class="wrapper__login__item__link" @click="handleRegisterClick">
立即注冊(cè)
</div>
<p class="wrapper__login__item__cut">|</p>
<div class="wrapper__login__item__password">忘記密碼</div>
</div>
</div>
</template>
<script>
// 路由跳轉(zhuǎn)方法
import { useRouter } from 'vue-router'
export default {
name: 'Login',
setup () {
// 獲取路由實(shí)例
const router = useRouter()
// 登錄按鈕
const handleLogin = () => {
localStorage.isLogin = true
// 登陸之后重新做一次頁(yè)面跳轉(zhuǎn)段标,再訪問(wèn)下一個(gè)頁(yè)面
router.push({ name: 'Home' })
}
const handleRegisterClick = () => {
router.push({ name: 'Register' })
}
return { handleLogin, handleRegisterClick }
}
}
</script>
<style lang="scss" scoped>
@import '@/style/viriables';
.wrapper {
position: absolute;
top: 50%;
left: 0;
right: 0;
transform: translateY(-50%);
&__img {
display: block;
margin: 0 auto 0.4rem auto;
width: 0.66rem;
height: 0.66rem;
}
&__input {
// box-sizing: border-box;//內(nèi)部間距
height: 0.48rem;
margin: 0 0.4rem 0.16rem 0.4rem;
background: #f9f9f9;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 0.06rem;
&__content {
line-height: 0.48rem;
background: none;
border: none;
outline: none;
width: 100%;
font-size: 0.16rem;
color: $centent-notice-fontcolor;
&::placeholder {
color: $centent-notice-fontcolor;
}
}
}
&__login-button {
line-height: 0.48rem;
margin: 0.32rem 0.4rem 0.16rem 0.4rem;
background: #0091ff;
color: #fff;
box-shadow: 0 0.04rem 0.08rem 0 rgba(0, 145, 255, 0.32);
border-radius: 0.04rem;
font-size: 0.16rem;
text-align: center;
}
&__login__item {
text-align: center;
&__link {
display: inline-block;
margin: auto 0.05rem auto 0.05rem;
text-align: center;
font-size: 0.14rem;
color: $centent-notice-fontcolor;
}
&__cut {
display: inline-block;
text-align: center;
font-size: 0.14rem;
margin: auto 0.05rem auto 0.05rem;
}
&__password {
display: inline-block;
text-align: center;
font-size: 0.14rem;
margin: auto 0.05rem auto 0.05rem;
color: $centent-notice-fontcolor;
}
}
}
</style>