目錄
router的基本使用
main.js
App.vue
router檔案夾下的index.js(抽離router)
動態傳參+編程式導航
App.vue
user.vue組件
嵌套路由
路由傳參,懶加載
router的index.js
Info組件
User組件
App.vue
守衛鉤子(全域+獨享+組件內的守衛)
登錄頁
路由
About.vue
補充 :
解決重復點擊路由報錯:
$route和$router的區別:
router的基本使用
main.js
- 掛載路由
import Vue from 'vue'
import App from './App'
// 默認匯入router檔案夾下的內容
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,//掛載路由,把路由注入為Vue物件方便使用
render: h => h(App)
})
App.vue
- 路由跳轉的兩種方法
router-link 其他屬性:
- to:用于指定跳轉的路徑
- tag:可以指定router-link標簽之后渲染成什么html元素
- replace(沒有回傳記錄):在history模式下指定router-link使用的是replaceState,而不是一個pushState()
- active-class:設定對應路由匹配成功時,會給當前選中元素設定一個active-class屬性類名
<template>
<div id="app">
<!-- 利用router-view進行顯示路由渲染的組件,切換的是掛載的組件,其他內容不會發生改變-->
<router-view></router-view>
<!-- 默認router-link是被渲染成a標簽的 -->
<!-- to點擊后面的路徑就會渲染,tag跟要渲染成的html標簽 replace不能回傳上一頁-->
<!-- 當某一個路由處于活躍狀態的話vue會自動添加class,也可以用active-class來改類名 -->
<!-- <router-link to="/home" tag="button" replace active-class="active"
>首頁</router-link>
<router-link to="/about" replace>關于</router-link> -->
<button @click="homeClick">首頁</button>
<button @click="aboutClick">關于</button>
</div>
</template>
<script>
export default {
name: "App",
methods: {
homeClick() {
// 通過代碼也可以修改路徑
// vue定義每個元素里都有一個router屬性
// push = pushState點擊完之后還可以回傳上一步
// this.$router.push('/home')
this.$router.replace("/home");
},
aboutClick() {
this.$router.replace("/about");
},
},
};
</script>
router檔案夾下的index.js(抽離router)
路由模式:
hash:歷史模式,不會制造頁面重繪
history:不會有歷史,不會制造頁面重繪
注意:路由重復點擊會報錯,降級router插件到到3.5版本以下
此處可以配置活躍路由的類名,如果多個router-link都要類名,可以在路由中統一配置
// 參考檔案
import Vue from 'vue'
import Router from 'vue-router'
import Home from '../components/Home'
import About from '../components/About'
// 1.通過Vue.use(插件),安裝插件
Vue.use(Router)
// export default(匯出) 將Router物件傳入到vue實體
export default new Router({
// 2.創建Router物件
// 配置路由和組件之間的映射關系
// routes是固定寫法
routes: [
{
path:'',
// 重定向
redirect:'/home'
},
{
// 定義路徑
path: '/home',
name: 'HelloWorld',
// component顯示
component: Home
},
{
path:'/about',
component:About //組件名
},
],
mode:'history',
// 全域配置激活路由的class類名,處與活躍(動態)就會用上這個類名
linkActiveClass:'active'
})
動態傳參+編程式導航
路由路徑后加/:id就可以變成動態路由
App.vue
<template>
<div id="app">
<!-- <router-link to="/home" tag="button">首頁</router-link>
<router-link to="/user">用戶</router-link> -->
<!-- 增加了兩個到user的導航,使用不同的to -->
<!-- <router-link to="/user/1" tag="button">1</router-link>
<router-link to="/user/2" tag="button">2</router-link> -->
<!-- 動態路由 -->
<!-- <router-link :to="'/user/'+user1" tag="button">1</router-link>
<router-link :to="'/user/'+user2" tag="button">2</router-link> -->
<!-- 編程式導航,點擊觸發事件函式 -->
<button @click="toHome">首頁</button>
<button @click="toUser">用戶</button>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
user1:'一',
user2:'二'
}
},
components: {
},
methods: {
toHome(){
//去首頁
// 在函式中,通過組件實體物件下的$router,獲取路由物件,然后push到要跳轉的路由
// this.$router.push('/home')//祖父串的方式進行跳轉
// this.$router.push({path:'/home'})//以物件的方式跳轉
this.$router.replace('/home')//replace沒歷史記錄
},
toUser(){
//去用戶
this.$router.push('/user/'+this.user2)
}
},
}
</script>
user.vue組件
<template>
<div id="user">
<h2>用戶組件</h2>
<h3>歡迎 <span>{{uname}}</span> 來到用戶頁面</h3>//輸出一或二切換
<!-- 直接在模板中獲取資料 ,$route接收,$router發送-->
<h4>輸出名字:{{$route.params.id}}</h4>
</div>
</template>
<script>
export default {
computed:{
uname(){
// this是查看當前組件有哪些方法
// console.log(this);
// 輸出名字
return this.$route.params.id
}
}
}
</script>
嵌套路由
頁面中使用this.$route:獲取活躍的組件;
this.$router:獲取router整個路由
//配置路由的相關資訊
import Vue from 'vue'
import Router from 'vue-router'
// 1.通過vue.use安裝插件
Vue.use(Router);
// 參考組件
import Home from '../components/Home.vue'
import User from '../components/User.vue'
import News from '../components/News.vue'
import Msg from '../components/Msg.vue'
// 配置路由和組件之間的參考關系
const routes =[
{
path:'/',
// 重定向redirect
redirect:'/home'
},
{
path:'/home',
component:Home ,
// 使用嵌套路由用children屬性
children:[
{
path:'/home',
redirect:'/home/news'
},
{//子路由加斜杠會被當作根路徑
path:'news',
component:News
},
{
path:'msg',
component:Msg
},
]
},
{
path:'/user/:id',
component:User
},
]
// 創建vue-router物件
const router = new Router({
routes,
// 沒歷史
mode:'history',
linkActiveClass:'active'
})
// 3.把router匯出給vue實體
export default router
// $route:指向活躍的組件
// $router:指向router整個路由
路由傳參,懶加載
router的index.js
/配置路由的相關資訊
import Vue from 'vue'
import Router from 'vue-router'
// 1.通過vue.use安裝插件
Vue.use(Router);
// 懶加載
const User = ()=> import('../views/User.vue')
const Info = ()=> import('../views/info.vue')
const routes =[
// {
// path:'/home',
// name:'Home',//命名路由
// component:Home
// },
{
// 配置動態路由
path:'/user/:id',
name:'User',
// 懶加載
component:User
},
{
path:'/info',
name:'Info',
component:Info
},
]
const router = new Router({
routes,
// 沒歷史
mode:'history',
// linkActiveClass:'active'
})
// 3.把router匯出給vue實體
export default router
Info組件
<template>
<div id="info">
<h2>這是資訊組件</h2>
//$route接收引數
<h3>姓名:{{$route.query.name}}</h3>
<h3>年齡:{{$route.query.age}}</h3>
</div>
</template>
User組件
<template>
<div id="user">
<h2>用戶資訊</h2>
<!-- 取值用$route -->
//頁面中有兩個params.id,點擊誰就顯示哪個id
<h3>用戶編號{{$route.params.id}}</h3>
</div>
</template>
App.vue
<template>
<div id="app">
<router-link to="/user/2021">user</router-link>|
<router-link to="/info">info</router-link>
<!-- 編程式導航 -->
<button @click="toUser">user</button>
<hr />
<!-- 用path -->
<!-- <router-link :to="{path:'/user/'+userId}">user--path</router-link><br> -->
<!-- 用name,params傳參 -->
<router-link :to="{name:'User',params:{id:userId}}">user--name</router-link>
<div>
<!-- 通過query傳參, /info?name=rh&age=22&sex=男 -->
<router-link :to="{path:'/info',query:{name:'rh',age:22,sex:'男'}}">info-path</router-link>
<!-- 編程式導航,/info?name=有意&age=22 -->
<button @click="toInfo">info</button>
</div>
<hr>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
userId: '20211',
};
},
methods: {
// 路由傳參:
// query和path配合
// params和name配合
// name:命名路由
toUser() {
// params傳參
this.$router.push({ name: "User", params: { id: "567" } });
},
toInfo(){
// 沒歷史記錄
//$router傳參
this.$router.replace({name:'Info',
query:{
name:'有意',
age:22,
}})
}
},
};
</script>
守衛鉤子(全域+獨享+組件內的守衛)
登錄頁
<template>
<div id="login">
<h3>登錄</h3>
賬號:<input type="text" name="" id="" v-model="userName" />
密碼:<input
type="text"
v-model="userPass"
/>
<button @click="login">登錄</button>
</div>
</template>
<script>
export default {
data() {
return {
userName: "",
userPass: "",
};
},
methods: {
login() {
// 通過window物件給uname和upass賦值;
var name = window.uname = "admin";
var pass = window.upass = "123";
if (this.userName == name && this.userPass == pass) {
alert("登錄成功");
// 放行后跳轉到首頁
this.$router.replace("/");
}else{
alert('賬號不對')
}
},
},
};
</script>
路由
//配置路由的相關資訊
import Vue from 'vue'
import Router from 'vue-router'
// 1.通過vue.use安裝插件
Vue.use(Router);
// 懶加載
const User = ()=> import('../views/User.vue')
const Info = ()=> import('../views/info.vue')
const Login = ()=> import('../views/Login.vue')
const routes =[
{
// 配置動態路由
path:'/user/:id',
name:'User',
// 懶加載
component:User,
// 獨享路由守衛
beforeEnter(to, from, next){
next()
}
},
{
path:'/info',
name:'Info',
component:Info
},
{
path:'/Login',
name:'Login',
component:Login
},
]
const router = new Router({
routes,
// 沒歷史
mode:'history',
// linkActiveClass:'active'
})
// 全域前置鉤子:beforeEach
// 在進入前做一些事
// to:要去的路由
// from:來的路由
// next:放行,默認引數是false
//上面把賬號密碼放到window這里也可以訪問到
router.beforeEach((to,from,next)=>{
if(to.name !=='Login'){//驗證是否登錄
if(window.uname && window.upass){
next();
}else{
alert('請先登錄')
next('/Login')
}
}
next();
})
// 全域的后置
// to:要去跳轉的路由
// from:來的路由
router.afterEach((to,from)=>{
console.log('歡迎'+window.uname);
})
export default router
About.vue
<template>
<div class="about">
<h1>about</h1>
<button @click="toA">A</button>
<button @click="toB">B</button>
<div style="border:2px red solid">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: "About",
data() {
return {
msg: "這是組件的路由守衛",
};
},
methods: {
toA(){
this.$router.push('/about/a')
},
toB(){
this.$router.push('/about/b')
},
},
// 組件內的路由守衛
// beforeRouteEnter相當于生命周期的beforeCreate
beforeRouteEnter(to, from, next) {
// 不能獲取組件實體
// 當守衛執行前,組件實體還未創建
next();
},
beforeRouteLeave(to, from, next) {
// 導航離開組件的時候對應路由呼叫
// 可以訪問組件實體
// console.log(this.msg);
next();
},
beforeRouteUpdate(to, from, next) {
// 當前路由改變,但是該組件被復用時才觸發
// 在子路由a/b之間跳轉的時候才會觸發
next();
},
};
</script>
補充 :
解決重復點擊路由報錯:
1.在路由頁引入以下代碼:
//Router自己定義的路由名
const originalPush = Router.prototype.push;
Router.prototype.push = function push(location){
return originalPush.call(this,location).catch(err=>err);
}
2.或者直接降低router版本到3.5以下 ,
$route和$router的區別:
- $router為VueRouter實體,想要導航到不同URL,則使用$router.push方法
- $route為當前router跳轉物件里面可以獲取name、path、query、params等
小編公_號:前端老實人;期待各位小伙伴加入同學們一起學習的隊伍討論哦?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/302256.html
標籤:其他
