【VUE】vue-router
1. vue-router组件
1.1 路由的嵌套
index.js
import {createRouter, createWebHistory} from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/login',
name: 'login',
component: () => import('../views/LoginView.vue')
},
{
path: '/info',
name: 'info',
component: () => import('../views/InfoView.vue')
},
{
path: '/admin',
name: 'admin',
component: () => import('../views/AdminView.vue'),
children: [
{
path: "",
redirect: {name: "mine"}
},
{
path: "mine",
name: "mine",
component: () => import('../views/MineView.vue')
},
{
path: "order",
name: "order",
component: () => import('../views/OrderView.vue')
}
]
}
]
})
export default router
App.vue
<template>
<div class="page-header">
<div class="container">
<RouterLink to="/login">登录</RouterLink> |
<RouterLink to="/info">信息</RouterLink> |
<RouterLink to="/admin">后台</RouterLink> |
<RouterLink to="/admin/mine">我的</RouterLink>
</div>
</div>
<div class="container">
<RouterView/>
</div>
</template>
<script setup>
</script>
<style scoped>
.page-header {
height: 48px;
background-color: cornflowerblue;
line-height: 48px;
}
.container {
width: 980px;
margin: 0 auto;
</style>
AdminView.vue
<template>
<h1>Admin</h1>
<router-link to="/admin/mine">我的</router-link> |
<router-link to="/admin/order">订单</router-link>
<RouterView/>
</template>
<script setup>
</script>
<style scoped>
</style>
1.2 编程式导航
不使用<router-link>
标签实现路由的跳转。
使用js代码实现路由跳转,例如:
InfoView.vue
<template>
<h1>Info</h1>
</template>
<script setup>
import {useRouter} from "vue-router"
const router = useRouter()
// router.push({path:"/admin/order"})
// router.push({name:"login"})
router.push({name: "login", params: {nid: 100}, query: {page: 100}})
</script>
<style scoped>
</style>
浏览器的后退前进缓存中,有以下区别:
push [A,B,C,D,新页面]
replace [A,B,C,新页面]
案例1:博客+公司官网+xx在线平台
-
未登录,可以查看某些页面
-
用户登录,去登录
-
去查看某些页面
现象:登录页是在有导航条的前提
App.vue
<template>
<div class="page-header">
<div class="container">
<RouterLink to="/info">信息</RouterLink>
|
<RouterLink to="/admin">后台</RouterLink>
|
<RouterLink to="/admin/mine">我的</RouterLink>
<div style="float:right;">
<RouterLink to="/login">登录</RouterLink>
</div>
</div>
</div>
<div class="container">
<RouterView/>
</div>
</template>
<script setup>
</script>
<style scoped>
body {
margin: 0;
}
.page-header {
height: 48px;
background-color: cornflowerblue;
line-height: 48px;
}
.page-header a {
display: inline-block;
padding: 0 10px;
}
.container {
width: 980px;
margin: 0 auto;
}
</style>
LoginView.vue
<template>
<div class="box">
<p>
用户名:
<input type="text" placeholder="用户名" v-model="msg.username">
</p>
<p>
密码:
<input type="text" placeholder="密码" v-model="msg.password">
</p>
<p>
<button @click="doLogin">登录</button>
</p>
</div>
</template>
<script setup>
import {ref} from "vue";
import {useRouter} from "vue-router";
const msg = ref({
username: "",
password: ""
})
const router = useRouter()
const doLogin = function () {
// 1、获取数据
console.log(msg.value)
// 2、发送网络请求
// 3、跳转到首页
router.push({name:"info"})
}
</script>
<style scoped>
.box {
width: 300px;
margin: 100px auto;
}
</style>
案例2:后台管理
现象:登录页面,无导航条的前提。未登录时,不允许查看系统中有哪些菜单。
index.js
import {createRouter, createWebHistory} from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/login',
name: 'login',
component: () => import('../views/LoginView.vue')
},
{
path: '/admin',
name: 'admin',
component: () => import('../views/AdminView.vue'),
children: [
{
path: "",
redirect: {name: "mine"}
},
{
path: "mine",
name: "mine",
component: () => import('../views/MineView.vue')
},
{
path: "order",
name: "order",
component: () => import('../views/OrderView.vue')
}
]
}
]
})
export default router
App.vue
<template>
<div class="container">
<RouterView/>
</div>
</template>
<script setup>
</script>
<style scoped>
body {
margin: 0;
}
.container {
width: 980px;
margin: 0 auto;
}
</style>
LoginView.vue
<template>
<div class="box">
<p>
用户名:
<input type="text" placeholder="用户名" v-model="msg.username">
</p>
<p>
密码:
<input type="text" placeholder="密码" v-model="msg.password">
</p>
<p>
<button @click="doLogin">登录</button>
</p>
</div>
</template>
<script setup>
import {ref} from "vue";
import {useRouter} from "vue-router";
const msg = ref({
username: "",
password: ""
})
const router = useRouter()
const doLogin = function () {
// 1、获取数据
console.log(msg.value)
// 2、发送网络请求
// 3、跳转到首页
router.push({name:"mine"})
}
</script>
<style scoped>
.box {
width: 300px;
margin: 100px auto;
}
</style>
AdminView.vue
<template>
<div class="page-header">
<div class="container">
<RouterLink to="/admin/mine">我的</RouterLink>
|
<RouterLink to="/admin/order">订单</RouterLink>
</div>
</div>
<div class="container">
<RouterView/>
</div>
</template>
<script setup>
</script>
<style scoped>
body {
margin: 0;
}
.page-header {
height: 48px;
background-color: cornflowerblue;
line-height: 48px;
}
.page-header a {
display: inline-block;
padding: 0 10px;
}
.container {
width: 980px;
margin: 0 auto;
}
</style>
1.3 导航守卫
请求之前,路由之前,进行拦截。
守护着每一个路由。
浏览器的本地存储
- cookie:有效期+保存
- localStorage:永久保存
- sessionStorage:浏览器关闭后自动消失
index.js
import {createRouter, createWebHistory} from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/login',
name: 'login',
component: () => import('../views/LoginView.vue')
},
{
path: '/admin',
name: 'admin',
component: () => import('../views/AdminView.vue'),
children: [
{
path: "",
redirect: {name: "mine"}
},
{
path: "mine",
name: "mine",
component: () => import('../views/MineView.vue')
},
{
path: "order",
name: "order",
component: () => import('../views/OrderView.vue')
}
]
}
]
})
router.beforeEach(function (to,from,next) {
// 1.访问登录页面,不需要登录就可以直接去查看
if (to.name === "login") {
next()
return
}
// 2.检查用户登录状态,登录成功,继续往后走next();未登录,跳转至登录页面
let username = localStorage.getItem("name")
if (!username){
next({name:"login"})
return;
}
// 3.登录成功且获取到用户信息,继续向后访问
next()
})
export default router
LoginView.vue
<template>
<div class="box">
<p>
用户名:
<input type="text" placeholder="用户名" v-model="msg.username">
</p>
<p>
密码:
<input type="text" placeholder="密码" v-model="msg.password">
</p>
<p>
<button @click="doLogin">登录</button>
</p>
</div>
</template>
<script setup>
import {ref} from "vue";
import {useRouter} from "vue-router";
const msg = ref({
username: "",
password: ""
})
const router = useRouter()
const doLogin = function () {
// 1、获取数据
console.log(msg.value)
// 2、发送网络请求
// 3、本地存储用户信息(登录凭证)
localStorage.setItem("name", msg.value.username)
// 3、跳转到首页
router.push({name:"mine"})
}
</script>
<style scoped>
.box {
width: 300px;
margin: 100px auto;
}
</style>
AdminView.vue
<template>
<div class="page-header">
<div class="container">
<RouterLink to="/admin/mine">我的</RouterLink>
|
<RouterLink to="/admin/order">订单</RouterLink>
<div style="float:right;">
<a @click="doLogout">退出</a>
</div>
</div>
</div>
<div class="container">
<RouterView/>
</div>
</template>
<script setup>
import {useRouter} from "vue-router";
const router = useRouter()
function doLogout() {
localStorage.clear()
router.push({name:"login"})
}
</script>
<style scoped>
body {
margin: 0;
}
.page-header {
height: 48px;
background-color: cornflowerblue;
line-height: 48px;
}
.page-header a {
display: inline-block;
padding: 0 10px;
cursor: pointer;
}
.container {
width: 980px;
margin: 0 auto;
}
</style>