前言:
最近我跟同事在作一個BI系統,採用先後端分離。整個系統包括數據分析系統、運營支持、系統設置等多個子系統。數據分析系統其實就是作各類數據報表、數據統計、實時數據的系統,這裏面其實整個頁面就是一個模板,最上面是filter、第二級是統計圖、最下面是table數據。因此在數據分析子系統中,只要配置一個路由就能夠匹配全部頁面,在系統中,我把這個爲公用路由。至於公用路由權限如何鑑定其實很簡單:獲取到用戶權限列表後,渲染出全部的權限菜單,但注意每次跳轉時必定要進行權限校驗,具體緣由自行思考。說着有點跑偏了,那麼這個公用路由怎麼能夠匹配多個業務視圖呢?(一個路由對應多個業務視圖)html
很天然咱們就會想經過路由傳遞參數,但進入到公用數據分析路由中時,組件能夠獲取路由信息,根據路由信息咱們去獲取filter\獲取圖表\獲取table數據\當前視圖名稱,從而渲染出不一樣的數據分析報表、統計。vue
備註:爲了減低複雜度,我這裏經過傳遞一個參數(數據請求接口)獲取上面的全部數據,也就是經過一個接口把整個頁面的數據都獲取到,數據結構大體以下:vue-router
{ viewname: '留存數據', filters: [ { ... // 具體filter類型及數據 } ], echarts:[ { .... // options } ], tables:[ { ... // 表格數據,表頭\數據等 } ] }
那麼這個時候咱們就很清楚咱們的業務需求是什麼了。接下來咱們看下咱們隊這個數據分析公用路由的配置,以下:編程
// 路由配置 { path: '', component: Layout, children: [{ path: '/data/config/:block/:page', component: () => import('@/views/data/common'), name: 'common', meta: { title: 'common', icon: 'common', noCache: true } }] } ''' path:中統一規範data/config/:block/:page 全部的參數進入到common組件中,在組件中獲取到block\page參數, 而後做爲一個api,這個api就是獲取當前頁面數據的接口。 '''
分析:
那麼這是一種vue中經過路由傳遞參數的方式,那麼咱們vue中路由參數傳遞都有哪些方式呢?這就是我這篇文章詳細說明的主題。這個前言有點臭長了,sorry!咱們立刻進入正文。後端
咱們能夠先看下官方的文檔:路由組件傳參,這裏面講述了路由組件傳參的全部方式,分別爲:布爾模式、對象模式、函數模式。光看名字仍是不能明白,咱們接下來結合案例代碼一個一個解釋一下。api
在講各類模式傳參以前,咱們先了解一下路由是如何進行跳轉和傳遞過來的參數是如何在組件中接收的,爲何要先說這些?由於這有利於理解設計者爲啥要作這些模式的設計。咱們用過的都知道,組件中:經過this.$router.push進行編程式路由跳轉、router-link中的to屬性進行路由切換。經過this.$route.params/this.$route.query獲取路由傳遞的參數。特別要留意this.$router和this.$route的區別,你能夠把這兩個對象打印出來看,或者自行查閱官方說明。數據結構
總結:
1.this,$router.push進行編程式路由跳轉
2.router-link進行頁面按鈕式路由跳轉
3.this.$route.params獲取路由傳遞參數
4.this.$route.query獲取路由傳遞參數
5.params和query都是傳遞參數區別在於params不會再url上顯示出現,
而且params參數是路由的一部分,是必定要存在的,不然沒法顯示視圖。
query則是咱們一般看到的url後面跟上的?後跟的顯示參數echarts
案例代碼:前後端分離
<template> <div class="hello"> <label>Hello</label> <button type="button" @click="gotoD()"> 查看詳細信息1 </button> <router-link :to="{path:'/Detail/ckmike', params:{name:'Lily'},query:{sex:'女'},props:{age:18}}" > 查看詳細信息2 </router-link> </div> </template> <script> export default { name: 'HelloWorld', data () { return { } }, methods: { gotoD () { this.$router.push({path: '/Detail/ckmike', query: {sex: '男'}}) } } } </script> // 路由配置 import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' import Detail from '@/components/Detail' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld }, { path: '/Detail/:name', name: 'Detail', component: Detail, props: { age: 21 } } ] })
若是 props 被設置爲 true,route.params 將會被設置爲組件屬性。ide
const User = { props: ['id'], template: '<div>User {{ id }}</div>' } const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, props: true }, // 對於包含命名視圖的路由,你必須分別爲每一個命名視圖添加 `props` 選項: { path: '/user/:id', components: { default: User, sidebar: Sidebar }, props: { default: true, sidebar: false } } ] })
若是 props 是一個對象,它會被按原樣設置爲組件屬性。當 props 是靜態的時候有用。
const router = new VueRouter({ routes: [ { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } } ] })
你能夠建立一個函數返回 props。這樣你即可以將參數轉換成另外一種類型,將靜態值與基於路由的值結合等等。
const router = new VueRouter({ routes: [ { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) } ] })
上面是官方給出的說明文檔,更多詳細可進入官方文檔。
接下來咱們來測試一下params和query有啥區別:
<template> <div class="hello"> <label>Hello</label> <button type="button" @click="gotoD()"> 查看詳細信息1 </button> <router-link :to="{path:'/Detail', params:{name:'Lily', age: 18},query:{sex:'女'}, props: true}" > 查看詳細信息2 </router-link> </div> </template> <script> export default { name: 'HelloWorld', data () { return { } }, methods: { gotoD () { this.$router.push({path: '/Detail', query: {sex: '男'}, params: {name: 'ckmike', age: 21}, props: true}) } } } </script> // 路由配置 import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' import Detail from '@/components/Detail' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld }, { path: '/Detail', name: 'Detail', component: Detail, props: true } ] }) // 信息頁面 <template> <div class="detail"> <label>詳細信息:</label> <br> <label>姓名:{{name}}</label> <br> <label>性別:{{sex}}</label> <br> <label>年齡:{{age}}</label> </div> </template> <script> export default { name: 'Detail', data () { return { } }, computed: { name () { return this.$route.params.name }, sex () { return this.$route.query.sex }, age () { return this.$route.params.age } } } </script>
說明:使用path進行跳轉時,params是不會被做爲route屬性傳遞給組件的。只有query屬性會被放入組件屬性中。
咱們把path換成name來再看:
說明:使用name進行跳轉時,params生效,被傳遞給組件,頁面顯示出信息,可是這個params的信息一旦屬性頁面就會丟失。query不會
params參數相似於post方式,而query則相似於get方式,一旦路由的props設置爲true時,那麼組件中刻意經過props拿到參數,這個就是布爾模式。
若是給props傳遞一個對象,那麼在組件中刻意獲取到路由中props的參數,通常用於靜態參數,這個無論你在router-link或者router.push改變對應參數值,你獲取時都是路由配置中的值。
總結:1.params傳遞參數,須要使用name進行路由跳轉,不然沒法傳遞。2.params傳遞參數刷新會丟失數據,/router/:id方式上的id除外3.query顯示拼接在url上,刷新不丟失,不是必須有,router/:id方式則必須有id參數,不然沒法正確進入視圖。4.props也能夠傳遞參數,但傳遞的只能是靜態參數。