欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue中vue-router路由使用示例詳解

 更新時間:2024年06月25日 10:28:38   作者:愛編程的小學(xué)究  
Vue Router是Vue提供的路由管理器,將組件與路由一一對應(yīng)起來,這種對應(yīng)關(guān)系就路由,這篇文章主要介紹了Vue中vue-router路由使用,需要的朋友可以參考下

前言

Vue Router是Vue框架中非常重要的一個功能。

目標(biāo)

1 單頁面應(yīng)用與多頁面應(yīng)用的區(qū)別;
2 vue-router的具體實現(xiàn)方法;
3 路由模式有哪幾種,有什么區(qū)別;
4 如何進行路由守衛(wèi)與路由緩存;

一 路由的概念

概念
Vue Router是Vue提供的路由管理器。將組件與路由一一對應(yīng)起來,這種對應(yīng)關(guān)系就路由。
Vue是一個典型的SPA單頁面應(yīng)用框架。SPA單頁面是指網(wǎng)站只有一個html頁面,所有的頁面切換都只在這個一個頁面中完成。不同組件的切換全部交由路由來完成.
單頁面應(yīng)用與多頁面應(yīng)用
在編程開發(fā)興起時,多個html實現(xiàn)頁面的切換,這就是早期的MPA多頁面應(yīng)用。隨著技術(shù)的發(fā)展,這種頁面切換方式的弊端也逐漸的顯現(xiàn)出來,例如每次切換頁面都需要加載資源用戶體驗極其不好,造成服務(wù)器壓力也非常的大。為了解決多頁面應(yīng)用問題,SPA單頁面應(yīng)用應(yīng)運而生。
SPA單頁面應(yīng)用是指只有一個html頁面,不同組件切換通過路由來實現(xiàn)。頁面在首次進入時加載相關(guān)的資源,內(nèi)容功能都被封裝到組件中,頁面切換底層變成了組件切換,這樣就解決了多頁面應(yīng)用的很多弊端。但是單頁面應(yīng)用也不是完美無瑕的,首次進入加載相關(guān)資源會導(dǎo)致SPA的首頁加載慢

分類實現(xiàn)方式頁面性能開發(fā)效率用戶體驗首屏加載其他頁面加載SEO
單頁一個html按需更新性能高非常好
多頁多個html整頁更新性能低一般一般優(yōu)

SPA單頁面與MPA多頁面應(yīng)用方式各有優(yōu)缺點,根據(jù)自己的項目需要選擇更適合自己項目的開發(fā)方式(現(xiàn)在主流的是SPA應(yīng)用)。

vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,適合用于構(gòu)建單頁面應(yīng)用。

二 準(zhǔn)備工作

1 安裝

npm install vue-router@3.6.5 --save

這個地方需要注意的是你的Vue版本要與vue-router版本對應(yīng)上,否則安裝上也無法使用
vue2.x對應(yīng)的vue-router版本是 vue-router3.x
vue3.x對應(yīng)的vue-router版本是 vue-router4.x

2 引入-注冊-創(chuàng)建路由

import Router from ‘vue-router' // 引入
Vue.use(Router) // 注冊
new Router({})// 創(chuàng)建路由

對于一個項目來說,路由與組件映射不可能只有一兩個。
當(dāng)路由非常多時,將路由配置直接寫在main.js中顯然不太好維護,這里我直接建一個文件來進行路由封裝router.js

import Vue from 'vue'
import Router from 'vue-router'
// 引入組件
import helloWord from '../views/HelloWord'
import School from '../views/School'
Vue.use(Router)
// 路由與組件綁定
export default new Router({
    routes: [ {
        name:'school',
        path: '/school',
        component: School
    },{
        name:'hellword',
        path: '/helloWord',
        component: helloWord,
    }]
})

3 全局引入路由

在main.js中全局引入

import router from './router'
new Vue({
  el: '#app',
  router, // 引入路由
  render: h => h(App),
  beforeCreate(){
    // 全局事件總線
    Vue.prototype.$bus = this
  }
}).$mount('#app')

以上全部的準(zhǔn)備工作已完成

若以上操作都沒有問題,可以在控制臺打印vur-router提供的方法$ router、$ route。打印成功就可以使用路由了

$route 每個組件自己的路由信息
$router 全局都一樣,是路由的共用方法

在這里插入圖片描述

三 路由基本方法

3.1 聲明式導(dǎo)航與編程式導(dǎo)航

聲明式路由導(dǎo)航
聲明式導(dǎo)航是通過在模板中使用特定的指令來實現(xiàn)頁面導(dǎo)航。在Vue模板中,使用< router-link>組件來創(chuàng)建導(dǎo)航鏈接,通過設(shè)置to屬性指定目標(biāo)路由的路徑或命名路由。例如:

<router-link to="/search">跳轉(zhuǎn)到搜索頁面</router-link>

優(yōu)點:簡單直觀,通過在模板中編寫導(dǎo)航鏈接,不需要編寫額外的Js代碼。
編程式導(dǎo)航
編程式導(dǎo)航是通過在Js代碼中使用Vue Router提供的API來實現(xiàn)頁面導(dǎo)航。通過訪問$router對象,可以使用其提供的方法進行頁面跳轉(zhuǎn),例如push、replace、go等。例如:

this.$router.push('/search');

優(yōu)點:可以在Js代碼中根據(jù)條件或動態(tài)數(shù)據(jù)進行導(dǎo)航,更加靈活和可控。

1 聲明式導(dǎo)航

router-link
配置 to 屬性指定路徑(必須) 。本質(zhì)還是a 標(biāo)簽,to 無需 #
to后面可以是path或name

// to path,默認(rèn)類似 $router.push 跳轉(zhuǎn)路由并增加一條路由歷史記錄
<router-link class="link" to="/helloWord">Helloword</router-link>
// to name
<router-link class="link" to="helloword">Helloword</router-link>
// 替換當(dāng)前歷史記錄,跳轉(zhuǎn)到指定路由
<router-link class="link" replace to="helloword">Helloword</router-link>

2 編程式導(dǎo)航

$router.push
跳轉(zhuǎn)到指定路由,并在路由信息中增加一條歷史信息

<button class="link" @click="jump(1)">hellword</button>
jump(type) {
      console.log('type', type)
      if (type == 1) {
        // path 方法跳轉(zhuǎn)
        // this.$router.push('/helloWord')
        // this.$router.push({path:'/helloWord'})
        // name 方法跳轉(zhuǎn)
        this.$router.push({name:'hellword'})
      } else {
        this.$router.push('/school')
      }
}

$router.replace
替換當(dāng)前歷史記錄,跳轉(zhuǎn)到指定路由

<button class="link" @click="jump(1)">hellword</button>
jump(type) {
      console.log('type', type)
      if (type == 1) {
         this.$router.replace({name:'hellword'})
      } else {
        this.$router.push('/school')
      }
}

$router.go()
可以在瀏覽歷史中前進和后退(正數(shù)- 前進,0 - 刷新,負數(shù) - 后退)

this.$router.go(0) // 刷新
this.$router.go(-1)  // 后退1

$ router.back()
在歷史記錄中,后退到上一個頁面
$ router.forward()
在歷史記錄中,前進到下一個頁面

完整代碼

<template>
  <div id="app">
    <hr />
    <div class="flex">
      <div class="nav">
        <h1>方式一</h1>
        <router-link class="link" to="/helloWord">Helloword</router-link>
        <router-link class="link" to="/school">school</router-link>
        <h1>方式二</h1>
        <button class="link" @click="jump(1)">hellword</button>
        <button class="link" @click="jump(2)">school</button>
      </div>
      <div class="content">
        <router-view></router-view>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
    };
  },
  mounted() {
  },
  methods: {
    jump(type) {
      console.log('type', type)
      if (type == 1) {
        // path 方法跳轉(zhuǎn)
        // this.$router.push('/helloWord')
        // this.$router.push({path:'/helloWord'})
        // name 方法跳轉(zhuǎn)
        // this.$router.push({name:'hellword'})
      } else {
        this.$router.push('/school')
      }
    },
  },
};
</script>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.flex {
  display: flex;
}
.nav {
  width: 120px;
  display: flex;
  flex-direction: column;
}
.link {
  margin: 3px 10px;
  width: 100px;
  height: 60px;
  line-height: 60px;
  font-size: 20px;
  text-decoration: none;
  border: 1px solid blue;
  border-radius: 4px;
}
.content {
  width: calc(100% - 100px);
  height: 800px;
  background-color: #eee;
}
</style>

運行效果

3.2 嵌套(多級)路由

school組件下還有student路由,就可以如下方式寫

  • children子路由中的path不加/
  • 子頁面訪問路徑 /school/student
export default new Router({
    routes: [ {
        name:'school',
        path: '/school',
        component: School,
        children:[{
            name:'student',
            path: 'student',
            component: Student,
        }]
    },{
        name:'helloword',
        path: '/helloWord',
        component: helloWord,
    }]
})

school組件

<template>
  <div>
    <h1>我是School</h1>
    <hr>
    <div @click="$router.push('/school/student')">查看學(xué)生</div>
    <router-view></router-view>
  </div>
</template>

3.3 路由中的參數(shù)

3.3.1 query參數(shù)

顯式傳參
1 路徑后拼接參數(shù)

2 編程式路由中傳query參數(shù)

this.$router.push({path:'/helloWord',query:{id:'01',name:'張二'}})

3 注冊路由傳參
注冊路由時加參數(shù),這個基本不用,了解即可

{
 name:'helloword',
 path: '/helloWord',
 component: helloWord,
 query:{
     id:'02',
     name:'張三'
  }
}

3.3.2 params參數(shù)

1 路徑后傳參

path: '/helloWord/:id/:name'   // id、name位置對照

2 編程式路由傳參

this.$router.push({name:'helloword',params:{id:'01',name:'張二'}})

特別注意:路由攜帶params參教時,params不能和path一起使用會無效,params只能和name一起使用

params方法只有以上兩種方式傳遞參數(shù)

3.4 命名路由

然后我們可以使用 name 而不是 path 來傳遞 to 屬性給 < router-link>

export default new Router({
    routes: [ {
        name:'school',
        path: '/school',
        component: School,
        children:[{
            name:'student',
            path: 'student',
            component: Student,
        }]
    }]
})

3.5 props

路由的props傳參
1 值為對象,該對象中的所有key-value都會以props的形式傳給組件

{
   name:'helloword',
   path: '/helloWord',
   component: helloWord,
   props:{id:'003',name:'林淼淼'},
}
<template>
  <div>
    <h1>我是HelloWord</h1>
  </div>
</template>
<script>
export default {
  name: 'HelloWord',
  props:['id','name'], // 接收傳參
  mounted(){
    console.log('=====id======',this.id)
    console.log('=====name======',this.name)
  }
}
</script>

2 布爾值,若值為真,就會把該路由組件收到的所有params參數(shù),以props的形式傳給組件

{
   name:'helloword',
   path: '/helloWord',
   component: helloWord,
   props:true
}
this.$router.push({name:'helloword',params:{id:'01',name:'張二'}})
<template>
  <div>
    <h1>我是HelloWord</h1>
  </div>
</template>
<script>
export default {
  name: 'HelloWord',
  props:['id','name'], // 接收傳參
  mounted(){
    console.log('=====id======',this.id)
    console.log('=====name======',this.name)
  }
}
</script>

3 值為函數(shù)

{
   name:'helloword',
   path: '/helloWord',
   component: helloWord,
   props($route){
       // $route組件的路由信息
       return {id:$route.query.id,name:$route.query.name}
   },
   query:{
       id:'02',
       name:'張三'
   }
}
<template>
  <div>
    <h1>我是HelloWord</h1>
  </div>
</template>
<script>
export default {
  name: 'HelloWord',
  props:['id','name'], // 接收傳參
  mounted(){
    console.log('=====id======',this.id)
    console.log('=====name======',this.name)
  }
}
</script>

四 路由守衛(wèi)

執(zhí)行順序

4.1 全局路由守衛(wèi)(前/后置)

routes路由中的屬性不可以隨意的自定義,而是要在meta屬性中自定義,其他地方自定義屬性都會失效

Vue.use(Router)
const routes = new Router({
    routes: [ {
        name:'school',
        path: '/school',
        component: School,
        meta:{
            isAuth:true,
            title:'學(xué)校'
        },
        children:[{
            name:'student',
            path: 'student',
            component: Student,
            meta:{
                isAuth:true,
                title:'學(xué)生'
            },
        }]
    },
    {
        name:'helloword',
        path: '/helloWord',
        component: helloWord,
        meta:{
            isAuth:true,
            title:'首頁'
        },
    }]
})```
**前置路由守衛(wèi) beforeEach**,顧名思義在路由跳轉(zhuǎn)之前執(zhí)行,這里一般可以做頁面權(quán)限校驗等操作
```c
// 前置路由守衛(wèi)
/**
to 目的地
from 起始地
next 放行
**/
routes.beforeEach((to,from,next)=>{
    if(to.meta.isAuth){
        next()
    }
})

前置路由守衛(wèi) beforeEach,顧名思義在路由跳轉(zhuǎn)之前執(zhí)行,這里一般可以做頁面權(quán)限校驗等操作。
初始化時候、每次路由切換之前被調(diào)用

// 前置路由守衛(wèi)
/**
to 目的地
from 起始地
next 放行:路由跳轉(zhuǎn),next下的代碼還會繼續(xù)的執(zhí)行
**/
routes.beforeEach((to,from,next)=>{
    if(to.meta.isAuth){
        next()
    }else{
        alert('你沒有權(quán)限')
    }
})

后置路由守衛(wèi) afterEach,顧名思義在路由跳轉(zhuǎn)之后執(zhí)行,這里可以做title更改。
初始化時候、每次路由切換之后被調(diào)用

// 后置路由守衛(wèi)
/**
to 目的地
from 起始地
**/
routes.afterEach((to,form)=>{
    document.title = to.meta.title
})

4.2 獨享路由守衛(wèi)

獨享路由守衛(wèi) beforEnter,顧名思義就是某一個路由獨自享有的,只由觸發(fā)改路由時才會執(zhí)行類似路由的前置
執(zhí)行順序:全局前置 --> 獨享路由 --> 全局后置

        children:[{
            name:'student',
            path: 'student',
            component: Student,
            meta:{
                isAuth:true,
                title:'學(xué)生'
            },
            // to form 用法同上
            beforeEnter:(to,form,next)=>{
                console.log(to,form);
                next()
            }
        }]

4.3 組件內(nèi)路由守衛(wèi)

在組件內(nèi)部設(shè)置該組件的路由守衛(wèi)
beforeRouteEnter 進入該組件時觸發(fā)
beforeRouteLeave 離開該組件時觸發(fā)(切換路由)

<template>
  <div>
    <h1>我是HelloWord</h1>
  </div>
</template>
<script>
export default {
  name: 'HelloWord',
  props:['id','name'],
  data(){
    return{}
  },
  // 進入該該組件時觸發(fā)
  beforeRouteEnter(to,from,next){
    console.log('=====enter-to======',to)
    console.log('=====enter-from======',from)
    next()
  },
  // 離開該組件時觸發(fā)
  beforeRouteLeave(to,from,next){
    console.log('=====leave-to======',to)
    console.log('=====leave-from======',from)
    next()
  }
}
</script>

五 其它

5.1 路由模式

1. hash模式
修改為hash模式

const routes = new Router({
    // 模式  默認(rèn)為hash
    mode: 'hash',
})

#及其后面的值都是hash值

將打包后的文件發(fā)布到服務(wù)器上(如何沒有線上服務(wù)器可以啟動本地服務(wù)發(fā)布參考:)
hash值有特殊的#標(biāo)識,不會傳送給服務(wù)器端

2. history模式
修改為history模式

const routes = new Router({
    // 模式
    mode: 'history',
})

打包后發(fā)到本地?zé)o服務(wù)上,點擊可以正常的訪問,但是一旦刷新頁面就如下所示,這是因為刷新的時候頁面會當(dāng)成資源去請求服務(wù)器,服務(wù)器找不到此接口就會報錯

解決辦法:

  • node中connect-history-api-fallback插件是專門解決此問題的;
  • ngix中配置分辨是否前端路由
  • 通過后端去處理

3. 總結(jié)
hash模式

1.地址中永遠帶著#號,不美觀。
2.若以后將地址通過第三方手機app分享,若app校驗嚴(yán)格,則地址會被標(biāo)記為不合法。
3.兼容性較好。
4.hash值不會包含在 HTTP 請求中,即: hash值不會帶給服務(wù)器。

history模式

1.地址干凈,美觀。
2.兼容性和hash模式相比略差。
3.應(yīng)用部署上線時需要后端人員支持,解決刷新頁面服務(wù)端404的問題。

5.2 keep-alive緩存路由組件

原理
我們知道vue是通過vnode實現(xiàn)保存節(jié)點的,而keep-alive本身也是通過保存vnode來實現(xiàn)緩存的,而不是直接存儲DOM結(jié)構(gòu)。其實就是將需要緩存的VNode節(jié)點保存在this.cache中,在render時,如果VNode的name符合在緩存條件(可以用include以及exclude控制),則會從this.cache中取出之前緩存的VNode實例進行渲染。

作用
keep-alive組件是vue2.0提供的一個緩存組件,在組件切換過程中把切換出去的組件保留在內(nèi)存,不被銷毀,防止重復(fù)渲染DOM,減少加載時間及性能消耗,提高用戶體驗性

效果
keep-alive組件,只要將子組件嵌套在這里面就可以實現(xiàn)組件的緩存,當(dāng)頁面返回時數(shù)據(jù)不會丟失,實現(xiàn)了我們常見的歷史頁面不刷新的效果

參數(shù)Props
include - 類型字符串、數(shù)組以及正則表達式,只有匹配的組件會被緩存
exclude - 類型字符串、數(shù)組以及正則表達式,匹配的組件不會被緩存
max - 類型字符或者數(shù)字,可以控制緩存組件的個數(shù),緩存組件的最大值

// 只緩存組件name為a或者b的組件
<keep-alive include="a,b"> 
  <component />
</keep-alive>
?
// 組件name為c的組件不緩存(可以保留它的狀態(tài)或避免重新渲染)
<keep-alive exclude="c"> 
  <component />
</keep-alive>
?
// 如果同時使用include,exclude,那么exclude優(yōu)先于include, 下面的例子只緩存a組件
<keep-alive include="a,b" exclude="b"> 
  <component />
</keep-alive>
?
// 如果緩存的組件超過了max設(shè)定的值5,那么將刪除第一個緩存的組件
<keep-alive exclude="c" max="5"> 
  <component />
</keep-alive>

用法
1、與include結(jié)合使用

// include 只緩存組件名字為home的組件,其他組件不會緩存,而exclude恰好相反
<keep-alive include="home">
   <router-view />
</keep-alive>

2、結(jié)合Router中的meta屬性來控制組件緩存

{
      path: '/',
      name: 'home',
      meta:{
        keepAlive:true // 需要緩存
      },
      component: Home,
      children: [
        {
          path: 'goods',
          name: 'goods',
          component: Goods,
          meta: {
            keepAlive: false // 不需要緩存
            }
        }
      ]
    }
<keep-alive>
    <router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />

緩存所有頁面:

   在app.vue頁面里加keep-alive

緩存部分頁面:

  1、在app.vue頁面里加keep-alive,結(jié)合keep-alive的include屬性

  2、結(jié)合Router中的meta屬性,在app.vue頁面里加$route.meta.keepAlive的if判斷
小知識點
1、同時使用include,exclude,那么exclude優(yōu)先于include

2、緩存的組件超過了max設(shè)定的值5,那么將刪除第一個緩存的組件

3、keep-alive 不會在函數(shù)式組件中正常工作,因為它們沒有緩存實例

4、keep-alive 先匹配被包含組件的 name 字段,如果 name 不可用,則匹配當(dāng)前組件 components 配置中的注冊名稱

5、只有組件被 keep-alive 包裹時,這兩個生命周期函數(shù)才會被調(diào)用,如果作為正常組件使用,是不會被調(diào)用的,以及在 2.1.0
版本之后,包含在 keep-alive 中,但符合 exclude ,不會調(diào)用activated和
deactivated這兩個函數(shù)鉤子!另外,在服務(wù)端渲染時,此鉤子函數(shù)也不會被調(diào)用

5.3 生命周期變化

針對路由緩存組件的多加了兩個生命周期函數(shù)

1.activated

  • 在 keep-alive 組件激活時調(diào)用
  • 該鉤子函數(shù)在服務(wù)器端渲染期間不被調(diào)用
  • 使用 keep-alive會將數(shù)據(jù)保留在內(nèi)存中,如果要在每次進入頁面的時候獲取最新的數(shù)據(jù),需要在 activated 階段獲取數(shù)據(jù),承擔(dān)原來 created鉤子函數(shù)中獲取數(shù)據(jù)的任務(wù)。
activated(){
    /** 
     * 緩存的組件點擊時調(diào)用
    */
},

2.deactivated

  • 在 keep-alive 組件停用時調(diào)用
  • 該鉤子函數(shù)在服務(wù)器端渲染期間不被調(diào)用
  • 被包含在 keep-alive中創(chuàng)建的組件,會多出兩個生命周期的鉤子: activated 與 deactivated
deactivated(){
    /** 
     * 緩存的組件點擊時調(diào)用
    */
},

keep-alive的用法及詳解

總結(jié)
1、如何配置路由?

2、如何使用導(dǎo)航進行路由跳轉(zhuǎn)

聲明式:router-link
編程式:this.$ router.push,this.$ router.g等

3、嵌套(多級)路由如何配置與使用

  • 父級路由中加children,children下就是子路由
  • 子路由中的path不加/
  • 子頁面訪問路徑 /school/student

4、路由如何傳遞傳參

this.$router.push({path:‘/helloWord’,query:{id:‘01’,name:‘張二’}})

this.$router.push({name:‘helloword’,params:{id:‘01’,name:‘張二’}})
props
路徑冒號參數(shù)項:about/:id/:name

5、路由守衛(wèi)

前置守衛(wèi) routes.beforeEach((to,from,next)=>{}) ,后置守衛(wèi) routes.afterEach((to,from,next)=>{})
獨享路由守衛(wèi)
組件內(nèi)路由守衛(wèi)

6、路由緩存

keep-alive

到此這篇關(guān)于Vue中vue-router路由使用示例詳解的文章就介紹到這了,更多相關(guān)vue-router路由使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論