1. 程式人生 > >Vue路由傳遞參數詳細說明

Vue路由傳遞參數詳細說明

bar 則無 頁面 方式 編程 ide arch 信息 fig

前言
最近我跟同事在做一個BI系統,采用前後端分離。整個系統包括數據分析系統、運營支持、系統設置等多個子系統。數據分析系統其實就是做各種數據報表、數據統計、實時數據的系統,這裏面其實整個頁面就是一個模板,最上面是filter、第二級是統計圖、最下面是table數據。所以在數據分析子系統中,只要配置一個路由就可以匹配所有頁面,在系統中,我把這個為公用路由。至於公用路由權限如何鑒定其實很簡單:獲取到用戶權限列表後,渲染出所有的權限菜單,但註意每次跳轉時一定要進行權限校驗,具體原因自行思考。說著有點跑偏了,那麽這個公用路由怎麽可以匹配多個業務視圖呢?(一個路由對應多個業務視圖)

很自然我們就會想通過路由傳遞參數,但進入到公用數據分析路由中時,組件可以獲取路由信息,根據路由信息我們去獲取filter\獲取圖表\獲取table數據\當前視圖名稱,從而渲染出不同的數據分析報表、統計。

備註:為了減低復雜度,我這裏通過傳遞一個參數(數據請求接口)獲取上面的所有數據,也就是通過一個接口把整個頁面的數據都獲取到,數據結構大致如下:

{
    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!我們馬上進入正文。

Vue路由傳參

我們可以先看下官方的文檔:路由組件傳參,這裏面講述了路由組件傳參的所有方式,分別為:布爾模式、對象模式、函數模式。光看名字還是不能明白,我們接下來結合案例代碼一個一個解釋一下。

在講各種模式傳參之前,我們先了解一下路由是如何進行跳轉和傳遞過來的參數是如何在組件中接收的,為什麽要先說這些?因為這有利於理解設計者為啥要做這些模式的設計。我們用過的都知道,組件中:通過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後面跟上的?後跟的顯示參數

案例代碼:

<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 將會被設置為組件屬性。

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也可以傳遞參數,但傳遞的只能是靜態參數。

Vue路由傳遞參數詳細說明