VUE三 vue-router(路由)详解
前端路由
根据不同的 url 地址展示不同的内容或页面,无需依赖服务器根据不同URL进行页面展示操作
优点
- 用户体验好,不需要每次都从服务器全部获取,快速展现给用户
缺点
- 使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存
- 单页面无法记住之前滚动的位置,无法在前进,后退的时候记住滚动的位置
一、路由(以user为例)
userList-->用户列表页的路由所加载的代码(router-->index.js)
import Vue from 'vue' //引入vue
import Router from 'vue-router' //引入vue-router
import userList from '@/components/userList' //引入根目录下的user.vue组件
Vue.use(Router) //vue全局使用Router
export default new Router({
routes: [ //配置路由,这里是个数组
{
path: '/userList', //链接路径
name: 'userList', //路由名称
component: userList //对应的组件模板
}
]
})
userList-->用户列表页代码(userList.vue)
<template> <div>展示用户列表页</div> </template> <script> export default { name: 'userList', data () { return { msg: '' } } } </script> <style scoped> </style>
打开网址:http://localhost:8080/#/userList 显示如上模板解析页。
注意:其中 # 为哈希,mode:hash 若要用原始类型的网址,则mode:history。
二、动态路由匹配
模式 | 匹配路径 | 获取动态路由参数 |
/user/:username | /user/nina | $route.params.username |
/user?:username | /user?username=nina | $route.query.username |
还是以userList为例
创建一个 userList 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。所以,我们需要在 vue-router 的路由路径中使用『动态路径参数』来达到这个效果。
userList-->用户列表页的路由所加载的代码(router-->index.js)
import Vue from 'vue' import Router from 'vue-router' import userList from '@/components/userList' Vue.use(Router) export default new Router({ routes: [ { path: '/userList/:userId', //动态设置路由参数 name: 'userList', component: userList } ] })
user-->用户列表页代码(userList.vue)
<template> <div> <div>展示用户列表页</div> <div>用户ID</div> <span>{{$route.params.userId}}</span> //获取用户userId </div> </template> <script> export default { name: 'userList', data () { return { msg: '' } } } </script> <style scoped> </style>
打开网址:http://localhost:8080/#/userList/0006 可以看到用userList组件渲染出来的userId显示在页面上。
三、嵌套路由
选项卡,在选项卡中,顶部有数个导航栏,中间显示的是主体内容,这个时候,整个页面是一个路由,然后点击选项卡切换不同的路由来展示不同的内容,这个时候就是路由中嵌套路由。
用户信息列表页,在用户信息列表中,会有用户的基本信息页,用户的密码修改页等也需要路由的嵌套
以userList列表页为例
userList-->用户列表页的路由所加载的代码(router-->index.js)
import Vue from 'vue' import Router from 'vue-router' import userList from '@/components/userList' import userInfo from '@/components/userInfo' import changePaw from '@/components/changePaw' Vue.use(Router) export default new Router({ routes: [ { path: '/userList', name: 'userList', component: userList, children:[ { path:'userInfo', name:'userInfo', component:userInfo }, { path:'changePaw', name:'changePaw', component:changePaw } ] } ] })
useruserList-->用户列表页代码(userList.vue)
<template> <div> <div>展示用户列表页</div> <router-link to="/userList/userInfo">用户基本信息页</router-link> //to后必须用绝对地址 <router-link to="/userList/changePaw">修改密码页</router-link> <div> <router-view></router-view> </div> </div> </template> <script> export default { name: 'userList', data () { return { msg: '' } } } </script> <style scoped> </style>
两个子页面-->用户基本信息页(userInfo.vue)
<template> <div> <div>用户基本信息页</div> </div> </template> <script> export default { name: 'userInfo', data () { return { msg: '' } } } </script> <style scoped> </style>
两个子页面-->用户修改密码页(changePaw.vue)
<template> <div> <div>用户修改密码页</div> </div> </template> <script> export default { name: 'changePaw', data () { return { msg: '' } } } </script> <style scoped> </style>
打开网址:http://localhost:8080/#/userList 可以看到用userList组件渲染出来页面上,有两个导航(用户基本信息页、用户修改密码页)可以来回切换
四、编程式路由
通过js来实现页面的跳转
- $router.push("name")
- $router.push({path:"name"})
- $router.push({path:"name?a=123"})或者$router.push({path:"name",query:{a:123}})
- $router.go(1)
(1)先用常用的<router-link>为例
以userList列表页为例,添加跳转到产品中心的链接。
userList-->用户列表页的路由所加载的代码(router-->index.js)
import Vue from 'vue' import Router from 'vue-router' import userList from '@/components/userList' import productCenter from '@/components/productCenter' Vue.use(Router) export default new Router({ routes: [ { path: '/userList', name: 'userList', component: userList, }, { path:'/productCenter', name:'productCenter', component:productCenter } ] })
useruserList-->用户列表页代码(userList.vue)
<template> <div> <div>展示用户列表页</div> <router-link to="/productCenter">产品中心页</router-link> </div> </template> <script> export default { name: 'userList', data () { return { msg: '' } } } </script> <style scoped> </style>
产品中心页(productCenter.vue)
<template> <div> <div>产品列表页</div> </div> </template> <script> export default { name: 'productCenter', data () { return { msg: '' } } } </script> <style scoped> </style>
打开网址:http://localhost:8080/#/userList 可以看到用userList组件渲染出来页面上,有个跳转导航(产品中心页),点击可以跳转到产品中心页。
(2)$router.push("name") ==》其中如例一中,只改变userList.vue中的跳转方式
<template> <div> <div>展示用户列表页</div> <button @click="jump">产品中心页</button> //添加跳转事件 </div> </template> <script> export default { name: 'userList', data () { return { msg: '' } }, methods:{ jump(){ this.$router.push('/productCenter') //应用js跳转事件进行跳转 } } } </script> <style scoped> </style>
(2)$router.push({path:"name"}) ==》其中如例一中,只改变userList.vue中的跳转方式
<template> <div> <div>展示用户列表页</div> <button @click="jump">产品中心页</button> </div> </template> <script> export default { name: 'userList', data () { return { msg: '' } }, methods:{ jump(){ this.$router.push({path:'/productCenter'}) } } } </script> <style scoped> </style>
(3)$router.push({path:"name?a=123"})或者$router.push({path:"name",query:{a:123}})
==》其中如例一中,只改变userList.vue中的跳转方式,并在产品中心页(productCenter.vue)接收参数用query接收
userList.vue
<template> <div> <div>展示用户列表页</div> <button @click="jump">产品中心页</button> </div> </template> <script> export default { name: 'userList', data () { return { msg: '' } }, methods:{ jump(){ this.$router.push({path:'/productCenter?userId=0001'}) } } } </script> <style scoped> </style>
productCenter.vue-->接收传过来的参数
<template> <div> <div>产品列表页</div> <div>接收参数 <span>{{$route.query.userId}}</span> //接收页面切换过来的参数 </div> </div> </template> <script> export default { name: 'productCenter', data () { return { msg: '' } } } </script> <style scoped> </style>
注意组件与组件之前路由切换的时候传递用params
页面之间的切换(比如?拼接的方式)传递用jquery
五、命名路由和命名视图
- 给路由定义不同的名字,根据路由的名字进行匹配
- 给不同的router-view定义名字,通过名字进行对应组件的渲染
(1)命名路由
以userList列表页为例,添加跳转到产品中心的链接。
userList-->用户列表页的路由所加载的代码(router-->index.js)
import Vue from 'vue' import Router from 'vue-router' import userList from '@/components/userList' import productCenter from '@/components/productCenter' Vue.use(Router) export default new Router({ routes: [ { path: '/userList', name: 'userList', component: userList, }, { path:'/productCenter', name:'productCenter', //定义路由的名字 component:productCenter } ] })
useruserList-->用户列表页代码(userList.vue)
<template> <div> <div>展示用户列表页</div> <router-link v-bind:to="{name:'productCenter'}">产品中心页</router-link> //跳转到与路由名字相同的路由地址 </div> </template> <script> export default { name: 'userList', data () { return { msg: '' } } } </script> <style scoped> </style>
产品中心页(productCenter.vue)
<template>
<div>
<div>产品列表页</div>
</div>
</template>
<script>
export default {
name: 'productCenter',
data () {
return {
msg: ''
}
}
}
</script>
<style scoped>
</style>
(2)跳转到产品中心的路由为动态路由
userList-->用户列表页的路由所加载的代码(router-->index.js)
import Vue from 'vue' import Router from 'vue-router' import userList from '@/components/userList' import productCenter from '@/components/productCenter' Vue.use(Router) export default new Router({ routes: [ { path: '/userList', name: 'userList', component: userList, }, { path:'/productCenter/:userId', //为动态路由 name:'productCenter', component:productCenter } ] })
useruserList-->用户列表页代码(userList.vue)
<template>
<div>
<div>展示用户列表页</div>
<router-link v-bind:to="{name:'productCenter',params:{userId:0001}}">产品中心页</router-link> //跳转到与路由名字相同的路由地址,params是路由的参数,不是页面跳转参数
</div>
</template>
<script>
export default {
name: 'userList',
data () {
return {
msg: ''
}
}
}
</script>
<style scoped>
</style>
(2)命名视图
路由所加载的代码(router-->index.js)
import Vue from 'vue' import Router from 'vue-router' import userList from '@/components/userList' import userInfo from '@/components/userInfo' import changePaw from '@/components/changePaw' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'userList', components: { default:userList, userInfo:userInfo, changePaw:changePaw } } ] })
App.vue-->再浏览器输入根网址后,页面会展示出路由所加载的所有页面信息。
<template> <div id="app"> <span>ddddddddddddddddddd</span> <router-view class="main"></router-view> <router-view class="left" name="userInfo"></router-view> <router-view class="right" name="changePaw"></router-view> </div> </template> <script> export default { name: 'App' } </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; } </style>
路由中的meta
meta字段(元数据)
直接在路由配置的时候,给每个路由添加一个自定义的meta对象,在meta对象中可以设置一些状态,来进行一些操作。用它来做登录校验再合适不过了
{
path: '/actile',
name: 'Actile',
component: Actile,
meta: {
login_require: false
},
},
{
path: '/goodslist',
name: 'goodslist',
component: Goodslist,
meta: {
login_require: true
},
children:[
{
path: 'online',
component: GoodslistOnline
}
]
}
这里我们只需要判断item下面的meta对象中的login_require是不是true,就可以做一些限制了
router.beforeEach((to, from, next) => {
if (to.matched.some(function (item) {
return item.meta.login_require
})) {
next('/login')
} else
next()
})
vue-router中元信息meta的妙用
{ path:"/test", name:"test", component:()=>import("@/components/test"), meta:{ title:"测试页面", //配置title keepAlive: true //是否缓存 } }
1、配置此路由的标题title
//main.js中的代码
router.beforeEach((to,from,next)=>{ if(to.meta.title){ document.title=to.meta.title } next() })
2、配置组件是否需要缓存
<!-- app.vue中的代码 --> <!-- 需要被缓存的路由入口 --> <keep-alive> <router-view v-if="$route.meta.keepAlive"></router-view> </keep-alive> <!-- 不需要被缓存的路由入口 --> <router-view v-if="!$route.meta.keepAlive"></router-view>
vue中router与route区别
vue-router中经常会操作的两个对象route和router两个。
1、$route对象
$route对象表示当前的路由信息,包含了当前 URL 解析得到的信息。包含当前的路径,参数,query对象等。
![](http://upload-images.jianshu.io/upload_images/16956101-6d61bde58509f66f.png?imageMogr2/auto-orient/strip|imageView2/2/w/768/format/webp)
1. $route.path 字符串,对应当前路由的路径,总是解析为绝对路径,如"/foo/bar"。
2. $route.params 一个 key/value 对象,包含了 动态片段 和 全匹配片段, 如果没有路由参数,就是一个空对象。
3. $route.query 一个 key/value 对象,表示 URL 查询参数。 例如,对于路径 /foo?user=1,则有$route.query.user == 1, 如果没有查询参数,则是个空对象。
4. $route.hash 当前路由的hash值 (不带#) ,如果没有 hash 值,则为空字符串。锚点*
5. $route.fullPath 完成解析后的 URL,包含查询参数和hash的完整路径。
6. $route.matched 数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
7. $route.name 当前路径名字
8. $route.meta 路由元信息
导航钩子的参数:
router.beforeEach((to,from, next)=>{//to 和from都是 路由信息对象,后面使用路由的钩子函数就容易理解了})
2、$router对象
$router对象是全局路由的实例,是router构造方法的实例。
![](http://upload-images.jianshu.io/upload_images/16956101-14123ec9cab312b2.png?imageMogr2/auto-orient/strip|imageView2/2/w/736/format/webp)
路由实例方法:
1、push
1.字符串this.$router.push('home')
2. 对象this.$router.push({path:'home'})
3. 命名的路由this.$router.push({name:'user',params:{userId:123}})
4.带查询参数,变成 /register?plan=123this.$router.push({path:'register',query:{plan:'123'}})
push方法其实和<router-link :to="...">是等同的。
注意:push方法的跳转会向 history 栈添加一个新的记录,当我们点击浏览器的返回按钮时可以看到之前的页面。
2、go
页面路由跳转
前进或者后退this.$router.go(-1) // 后退
3、replace
push方法会向 history 栈添加一个新的记录,而replace方法是替换当前的页面,
不会向 history 栈添加一个新的记录
4.一般使用replace来做404页面
this.$router.replace('/')
配置路由时path有时候会加 '/' 有时候不加,以'/'开头的会被当作根路径,就不会一直嵌套之前的路径。
$router对象是全局路由的实例,是router构造方法的实例。