VueRouter
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
对应的如果说要使用VueRouter的话,对应的需要注册在main里面,因为对应的Router基本上都是通过配置文件 router.js进行配置的,对应的 因此是通过 router.js 配置好,将VueRouter模块中引进去之后, 配置路由表,导出 对应的从main.js 项目入口文件中引入router.js 并且通过 新建Vue实例对象的时候 传入到参数列表中!
对应的API:
<!-- 使用router-link组件来导航 to 表示指定的链接 -->
<router-link to="/foo">Go to Foo</router-link>
<!-- 通过JS定义对应的路由表(路由映射到)对应的组件 -->
<script>
const foo = {template:'<div>Foo</div>'}
const routes = [{path:'/foo',component:foo}]
const router = new VueRouter({routes})
const app = new Vue({router}).$mount('#app');
/* 路由器的注入 全局都能够通过this.$router访问路由器! 也可以通过this.$route访问当前的路由! */
</script>
动态路由匹配:
通过动态路径参数进行匹配! 并且是通过冒号开头的!
const router = new VueRouter(routes:[
{path:'/user/:id',component:User}
])
/*
user/xxx ===> User 当匹配到一个路由的时候,参数值就会被设置到 this.$route.params
*/
模式 | 匹配路径 | $route.params |
---|---|---|
/user/:username | /user/evan | {username:'evan'} |
/user/:username/post/:post_id | /user/evan/post/123 | {username:'evan',post_id:'123'} |
如果说使用对应的 路由参数 的时候,例如从 /user/foo
导航到 /user/bar
的话,那么对应的会 匹配到同一个组件 ,对应的原来的 组件实例会被复用 ,对应的 生命周期(钩子)函数 不会被调用,如果相对路由参数的变化作出相应的话可以使用 watch(监测变化) $route
对象
const user = {template:'xxxx',watch:{
'$route'(to,from){/*对路由的变化做出相应!*/}
}}
当然也可以使用 路由守卫:
const user = {template:'xxxx',beforeRouteUpdate(to,from,next){
//TODO
}}
常规的参数只会匹配被 /
分隔的URL片段中的字符,如果相匹配 任意路径 我么可以使用 通配符 *** **
这个得结合使用!
如果说使用了对应的 通配符 的时候, $route.params内会自动添加一个 pathMatch 参数!
/*给出对应的路由 {path:/user-*}*/
this.$router.push('/user-admin');
this.$route.params.pathMatch; //admin
/*给出对应的路由 {path:/*}*/
this.$router.push('/user-admin');
this.$route.params.pathMatch; //user-admin
匹配优先级
- 谁先定义 谁的优先级就高!
嵌套路由
URL中隔断动态路径也按照某种结构对应嵌套的各种组件:
借助 vue-router ,使用嵌套路由配置,可以很简单的表达这种关系!
<router-view> 是最顶层的出口,渲染UI高纪录有匹配到的组件!
const router = new VueRouter({
routes:[
{path:'/user/:id',component:User,
children:[
/* /user/:id/profile 匹配成功后 UserProfile会被渲染在<router-view> 中! */
path:'profile',component:UserProfile
]
}
]
})
编程式导航
除了 <router-link> 创建a标签来定义导航链接,我们可以借助对应的router的实例方法,通过编写代码来实现!
router.push(location,onComplete?,onAbort?)
对应的在 **Vue实例内部可以通过 router.push **
想要导航到不同的URL,则使用router.push
方法,这个方法会想history栈 添加一个新的记录!
因此点击 <router-link>
方法会在内部调用,等同于调用 router.push()
声明式 | 编程式 |
---|---|
<router-link :to=''> | router.push(...) |
router.push({path:'register',query:{plan:'private'}}); // /register?plan=private
const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
如果对应的路有相同,只是对应的参数发生了变化的话,对应的需要使用 beforeRouteUpdate
响应该变化!
router.replace(location, onComplete?, onAbort?)
该方法和对应的push方法很像,但是不会向history添加新的纪录,而是跟他的方法一样,替换掉当前的history记录!
声明式 | 编程式 |
---|---|
<router-link :to=' ' replace> | router.replace(....); |
router.go(n)
在history记录中向前或者说向后退多少步! 类似于: window.history.go(n);
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
//如果说对应的history记录不够用,那就默默地失败!
router.go(100);
命名路由:
import User from './components/views/User'
const router = new VueRounter({
routes:[
path:'/user/:userId',name:'user',component:User
]
})
如果说要连接到对应的命名的路有的话,可以这么做:
<router-link :to="{name:'user',params:{userId:123}}"></router-link>
如果说使用编程式导航的话是这样的:
router.push({name:'user',params:{userId:123}});
命名视图
如果说想同时(同级)展示多个视图,而不是嵌套展示,例如创建一个布局, 有多个视图,对应的视图组件就派上用途了,如果说 router-view
没有对应的名字,那么久设置为 default
<router-view class='view one'></router-view>
<router-view class='view two' name='a'></router-view>
<router-view class='view three' name='b'></router-view>
const router = new VueRouter({
routes:[
path:'/',components:{
default:Foo,
a:Bar,
b:Baz
}
]
})
重定向和别名
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' }
]
})
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
})
const router = new VueRouter({
routes: [
{ path: '/a', redirect: to => {
// 方法接收 目标路由 作为参数
// return 重定向的 字符串路径/路径对象
}}
]
})
路由组件传参
在组件中使用$route
会使之与其对应路由形成高度耦合,从而组件只能够在某些特定的URL上使用,限制了其灵活性!
可以使用props将组件和路由解耦
const User = {
template: '<div>User {{ $route.params.id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
使用props解耦
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
被设置为true
,route.params
将会被设置为组件属性
对象模式
如果对应的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 }) }
]
})
URL /search?q=vue
会将 {query: 'vue'}
作为属性传递给 SearchUser
组件。
请尽可能保持 props
函数为无状态的,因为它只会在路由发生变化时起作用。如果你需要状态来定义 props
,请使用包装组件,这样 Vue 才可以对状态变化做出反应。
后续内容待补充...
网友评论