Day 85 VUE——路由
路由
安裝:npm i vue-router -S,
推薦使用 vue add router 添加組件(記得提前把代碼提交到 git)
在 main,js 中
import Vue from ‘vue’
import VueRouter from ‘vue-router’
Vue.use(VueRouter)
vue-router的基本使用
// 1.導(dǎo)入
import Vue from 'vue'
import router from 'vue-router'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
// 2.模塊化機制 使用 Router
Vue.use(router)
// 3.創(chuàng)建路由器對象
export default new VueRouter({
routes:[
{
path:'/',
name:'home',
component:Home
},
{
path:'/about',
name:'about',
component:About
},
{
path:'/user:id',
name:'user',
component:()=>import('@/views/User')
},
{
path:'*',
component:()=>import('@/views/404')
},
]
})
命名路由
const routes = [
{
path: '/',
name: 'Home', // 對路由命名
component: Home
}
]
<template> <div id="nav"> // :to="{name:'Home'}" 使用命名路由 <router-link :to="{name:'Home'}">Home</router-link> | <router-link :to="{name:'About'}">About</router-link> | </div> <router-view/> </template>
動態(tài)路由匹配和路由組件復(fù)用
路由 監(jiān)聽、導(dǎo)航守衛(wèi)
import User from '@/views/User.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
// 準(zhǔn)備重用的路由
{
path:'/user',
name:'User',
component:User
}
]
<template> <div id="app"> <!-- :to="{params:{id:2}} params 是對路由的重用設(shè)置 --> <div id="nav"> <router-link :to="{name:'Home'}">Home</router-link> | <router-link :to="{name:'User',params:{id:1}}">User_1</router-link> | <router-link :to="{name:'User',params:{id:2}}">User_2</router-link> </div> <router-view/> </div> </template>
<template> <div> 我是用戶界面{{ $route.params.id }} </div> </template> <script> export default { // 路由組件會復(fù)用的情況 // 當(dāng)路由參數(shù)變化時,/user/1 切換到 /user/2 時,原來的組件實例會被復(fù)用 // 因為兩個路由渲染了同個組件,復(fù)用高效 // created(){ // console.log(this.$route.params.id) // }, // 監(jiān)聽 // 相應(yīng)路由參數(shù)變化 watch:{ $route:function(to){ console.log(to.params.id) // 發(fā)起 ajax 請求后端接口數(shù)據(jù) 數(shù)據(jù)驅(qū)動視圖 } }, // 導(dǎo)航守衛(wèi) // beforeRouteUpdate(to,form,next){ // console.log(to.params.id) // // 放行,一定要調(diào)用 next,不然會柱塞整個路由 // next() // } } </script> <style> </style>
404路由和路由匹配優(yōu)先級
404 的路由要放到最下面,不然影響正常使用
export default new VueRouter({
routes:[
{
path:'/user:id',
name:'user',
component:()=>import('@/views/User')
},
{
// 404 路由
path:'*',
component:()=>import('@/views/404')
},
]
})
同一個路徑可以匹配多個路由,匹配的優(yōu)先級按照路由的定義順序
誰先定義,誰的優(yōu)先級高
export default new VueRouter({
routes:[
// 同一個路徑可以匹配多個路由,匹配的優(yōu)先級按照路由的定義順序
// 誰先定義,誰的優(yōu)先級高
// {
// path:'/about',
// name:'about',
// component:()=>import('@/views/User')
// },
{
path:'/about',
name:'about',
component:About
},
]
})
路由查詢參數(shù)
history 模式,干凈的網(wǎng)頁地址,沒有 #
// 3.創(chuàng)建路由器對象
export default new VueRouter({
mode:'history', // history 模式,干凈的網(wǎng)頁地址
routes:[
{
path:'/',
name:'home',
component:Home
},
{
path:'/page',
name:'page',
component:()=>import('@/views/Page')
},
]
})
<template> <div id="app"> <div id="nav"> <router-link :to="{name:'user',params:{id:2}}">User_2</router-link> | <router-link :to="{name:'page',query:{id:2,foo:'title'}}">Page</router-link> </div> <router-view/> </div> </template>
<template> <div> <h3>這是一個 Page 界面</h3> </div> </template> <script> export default { created(){ const {id,foo} = this.$route.query console.log(id,foo) // 拿到這些信息就可以與后端進(jìn)行交互了 } } </script> <style> </style>
路由重定向和別名
export default new VueRouter({
mode:'history', // history 模式,干凈的網(wǎng)頁地址
routes:[
{
path:'/',
// 重定向
// redirect:'home'
redirect:{name:'home'}
},
{
path:'/home',
name:'home',
component:Home,
// 別名
alias:'/hhh'
},
{
path:'/about',
name:'about',
component:About
},
]
})
路由組件傳值
// 3.創(chuàng)建路由器對象
export default new VueRouter({
{
path:'/user:id',
name:'user',
component:()=>import('@/views/User'),
// 路由組件傳值
// 方法一
// props:true
// 方法二
props:(route)=>({
id:route.params.id,
title:route.query.title,
})
},
]
})
<template> <div> <h2>這個是 User {{ $route.params.id }}</h2> <h2>使用 props 傳值 {{ id }} --- {{ title }}</h2> </div> </template> <script> export default { props:['id','title'], } </script> <style> </style>
如何使用編程式導(dǎo)航
<template> <div> <button @click="goHome">界面跳轉(zhuǎn)</button> <button @click="goBack">后退</button> </div> </template> <script> export default { methods:{ goBack(){ // 正數(shù) 前進(jìn) 0 刷新界面 負(fù)數(shù) 后退 this.$router.go(-1) }, goHome(){ // 編程時導(dǎo)航 // 方法一 // this.$router.push('/') // 方法二 this.$router.push({ path:'/' }) // 方法三 // this.$router.push({ // name:'user', // params:{id:2} // }) // 方法四 // this.$router.push({ // path:'/reg', // query:{plan:'123'} // }) } } } </script> <style> </style>
嵌套路由的使用
// 3.創(chuàng)建路由器對象
export default new VueRouter({
mode:'history', // history 模式,干凈的網(wǎng)頁地址
routes:[
{
path:'/user:id',
name:'user',
component:()=>import('@/views/User'),
// 路由組件傳值
// 方法一
// props:true
// 方法二
props:(route)=>({
id:route.params.id,
title:route.query.title,
}),
children:[
{
path:'App1',
component:()=>import('@/views/App1')
},
{
path:'App2',
component:()=>import('@/views/App2')
},
]
},
]
})
<template> <div id="app"> <div id="nav"> <!-- 聲明式跳轉(zhuǎn) --> <router-link :to="{name:'user',params:{id:1}}">User_1</router-link> | <router-link :to="{name:'user',params:{id:2}}">User_2</router-link> | <!-- 路由嵌套 --> <router-link to='/user1/App1'>user_1/App1</router-link> | <router-link to='/user2/App2'>user_2/App2</router-link> | </div> <router-view/> </div> </template>
<template> <div> <h2>這個是 User {{ $route.params.id }}</h2> <!-- 子路由的文件出口 --> <router-view></router-view> </div> </template>
命名視圖的使用
// 3.創(chuàng)建路由器對象
export default new VueRouter({
mode:'history', // history 模式,干凈的網(wǎng)頁地址
routes:[
{
path:'/about',
name:'about',
// component:About
// 設(shè)置命名視圖
components:{
default:About, // 默認(rèn)的名字
right:()=>import('@/views/right'),
left:()=>import('@/views/left'),
}
},
]
})
<template> <div id="app"> <!-- 渲染 Home 的 --> <router-view/> <router-view name='right' class="right"></router-view> <router-view name='left' class="left"></router-view> </div> </template>
使用全局守衛(wèi)做登錄操作
// 1.導(dǎo)入
import Vue from 'vue'
import router from 'vue-router'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
// 2.模塊化機制 使用 Router
Vue.use(router)
// 3.創(chuàng)建路由器對象
export default new VueRouter({
mode:'history', // history 模式,干凈的網(wǎng)頁地址
routes:[
{
path:'/note',
name:'note',
component:()=>import('@/views/Note')
},
{
path:'/login',
name:'login',
component:()=>import('../views/Login')
},
{
path:'*',
component:()=>import('@/views/404')
},
]
})
<template> <div id="app"> <div id="nav"> <!-- 聲明式跳轉(zhuǎn) --> <router-link :to="{name:'home'}">Home</router-link> | <router-link :to="{name:'about'}">About</router-link> | <router-link :to="{name:'note'}">我的筆記</router-link> | </div> </div> </template>
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
// 全局守衛(wèi)
router.beforeEach((to,from,next)=>{
// 判斷用戶是否訪問了 note
if(to.path === '/note'){
const user = JSON.parse(localStorage.getItem('user'))
if (user) {
// 用戶已登錄
next()
}else{
// 用戶沒有登錄 跳轉(zhuǎn)到登錄界面
next('/login')
}
}
next()
})
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
<template> <div> <h2>登錄界面</h2> 賬號:<input type="text" v-model="user"> 密碼:<input type="password" v-model="pawd"> <input type="button" value='登錄' @click="login"> </div> </template> <script> export default { data(){ return{ user:'', pawd:'' } }, methods:{ login(){ // 1.獲取賬號密碼 // 2.模擬后端交互 setTimeout(() => { let data = { user:this.user } // 保存用戶名到本地 localStorage.setItem('user',JSON.stringify(data)); // 跳轉(zhuǎn)到 note this.$router.push('/note') }, 1000); } } } </script> <style> </style>
組件內(nèi)部的守衛(wèi)的應(yīng)用
// 1.導(dǎo)入
import Vue from 'vue'
import router from 'vue-router'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
// 2.模塊化機制 使用 Router
Vue.use(router)
// 3.創(chuàng)建路由器對象
export default new VueRouter({
mode:'history', // history 模式,干凈的網(wǎng)頁地址
routes:[
{
path:'/edit',
name:'edit',
component:()=>import('../views/Edit')
},
{
path:'*',
component:()=>import('@/views/404')
},
]
})
<template> <div id="app"> <div id="nav"> <router-link :to="{name:'edit'}">編輯</router-link> | </div> </div> </template>
<template> <div> <textarea v-model="edit" id="" cols="30" rows="10"></textarea> <button @click='save'>保存</button> <ul> <li v-for="(item,index) in list" :key="index"> <h4>{{ item.title }}</h4> </li> </ul> </div> </template> <script> export default { data(){ return{ edit:'', list:[] } }, methods:{ save(){ this.list.push({ title:this.edit }) // 清空文本框 this.edit = ''; } }, // beforeRouteUpdate(to,from,next){ // // 組件重用時 這個方法才起作用 // next(); // }, beforeRouteLeave(to,from,next){ if (this.edit) { alert('請保存后在離開') next(false) }else{ next() } } } </script> <style> </style>
路由meta元信息實現(xiàn)權(quán)限控制
// 3.創(chuàng)建路由器對象
export default new VueRouter({
mode:'history', // history 模式,干凈的網(wǎng)頁地址
routes:[
{
path:'/page',
name:'page',
component:()=>import('@/views/Page'),
meta:{
// 加入到黑名單
requireAuth:true
}
},
{
path:'/edit',
name:'edit',
component:()=>import('../views/Edit'),
meta:{
// 加入到黑名單
requireAuth:true
}
},
{
path:'*',
component:()=>import('@/views/404')
},
]
})
<template> <div> <h2>登錄界面</h2> 賬號:<input type="text" v-model="user"> 密碼:<input type="password" v-model="pawd"> <input type="button" value='登錄' @click="login"> </div> </template> <script> export default { data(){ return{ user:'', pawd:'' } }, methods:{ login(){ // 1.獲取賬號密碼 // 2.模擬后端交互 setTimeout(() => { let data = { user:this.user } // 保存用戶名到本地 localStorage.setItem('user',JSON.stringify(data)); // 跳轉(zhuǎn)到 note this.$router.push({ path:this.$route.query.redirect }) }, 1000); } } } </script> <style> </style>
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
// 全局守衛(wèi)
router.beforeEach((to,from,next)=>{
if(to.matched.some(record=>record.meta.requireAuth)){
// 需要權(quán)限 在黑名單中
if (!localStorage.getItem('user')) {
next({
path:'/login',
query:{
redirect:to.fullPath
}
})
}else{
next();
}
}
// 在白名單中
next();
})
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
路由組件內(nèi)在什么時機獲取數(shù)據(jù)
module.exports = {
devServer:{
before:(app,serve)=>{
app.get('/api/post',(req,res)=>{
res.json({
title:'vue-router 的數(shù)據(jù)獲取',
body:'在導(dǎo)航完成之后獲取數(shù)據(jù)'
})
})
}
}
}
// 1.導(dǎo)入
import Vue from 'vue'
import router from 'vue-router'
import VueRouter from 'vue-router'
// 2.模塊化機制 使用 Router
Vue.use(router)
// 3.創(chuàng)建路由器對象
export default new VueRouter({
mode:'history', // history 模式,干凈的網(wǎng)頁地址
routes:[
{
path:'/post',
name:'post',
component:()=>import('../views/Post')
},
{
path:'*',
component:()=>import('@/views/404')
},
]
})
<template> <div id="app"> <div id="nav"> <!-- 聲明式跳轉(zhuǎn) --> <router-link :to="{name:'home'}">Home</router-link> | <router-link :to="{name:'about'}">About</router-link> | <router-link :to="{name:'note'}">我的筆記</router-link> | <router-link :to="{name:'edit'}">編輯</router-link> | <router-link :to="{name:'post'}">Post</router-link> | </div> </div> </template>
<template> <div class="post"> <div v-if="loading" class="loading">Loading...</div> <div v-if="error" class="error">{{ error }}</div> <div v-if="post"> <h2>標(biāo)題:{{ post.title }}</h2> <h2>內(nèi)容:{{ post.body }}</h2> </div> </div> </template> <script> export default { data(){ return{ post:null, error:null, loading:false } }, // 導(dǎo)航完成之后獲取數(shù)據(jù) created(){ console.log(this.$https) this.getPostData() }, watch:{ $route:"getPostData" }, methods:{ async getPostData(){ try { this.loading = true const {data} = await this.$https.get('/api/post') this.loading = false this.post = data; } catch (error) { console.log(error); this.error = error.toString() } } } } </script> <style> </style>

浙公網(wǎng)安備 33010602011771號