天天看點

vue學習筆記(十)路由

前言

在上一篇部落格vue學習筆記(九)vue-cli中的元件通信内容中,我們學習元件通信的相關内容和進行了一些元件通信的小練習,相信大家已經掌握了vue-cli中的元件通信,而本篇部落格将會帶你更上一層樓,說實話有關路由的知識我有提到過一點,使用webstorm搭建vue-cli項目這篇部落格結尾的示例就是有關路由的一點小知識,但是當時隻是做了一個小小的案例,而本篇部落格将會詳細講解vue中的路由相關知識,那麼一起來看看吧!

本章目标

  • 了解Vue Router的簡單介紹
  • 學會vue路由的傳參方式

Vue Router的介紹

Vue Router是一個Vue核心插件,是Vue.js官方的路由管理器。它和 Vue.js 的核心深度內建,讓建構單頁面應用變得易如反掌。vue的單頁面應用是基于路由群組件的,路由用于設定通路路徑,并将路徑群組件映射起來。傳統的頁面應用,是用一些超連結來實作頁面切換和跳轉的。在vue router單頁面應用中,則是路徑之間的切換,也就是元件的切換。包含的功能有:

  • 嵌套的路由/視圖表
  • 子產品化的、基于元件的路由配置
  • 路由參數、查詢、通配符
  • 基于 Vue.js 過渡系統的視圖過渡效果
  • 細粒度的導航控制
  • 帶有自動激活的 CSS class 的連結
  • HTML5 曆史模式或 hash 模式,在 IE9 中自動降級
  • 自定義的滾動條行為

參考資源

中文幫助:https://router.vuejs.org/zh/

英文幫助:https://router.vuejs.org/

Git源碼:https://github.com/vuejs/vue-router

vue router中有三個比較重要的概念,route,routes,router,接下來我們一一介紹它們。

  • route,它是一個路由,代表一個通路的位址。
  • routes 是一組路由,把route組合起來,形成一個數組。
  • router 是一個機制,相當于一個管理者,它來管理路由,舉個例子來說:假設我們點選按鈕需要查詢資料怎麼辦?這時router 就起作用了,它到routes 中去查找,去找到對應查詢資料的路由,然後将數組傳回到頁面上。
  • 用戶端中的路由,實際上就是dom 元素的顯示和隐藏。當頁面中顯示home 内容的時候,about 中的内容全部隐藏,反之也是一樣。用戶端路由有兩種實作方式:基于hash 和基于html5 history api。

接下來我們通過兩種方式來實作vue-router的使用,這兩種方式分别是網頁版的vue-router的使用和vue-cli版vue-router的使用

網頁版

直接下載下傳 / CDN

https://unpkg.com/vue-router/dist/vue-router.js      

Unpkg.com 提供了基于 NPM 的 CDN 連結。上面的連結會一直指向在 NPM 釋出的最新版本。你也可以像 https://unpkg.com/[email protected]/dist/vue-router.js 這樣指定 版本号 或者 Tag。

NPM

使用nodejs包管理器安裝

npm install vue-router      

如果在一個子產品化工程中使用它,必須要通過 Vue.use() 明确地安裝路由功能

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)      

用 Vue.js + Vue Router 建立單頁應用,是非常簡單的。使用 Vue.js ,我們已經可以通過組合元件來組成應用程式,當你要把 Vue Router 添加進來,我們需要做的是,将元件 (components) 映射到路由 (routes),然後告訴 Vue Router 在哪裡渲染它們

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>網頁版vue-router</title>
</head>
<body>
<div id="app">
    <h1>{{msg}}</h1>
    <!--使用router-link元件來導航-->
    <!--通過傳入to屬性指定連結-->
    <!--router-link元件預設渲染成a标簽-->
    <router-link to="/foo">Foo</router-link>
    <router-link to="/bar">Bar</router-link>
    <!--路由出口-->
    <!--路由比對到的元件将渲染到這裡-->
    <router-view></router-view>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<script>
  //1.定義元件
  const foo={template:'<h1>這是foo元件</h1>'}
  const bar={template: '<h1>這是bar元件</h1>'}
  //2.定義routes
  const routes=[
    {
      path:'/foo',
      component:foo,
      name:foo,
    },
    {
      path:'/bar',
      component:bar,
      name:bar
    }
  ]
  //3.定義router
  const router=new VueRouter({
    routes  //相當于routes:routes
  })
  //4.建立和挂載根執行個體
  const  vm=new Vue({
    el:'#app',  //挂載元素
    data:{
      msg:'網頁版vue-router'
    },
    router:router
  })
</script>
</body>
</html>      

結果:

vue學習筆記(十)路由
vue學習筆記(十)路由

可以看到我們已經實作的簡單的路由切換,但是這種方式我們以後的開發中極少用到,作為初學者還是有必要講解一下

步驟分析:

  • 引入js和挂載元素
  • 定義元件和定義routes管理每一個路由,一個路由可以對應一個元件,例如示例中/foo對應foo元件,/bar對應bar元件
  • 定義router,用來處理請求每一個route對應的資訊

注意:<router-view></router-view>這個标簽特别重要,如果沒有這個标簽vue-router将會失效。

vue-cli版

接下來我帶大家講解vue-cli版vue-router的使用,這也是後面開發中常用的手法

安裝:

npm install vue-router
yarn add vue-router      

這兩種方式任意選一種都可以

若在建構vue-cli的時候,在詢問“nstall vue-router”(是否安裝vue-router)時,選擇“Y”,這裡就不用重複安裝vue-router。使用WebStorm建立一個vue-cli項目,選擇使用router:

vue學習筆記(十)路由

(1)/src/components/test03建立4個元件,分别是IndexComponent.vue,HomeComponent.vue,DefaultComponent.vue,AboutComponent.vue,建立目錄結構如下:

vue學習筆記(十)路由

(2)在對應的元件寫上相應的代碼

IndexComponent.vue

<template>
    <div>
      <h1>{{msg}}</h1>
    </div>
</template>

<script>
    export default {
        name: "IndexComponent",
      data(){
          return{
            msg:'這是index元件'
          }
      }
    }
</script>

<style scoped>
  
</style>      

HomeComponent.vue

<template>
    <div>
      <h1>{{msg}}</h1>
    </div>
</template>

<script>
    export default {
        name: "HomeComponent",
      data(){
          return{
            msg:'這是home元件'
          }
      }
    }
</script>

<style scoped>
  h1{
    color: red;
  }
</style>      

AboutComponent.vue

<template>
    <div>
      <h1>{{msg}}</h1>
    </div>
</template>

<script>
    export default {
        name: "AboutComponent",
      data(){
          return{
            msg:'這是about元件'
          }
      }
    }
</script>

<style scoped>
  h1{
    color: green;
  }
</style>      

DefaultComponent.vue

<template>
    <div>
      <h1>{{msg}}</h1>
    </div>
</template>

<script>
    export default {
        name: "DefaultComponent",
      data(){
          return{
            msg:'這是default元件'
          }
      }
    }
</script>

<style scoped>
  h1{
    color: pink;
  }
</style>      

(3)自定義router并在main.js注冊

其實我們可以自定義router,自定義的router和原來的router都差不多,我們/src/router建立一個test.js并編寫對應的代碼

test.js

import Vue from 'vue'
import Router from  'vue-router'
import Index from '@/components/test03/IndexComponent'
import Home from '@/components/test03/HomeComponent'
import Default from '@/components/test03/DefaultComponent'
import About from '@/components/test03/AboutComponent'
Vue.use(Router)
export  default  new Router({
  routes:[
    {
      path:'/',
      component:Index,
      name:Index
    },
    {
      path:'/home',
      component:Home,
      name: Home
    },
    {
      path:'/about',
      component:About,
      name:About
    },
    {
      path:'/default',
      component:Default,
      name:Default
    }
  ]
})      

main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'      
// import router from './router'    //這個是最開始的路由      
import  router from './router/test'  //修改原來的路由,換成自己定義的路由
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: {},
  template: ''
})      

修改之後IndexComponent.vue

<template>
    <div>
      <h1>{{msg}}</h1>
      <router-link to="/home">Home</router-link>
      <router-link to="/about">About</router-link>
      <router-link to="/default">Default</router-link>
      <router-view></router-view>
    </div>
</template>

<script>
    export default {
        name: "IndexComponent",
      data(){
          return{
            msg:'這是index元件'
          }
      }
    }
</script>

<style scoped>

</style>      

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vue_01</title>
  </head>
  <body>
    <div id="app">
      <!--對應的元件内容渲染到router-view中-->
      <router-view></router-view>
    </div>
    <!-- built files will be auto injected -->
  </body>
</html>      

(4)測試結果

vue學習筆記(十)路由
vue學習筆記(十)路由

vue-router兩種方式的使用我已經講解完成了,寫得如此詳細,想必大家都可以看得懂。

路由模式

vue-router 預設 hash 模式 —— 使用 URL 的 hash 來模拟一個完整的 URL,于是當 URL 改變時,頁面不會重新加載

http://localhost:8080/#/home      

如果不想要很hash,可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成 URL 跳轉而無須重新加載頁面

const router = new VueRouter({
  mode: 'history',
  routes: [...]
}      

當使用 history 模式時,URL 就像正常的 url

http://localhost:8080/home

import Vue from 'vue'
import Router from  'vue-router'
import Index from '@/components/test03/IndexComponent'
import Home from '@/components/test03/HomeComponent'
import Default from '@/components/test03/DefaultComponent'
import About from '@/components/test03/AboutComponent'
Vue.use(Router)
export  default  new Router({
  mode:'history',
  routes:[
    {
      path:'/',
      component:Index,
      name:Index
    },
    {
      path:'/home',
      component:Home,
      name: Home
    },
    {
      path:'/about',
      component:About,
      name:About
    },
    {
      path:'/default',
      component:Default,
      name:Default
    }
  ]
})      
vue學習筆記(十)路由

不過這種模式需要背景配置支援。如果背景沒有正确的配置,當使用者在浏覽器直接通路 http://site.com/user/id 就會傳回 404,詳細請參考:https://router.vuejs.org/zh/guide/essentials/history-mode.html

vue路由的傳參方式

在講解vue路由傳參方式之前我們需要回顧下元件通信的相關知識,我們知道要實作參數傳遞如果依靠之前所學的知識,無非三種,父元件向子元件傳遞參數,子元件向父元件傳遞參數,非父子元件傳遞參數,而vue的路由傳參的功能就特别強大,可以向任意路由傳遞參數,接觸之前我們先來回顧一下vue中的非父子元件的通信方式吧!

(1)建立目錄用于非父子元件通信

在src/components建立test04目錄和兩個元件分别:BrotherComponent.vue,SisterComponent.vue,以及在src/assets下建立一個bus.js檔案,建立之後的目錄如下

vue學習筆記(十)路由

(2)bus.js充當總線

event.js這個檔案中我們隻建立了一個新的Vue執行個體,以後它就承擔起了元件之間通信的用來充當總線橋梁了,也就是中央事件總線,為的就是将BrotherComponent.vue和SisterComponent.vue聯系起來

bus.js

//方式一
import Vue from 'Vue'
export  default  new Vue
/*方式二
let bus=new Vue
export  default  bus
*/      

BrotherComponent.vue

<template>
    <div>
      <h1>{{msg}}</h1>
      <button @click="sendMsg()">向姐妹元件傳遞資訊</button>
      <sister></sister>
    </div>
</template>

<script>
    //導入總線
    import  bus from '../../assets/bus'
    //導入姐妹元件
    import  sister from './SisterComponent'
    export default {
        name: "BrotherComponent",
      data(){
        return{
          msg:'這是兄弟元件',
          tips:'I am your brother'
        }
      },
        components:{
          sister  //注冊姐妹元件
        },
        methods:{
          sendMsg(){
            bus.$emit('send',this.tips);
          }
        }
    }
</script>

<style scoped>

</style>      

在這個元件中首先是導入的總線和姐妹元件,然後注冊了姐妹元件,我們在響應點選事件的sendMsg函數中用$emit觸發了一個自定義的send事件,并傳遞了一個字元串參數。

這個參數就是需要傳遞個姐妹元件的值。$emit執行個體方法觸發目前執行個體(這裡的目前執行個體就是bus)上的事件,附加參數都會傳給監聽器回調

SisterComponent.vue

<template>
    <div>
      <h1>這是姐妹元件</h1>
      <h1>{{msg}}</h1>
    </div>
</template>

<script>
    //導入總線
    import  bus from '../../assets/bus'
    export default {
        name: "SisterComponent",
      data(){
          return{
            msg:'',
          }
      },
      mounted(){

      },
      methods:{
          getMsg(){
            bus.$on('send',data=>{
              this.msg=data;
            })
          }
      },
      mounted(){
          this.getMsg();
      }
    }
</script>

<style scoped>

</style>      

在這個元件中,我們在mounted中,監聽了send,并把傳遞過來的字元串參數傳遞給了$on監聽器的回調函數,mounted:是一個Vue生命周期中的鈎子函數,簡單點說就類似于jquery的ready,Vue會在文檔加載完畢後調用mounted函數,$on:監聽目前執行個體上的自定義事件(此處目前執行個體為bus)。事件可以由$emit觸發,回調函數會接收所有傳入事件觸發函數($emit)的額外參數

(3)建立router

在src/router目錄下建立common.js路由并寫上對應的代碼

common.js

import  Vue from 'vue'
import Router from 'vue-router'
import Brother from '@/components/test04/BrotherComponent'
import sister from '@/components/test04/SisterComponent'
Vue.use(Router)
export  default new Router({
    routes:[
      {
        path:'/',
        name:Brother,
        component:Brother
      },
      {
        path:'/sister',
        name:sister,
        component:sister,
      }
    ],

})      

(4)main.js注冊新增的common路由

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
// import router from './router'
// import router from './router/hello'
// import  router from './router/test'
import  router from './router/common'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: {},
  template: ''
})      
vue學習筆記(十)路由

總結:

  • 建立一個事件總線,例如示例中event.js,用它作為通信橋梁
  • 在需要傳值的元件中用bus.$emit觸發一個自定義事件,并傳遞參數
  • 在需要接收資料的元件中用bus.$on監聽自定義事件,并在回調函數中處理傳遞過來的參數

非父子元件通信我們回顧了一遍之後就進入正式換節了,我會講解一些常用的方法

vue-router的params參數傳遞

文法:

  • 發送參數的元件,this.$router.push({name:'路由的名稱',params:{key1:value1,key2:value2,....}})
  • 接收參數的元件,this.$route.params.參數名稱

注意:接收參數的時候使用的是this.$route而不是this.$router

示例

(1)建立目錄群組件

在src/components建立test05目錄和OneComponent.vue和TwoComponent.vue兩個元件,建立目錄群組件之後的結構如下

vue學習筆記(十)路由

(2)元件編寫對應的代碼

OneComponent.vue

<template>
    <div>
      <button @click="sendMsg()">發送消息</button>
    </div>
</template>

<script>
    export default {
        name: "OneComponent",
      data(){
          return{
            code:'我是通過params傳過來的'
          }
      },
      methods:{
          sendMsg(){
            this.$router.push({
              name:'two', // 路由的名稱,在定義route的時候可以自己定義
              params:{
                code:this.code
              }
            });
          }
      }
    }
</script>

<style scoped>

</style>      

TwoComponent,vue

<template>
    <div>
      <h1>{{msg}}</h1>
      <h2>{{this.$route.params.code}}</h2>
    </div>
</template>

<script>
    export default {
        name: "TwoComponent",
        data(){
            return{
              msg:''
            }
        },
        mounted(){
          this.msg=this.$route.params.code;
        }
    }
</script>

<style scoped>

</style>      

(3)建立router并在main注冊

在src/router目錄建立one.js路由并在main.js注冊

one.js

import  Vue from 'vue'
import Router from 'vue-router'
import one from '@/components/test05/OneComponent'
import two from '@/components/test05/TwoComponent'
Vue.use(Router)
export  default  new Router({
  routes:[
    {
      path:'/',
      name:one,
      component:one
    },
    {
      path:"/two",
      name:'two', //路由的名稱,一定需要加單引号或者雙引号,否則找不到
      component:two
    }
  ]
})      
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
// import router from './router'
// import router from './router/hello'
// import  router from './router/test'
// import  router from './router/common'
import router from './router/one'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: {},
  template: ''
})      

(4)測試

vue學習筆記(十)路由

vue-router的query參數傳遞

  • 發送參數的元件:this.$router.push({path:'路由的路徑',query:{key1:value1,key2:value2}})
  • 接收參數的元件:this.$route.query.參數名稱

在src/components建立test06目錄和ThreeComponent.vue和FourComponent.vue兩個元件,建立目錄群組件之後的結構如下

vue學習筆記(十)路由

ThreeComponent.vue

<template>
    <div>
      <button @click="sendMsg()">query傳遞參數</button>
    </div>
</template>

<script>
    export default {
        name: "ThreeComponent",
      data(){
          return{
            msg:'我是通過quey傳遞參數過來的'
          }
      },
      methods:{
        sendMsg(){
          this.$router.push({
            path:'Four',
            query:{
              msg:this.msg
            }
          })
        }
      }
    }
</script>

<style scoped>

</style>      

FourComponent.vue

<template>
      <div>
        <h1>{{msg}}</h1>
      </div>
</template>

<script>
    export default {
        name: "FourComponent",
      data(){
          return{
            msg:'',
          }
      },
      mounted(){
          this.msg=this.$route.query.msg;
      }
    }
</script>

<style scoped>

</style>      

在src/router目錄下建立two.js并在main.js注冊

two.js

import Vue from 'vue'
import Router from 'vue-router'
import Three from '@/components/test06/ThreeComponent'
import Four from '@/components/test06/FourComponent'
Vue.use(Router)
export  default  new Router({
  routes:[
    {
      path:'/',
      name:'Three', //name需要添加單引号或者雙引号,否則找不到
      component:Three
    },
    {
      path:'/four',
      name:'Four',//name需要添加單引号或者雙引号,否則找不到
      component:Four
    }
  ]
})      
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
// import router from './router'
// import router from './router/hello'
// import  router from './router/test'
// import  router from './router/common'
// import router from './router/one'
import router from './router/two'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: {},
  template: ''
})      

(4)測試 

vue學習筆記(十)路由

params和query的差別

  • params傳遞參數之後重新整理界面,參數取值undefined
  • query傳遞參數之後重新整理界面,參數仍然保留
  • params傳遞參數隻能使用name,不能使用path
  • query傳遞參數既可以使用path,也可以使用name
  • params傳遞參數不會再位址欄顯示,類似于post請求
  • query傳遞參數會在位址欄顯示,類似于get請求
  • params取值使用this.$route.params.參數名稱
  • query取值使用this.$route.query.參數名稱

總結

作者:一隻流浪的kk

出處:https://www.cnblogs.com/jjgw/

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留原文連結,否則将追究法律責任

vue學習筆記(十)路由

微信掃一掃

關注公衆号

繼續閱讀