Vue Router是Vue.js官方的路由管理器,严格来说,它是一款插件,但它又和Vue.js核心深度集成,Vue Router的版本依赖于Vue.js的版本,最新的vue-router 3.0 依赖于Vue.js 2.0及以上版本。
一 安装Vue-router
1,简介
Vue Router 有两种模式,分别是HTML5 History模式和hash模式。我们知道,Vue.js是主要用于构建单页面应用用户界面的渐进式框架,所以hash是Vue推荐的主力模式,如果你要使用History模式,需要配合后端进行一些单独的设置。
Vue Router 提供的主要功能包括但不限于:
嵌套路由和视图;
基于模块化、组件化的路由配置;
路由参数、查询;
简单过渡效果。
2,安装
安装Vue Router也很简单,三种方式:script标签本地引入,CDN加速,模块化开发npm安装。
1 //标签本地引入
2 <script src="/vue.js"></script>
3 <script src="/vue-router.js"></script>
4 //vue-router依赖于vue.js,序偶一要先引入vue.js
1 //CDN加速
2 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
3 <script src='https://unpkg.com/vue-router/dist/vue-router.js'></script>
4 //同样需要先引入vue.js
1 //shell npm安装
2 npm install vue-router -d
3 //根据需要选择安装方式
如果在模块化工程中使用它,必须要通过 Vue.use()
明确地安装路由功能:
1 import Vue from 'vue.js'
2 import VueRouter from 'vue-router.js'
3
4 Vue.use('vueRouter')
5 //手动安装路由功能
vue-router安装完成后,会在window上注册一个VueRouter属性,它是一个构造函数,稍后我们需要用它创建一个路由对象,并挂载到vue实例上。
二 路由规则
1,基本模式
使用Vue Router只需要简单的四步:
a:定义路由组件;
1 const Foo = { template: '<div>foo</div>' }
2 const Bar = { template: '<div>bar</div>' }
3 //路由只需要模板对象,并不需要把该模板对象注册成真实的Vue组件,这一点需要特别注意
b:定义路由规则;
1 const routes = [
2 {
3 path: '/foo',
4 component: Foo
5 },
6 {
7 path: '/bar',
8 component: Bar
9 }
10 ]
11 //路由规则是一个对象数组,每一个对象构建一条完整的路由规则,其中path和component是规则的必要属性,他们规定:在path指定的路径渲染component指定的组件。
c:创建路由实例;
1 const router = new VueRouter({
2 routes //ES6语法,相当于routes:routes
3 });
4 //为了能让路由最终运行起来,需要先创建一个router实例,稍后我们将选择合适的时机把它挂在到vue根实例上
d:把路由实例挂载到vue根实例。
1 //方式一
2 const vm = new Vue({
3 el:'#app',
4 router
5 });
6 //方式二
7 const vm = new Vue({
8 router
9 }).$mount('#app');
在JavaScript中设置好后还不够,为了在页面上有所表现,还需要在HTML页面中指定路径导航和组件渲染出口。
1 <div id="app">
2 <p>
3 <router-link to="/foo" tag="button">Foo</router-link>
4 <router-link to="/bar">Bar</router-link>
5 </p>
6 <div>
7 <router-view></douter-view>
8 </div>
9 </div>
10 <!-- 使用<router-link>标签来导航,它默认将被渲染为<a>标签,你可以通过tag属性来改变这一默认行为 -->
11 <!-- <router-view>标签是路由的出口,路由规则匹配的组件模板对象将被注册成真正的Vue组件,并替换该出口标签 -->
在完成以上这些操作后,页面上最终会有一个按钮和一个链接,点击他们将渲染对应的组件。
2,路由重定向
如果只是上面那样设置,会存在一个问题:首次进入页面时不会有任何组件被渲染。一般情况下,我们第一次进入页面,即根域名下时,希望展示一个默认组件,vue-router有两种方式可以实现。
1 const routes = [
2 {//重定向到一个已知组件
3 path:'/',
4 redirect:'/foo'
5 },
6 {//指定一个额外的页面,比如欢迎页
7 path:'/',
8 redirect:'/welcome'
9 }
10 ]
3,激活的样式
为了让用户获得更好的体验,当用户点击某个<router-link>时,我们可以给这个导航组件设置特别的样式,以提醒用户当前渲染的是什么,vue-router提供了两个css类来实现这一功能:router-link-active和router-link-exact-active。
1 router-link-active{
2 /*some code*/
3 }
4 router-link-exact-active{
5 /*some code*/
6 }
另外你还可以通过给路由实例添加linkActiveClass和linkExactActiveClass两个属性来自定义这两个类名。
这两个类的最终效果相同,但router-link-exact-active的优先级更高。
4,路由过渡
我们知道,<router-view>是基本的动态组件,所以我们可以用 <transition>
组件给它添加一些过渡效果。
1 <transition>
2 <router-view></router-view>
3 </transition>
上面的方式会给所有路由设置相同的过渡效果,如果你想给每个路由单独设置过渡效果,那么你需要在子组件内部单独使用<transition>,并为它设置name属性。
1 const Foo = {
2 template: `
3 <transition name="slide">
4 <div class="foo">...</div>
5 </transition>
6 `
7 }
8
9 const Bar = {
10 template: `
11 <transition name="fade">
12 <div class="bar">...</div>
13 </transition>
14 `
15 }
三 路由操作
1,路由传参
VueRouter有两种方式向组件传递参数,分别是:$route.query和$route.params。下面通过示例来详细说明。
<div id="app">
<router-link tag="button" to="/com1?name=ren&age=12">$route.query</router-link>
<router-link tag="button" to="/com2/ren/12">$route.params</router-link>
<router-view><router-view>
</div>
<script>
var com1 = {
template:"<div>{{$route.query.name}}:{{$route.query.age}}</div>",
};
var com2 = {
template:"<div>{{$route.params.name}}:{{$route.params.age}}</div>",
};
const routerObj = new VueRouter({
routes:[
{path:'/com1',component:com1},
{path:'/com2/:age/:name',component:com2},]
});
var vm = new Vue({
el:"#app",
router:routerObj
});
</script>
请注意两种方式使用时的差异:$route.query 通过url的查询参数(?问号后面的)传递数据,并且不需要修改路由规则(path属性)。$route.params 需要修改路由规则,通过定义变量(:冒号占位符)来获取数据,并且,路由规则中定义了多少个变量,触发路由(点击<router-link>)时就必须传递多少个,否则路由将不能正常工作。
2,路由嵌套
VueRouter通过children属性实现路由嵌套。children属性是路由规则对象的另一个属性,和path,component属性同级。
1 <div id="app">
2 <router-link to="/com1">com1<router-link>
3 <router-view></router-view>
4 </div>
5
6 <template id="com1">
7 <router-link to="/com1/login">login</router-link>
8 <router-view></router-view>
9 </template>
10 <template id="login">
11 <p>login</p>
12 </template>
1 var routerObj = new VueRouter({
2 routes:[
3 {
4 path:'/com1',
5 component:com1,
6 children:[
7 {path:'login',component:login}
8 ]
9 }
10 ]
11 });
根路径下点击com1按钮将展示com1组件,在com1组件内有一个login按钮,点击该按钮将在com1组件内展示login组件。
这里有一个注意点,children属性中的路由规则对象,其path属性不需要从根路径开始匹配(不需要从/斜线开始),当触发该路由时(/com1/login),它会自动从根路径开始,依次匹配/com1、/com1/path,最终成功渲染login组件。
3,命名视图
多数时候,当路由规则匹配到一个url路径时,我们需要展示的组件不止一个,这时候,我们就需要命名视图来帮忙了。
1 <div id="app">
2 <router-view></router-view>
3 <router-view name="left"></router-view>
4 <router-view name="right"></router-view>
5 </div>
6
7 <script>
8 var header = {template:'<div>header</div>'};
9 var left = {template:'<div>left</div>'};
10 var right = {template:'<div>right</div>'};
11
12 const routerObj = new VueRouter({
13 routes:[
14 {
15 path:'/',
16 components:{default:header,left,right}
17 }
18 ]
19 });
20
21 var vm = new Vue({
22 el:'#app',
23 router:routerObj
24 });
25 </script>
通过给<router-view>添加name属性,并在路由规则对象中添加多个组件模板,即可以实现统一url地址匹配多个组件的需求了。