- 安装
cnpm install --save vue-router
- 引入
// main.js
import VueRouter from 'vue-router';
Vue.use(VueRouter);
- 使用
// 引入组件
import comA from './components/comA';
import comB from './components/comB';
// 定义路由
const routes = [
{
path: '/comA',
component: comA
},
{
path: '/comB',
component: comB
},
{
path: '*',
redirect: '/comA'
// 首次加载显示 comA (首页) 没有匹配到路径也显示首页
// 重定向, 如果以上配置路由都没有匹配到, 就显示 * 中定义的路由 即 /comA
}
];
// 实例化
const router = new VueRouter({
routes: routes
});
// 挂载
new Vue({
el: '#app',
// 将上一步的 router 放入这个根实例中
router,
store,
components: { App },
template: '<App/>'
});
// 切记: 在 App.vue 中 添加一行 <router-view></router-view>
// router 是若干路由的管理者
// route 是一个路由的映射
基本操作
HTML
<div id="app">
<h1>Hello App!</h1>
<p>
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<router-view></router-view>
</div>
<!--
解释: <router-link to="/foo">Go to Foo</router-link>
- router-link => 将会被解析成 a 标签
- to: "" => 指定这个 a 会跳往何处
---------------------------------
解释: <router-view></router-view>
- 路由匹配到的组件将渲染在这里
例如, 点击 Foo, <router-view> 里面就显示 Foo 的内容
-->
JS
// router.js
import Vue from 'vue';
import VueRouter from "vue-router";
Vue.use(VueRouter);
// 在此导入 组件
import Foo from '../components/foo';
import Bar from '../components/bar';
// 配置路由信息
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 将路由构造出来
const router = new VueRouter({
routes
})
// 导出
// 在 main.js 中引入, 放入 App Vue 实例配置对象中
export default router;
// main.js
import router from './router/index';
new Vue({
el: '#app',
router, // 写入 Vue 根实例的配置项中
components: { App },
template: '<App/>',
store
});
// 注意 ****
// 写入根实例的配置项之后, 我们可以在任何组件内通过 this.$router 访问路由器,
// 也可以通过 this.$route 访问当前路由
完成以上两步HTML和JS的操作之后, 在页面中, 点击 Go to Foo会显示Foo的内容, 另外一个也一样, 同时只会显示一个.
动态路由
在路由跳转的时候, 需要传递值:
// 如果某个路由跳转需要传值, 修改路径配置
// <router-link to="/user/123">About</router-link>
const route = {
path: '/user/:id',
// ... 其他
}
/*
解释: '/user/:id'
- : 冒号标记参数, 这个参数会被设置到 $route.params 中, 上例中为: {id: 123}
*/
<li role="presentation" v-for="id in 5" :key="id">
<router-link :to="{name: 'news', params:{id: id}, query:{user: 123}}">News{{id}}</router-link>
</li>
<!--
这里循环了五个路由, 他们都是属于 news 下的子路由, 相当于在 news 组件中, 新闻列表, 每一条对应着一条新闻,当我们点击的时候, 需要向服务器发起请求, 指定是那一条新闻的数据请求回来渲染, 那么 params 中存放的就是这样的数据, id 就指明了是那一条新闻, 这个 id 我们可以将其拼接在新闻详情请求地址后面, 拿回数据.
我们可以使用 watch 来监听这个 $route , 可以清楚的看见路由是如何切换的
name: news 是在 VueRouter 中定义路由的时候, 给 news 路由给了一个名字, 在这里我们就直接使用这个名字就能找到这个路由
query 则是查询参数
http://localhost:8080/news/5?user=123 在 url 中, 也会拼接上我们传递的数据
-->
你可以在一个路由中设置多段“路径参数”,对应的值都会设置到 $route.params 中。例如:
模式 匹配路径 $route.params
/user/:username /user/evan { username: 'evan' }
/user/:username/post/:post_id /user/evan/post/123 { username: 'evan', post_id: '123' }
除了 route 对象还提供了其它有用的信息,例如,route.hash 等等。
监听路由变化
watch: {
$route (to, from) {
// to: 路由跳往何处
// from: 从哪里跳过来的
}
}
后面还可以使用 路由守卫.
嵌套路由
// 在用户界面下, 还有两个功能, 需要通过点击切换
// 这就需要用到嵌套路由
// 先引入需要跳转的组件
import User from './components/User';
import UserAdd from './components/user/UserAdd';
import UserList from './components/user/UserList';
// 在 user 下添加一个 children 数组, 里面存放子路由的路径和组件
{
path: '/user',
component: User,
children: [
{
path: 'useradd',
component: UserAdd
},
{
path: 'userlist',
component: UserList
}
]
}
// 其他的不用变
在 user 中:
<div class="user">
<div class="left">
<ul>
// 跳转处添加好链接
<li><router-link to="/user/useradd">添加用户</router-link></li>
<li><router-link to="/user/userlist">用户列表</router-link></li>
</ul>
</div>
<div class="right">
在路由需要展示的地方加上 router-view
<router-view></router-view>
</div>
</div>
// 如果需要点击user默认显示第一条, 在 App.vue 中这样设置:
<router-link to="/user/useradd">User ----</router-link>
不必担心在某一个router-view中显示不应该显示的组件, 因为在路由的配置中他就是有层级的, 不属于同一个层级的路由不会被匹配到而显示出来, 所以只要嵌套层级放对了, 就不会出问题.
命名路由
有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
}
]
})
要链接到一个命名路由,可以给 router-link 的 to 属性传一个对象:
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
这跟代码调用 router.push() 是一回事:
router.push({ name: 'user', params: { userId: 123 }})
这两种方式都会把路由导航到 /user/123 路径。
命名视图
有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 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>
一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components配置 (带上 s):
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
// 指定组件显示的位置.
// router-view a 中显示 Bar
// router-view b 中显示 Baz
重定向和别名
重定向也是通过 routes 配置来完成,下面例子是从 /a 重定向到 /b:
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 重定向的 字符串路径/路径对象
if(xx){
return {
path: '/'
....
}
}
}}
]
})
// 如果没有匹配到已经配置的路由, 就会进入重定向路由, 我们可以判断一下, 如果路径是 / 我们就去 首页
// 如果不是, 那说明路由路径有问题, 我们就重定向到 error 页面
// redirect: path | { 配置对象 } | funtion
命名视图
在某个路径下, 需要展示两个或以上的组件, 这时候就需要路由命名
// 配置项需要修改
routes: [
{
path: '/home',
components: {
left: about,
default: home
}
},
{
path: 'about',
components: {
left: home
default: about
}
}
]
// router-view 也需要
<router-view name="left"></router-view>
<router-view></router-view>
// 这时候, 当我们点击 home 的时候, 第一个(left)显示 user, 第二个(default)显示 home
get传值
// main.js 中, 正常配置, 无需添加任何东西
const routes = [
{
path: '/comC',
component: comC
},
];
// 跳转的地方如此配置:
<router-link :to="'/comC?id=' + index" key={{index}}>{{ item }}</router-link>
// 在 C 组件中:
this.$route.query.id
// 可以获取到传递过来的值
编程式路由跳转
this.$router.push({path: '/comB'})
// 前提是 在 main.js 中, 有这个命名了的路由
this.$router.push({name: 'comA'})
// 传递参数
this.$router.push({name: 'comA', params: { userId: 123 }})
this.$router.replace('/all')
// 区别
// push: [a, b, c] => [a, b, c, d]
// replace: [a, b, c] => [a, b, d]
hash路由
默认情况下就是 hash 路由: http://localhost:8080/comC?id=499#/comA
history模式: http://localhost:8080/comC?id=499
直接时候用默认的router-link名称添加active样式
当router-link被激活的时候, 会给标签添加上两个样式
router-link-active router-link-exact-active
其中exact为精确匹配,
没有exact的为模糊匹配, 即'/', '/a', '/abc', 当最后一个被激活的时候, 前面两个也会被激活.这个特性是有用的.
精确匹配也是有特定的使用场景的.
但是有时候我们会觉得这个class太长了:
// 在 router.js 中配置项设置
linkActiveClass: 'active',
linkExactActiveClass: 'exact-active',
通过这样的方式可以修改.