前言:
最近我跟同事在作一个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也能够传递参数,但传递的只能是静态参数。