想学习 vue 的 SPA 应用, 路由这一块是必不可少的. 相信很多和我一样刚接触前端的朋友对于路由这玩意是很困惑的. 所以在我学习并成功使用了 vue-router 后, 将我的个人经验分享出来, 希望可以让同样对路由不知所措的同学有所帮助.
注意:
本文 demo 的项目结构用的是最新的命令行工具 https://github.com/vuejs/vue-cli 创建的 webpack 项目模板;
本文知识点是基于 Vue2.0 和 vue-route 2 的, 更多内容请参考 vue.js 官网 http://cn.vuejs.org/ 和 vue-router 2 官方文档 http://router.vuejs.org/zh-cn/ :
一, 路由的安装:
npm 安装
可以使用 npm 直接安装插件
npm install vue-router --save
执行命令完成 vue-router 的安装, 并在 package.json 中添加了 vue-router 的依赖. 当我们在其他电脑上安装项目时只需要执行 npm install 即可完成安装.
package.json
"dependencies": {
...
"vue-router": "^2.1.1"
...
},
如果是要安装在开发环境下, 则使用以下命令行:
npm install vue-router --save-dev
package.json
"devDependencies": {
...
"vue-router": "^2.1.1",
...
},
二, SPA 中路由的简单实现 (附 demo)
下面让我们来配置路由并实现我们的第一次页面跳转.
官方提供的 demo http://router.vuejs.org/zh-cn/essentials/getting-started.html 很简单, 复制到 HTML 中也的确能跑, 但是问题是不知道如何在 SPA 应用中使用, 这坑了我不少时间. 在看了不少他人的项目后, 完成了 SPA 路由的简单实现 demo(基于 vue-cli 的 webpack 模板).
main.js
- import Vue from 'vue'import App from './App'import VueRouter from 'vue-router'import Page01 from './components/page01'import Page02 from './components/page02'Vue.use(VueRouter) // 全局安装路由功能
- // 定义路径
- const routes = [{
- path: '/',
- component: Page01
- },
- {
- path: '/02',
- component: Page02
- },
- ]
- // 创建路由对象
- const router = new VueRouter({
routes
- }) new Vue({
- el: '#app',
- template: '<App/>',
- components: {
App
},
router
})
App.vue
- <template>
- <div id="app">
- <router-link to="/">01</router-link>
- <router-link to="/02">02</router-link>
- <br/>
- <router-view></router-view>
- </div>
- </template>
page01.vue
- <template>
- <div>
- <h1>page02</h1>
- </div>
- </template>
page02.vue
- <template>
- <div>
- <h1>page02</h1>
- </div>
- </template>
实现步骤:
npm 安装 vue-router
Vue.use(VueRouter) 全局安装路由功能
定义路径数组 routes 并创建路由对象 router
将 router 对象传到 Vue 对象中
在根组件中使用 < router-link > 定义跳转路径
在根组件中使用 < router-view > 来渲染组件
创建子组件
三, 路由的跳转
router-link
router-link 标签用于页面的跳转, 简单用法我们刚才提到过了.
<router-link to="/page01">page01</router-link>
点击这个 router-link 标签 router-view 就会渲染路径为 / page01 的页面.
注意: router-link 默认是一个 < a > 标签的形式, 如果需要显示不同的样子, 可以在 router-link 标签中写入不同标签元素, 如下显示为 button 按钮.
- <router-link to="/04">
- <button>to04</button>
- </router-link>
router.push
下面我们通过 JS 代码控制路由的界面渲染, 官方文档写法如下:
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
// 带查询参数, 变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
那么问题来了, 如果是全局注册的路由 Vue.use(VueRouter), 应该怎么写呢?
// 字符串
this.$router.push('home')
// 对象
this.$router.push({ path: 'home' })
// 命名的路由
this.$router.push({ name: 'user', params: { userId: 123 }})
// 带查询参数, 变成 /register?plan=private
this.$router.push({ path: 'register', query: { plan: 'private' }})
为什么能这么写呢, 猜测是将 router 对象传递给 Vue 对象后, 复制 router 对象为 Vue.$router 上了. 还未在源码中求证, 如有错误请指出, 谢谢~
push 方法其实和
<router-link :to="...">
的写法是等同的.
注意: push 方法的跳转会向 history 栈添加一个新的记录, 当我们点击浏览器的返回按钮时可以看到之前的页面.
router.replace
push 方法会向 history 栈添加一个新的记录, 而 replace 方法是替换当前的页面, 不会向 history 栈添加一个新的记录. 用法如下
- template
- <router-link to="/05" replace>05</router-link>
- script
this.$router.replace({ path: '/05' })
router.go
go 方法用于控制 history 记录的前进和后退
// 在浏览器记录中前进一步, 等同于 history.forward()
this.$router.go(1)
// 后退一步记录, 等同于 history.back()
this.$router.go(-1)
- // 前进 3 步记录 router.go(3)
- // 如果 history 记录不够用, 那就默默地失败呗
this.$router.go(-100)
this.$router.go(100)
其实很好理解: go 方法就是浏览器上的前进后退按钮, 方法中传递的数字参数就是前进和后退的次数
四, 路由的传参方式
在路由跳转的过程中会传递一个 object, 我们可以通过 watch 方法查看路由信息对象.
- watch: {
- '$route' (to, from) {
- console.log(to);
- console.log(from);
- },
- },
console 中看到的路由信息对象
{
...
- params: { id: '123' },
- query: { name: 'jack' },
...
}
这两个参数会在页面跳转后写在路径中, 路径相当于 / page/123?name=jack
1. params
params 传递的数据可用于匹配动态路由字段. 如 params 的数据为
params: { abc: 'hello', txt: 'world' }
而动态路由路径为 path: '/05/:txt 那么最终的路径就会是 /05/world. 所以, 动态路由其实就是一种 params 的传递方式.
注意: 由于动态路由也是传递 params 的, 所以在 this.$router.push() 方法中 path 不能和 params 一起使用, 否则 params 将无效! 需要用 name 来指定页面. 之后动态路由会从 params 中找到动态路由同名的数据.
传递数据
在路由配置文件中定义参数
export default [
...
- { name: 'Page05', path: '/05/:txt', component: Page05 },
- ]
下面有两种传递 params 的方式
1. 通过 path 传递
路径后面的 /:txt 就是我们要传递的参数.
this.$router.push({ path: '/05/441'})
此时路由跳转的路径
http://localhost:8080/#/05/441
此时我们看到查看路由信息对象:
{
...
- params: {
- txt: '441'
- }
...
}
2. 通过 params 传递
- this.$router.replace({
- name: 'Page05',
- params: { abc: 'hello', txt: 'world' },
- query: { name: 'query', type: 'object' }
- })
通过 name 获取页面, 传递 params 和 query.
得到的 URL 为
http://localhost:8080/#/05/world?name=query&type=object
而获取到的参数为
{
...
- params: {
- abc: "hello",
- txt: "world"
- }
...
}
获取数据
- template
- <h2> {{ $route.params.txt }} </h2>
- script
- console.log(this.$route.params.txt)
2. query
query 传递数据的方式就是 URL 常见的查询参数, 如
/foo?user=1&name=2&age=3
. 很好理解, 下面就简单写一下用法以及结果
传递数据
- template
- <router-link :to="{ path:'/05', query: { name:'query', type:'object'}}" replace>05</router-link>
- script
this.$router.replace({ path: '/05', query: { name: 'query', type: 'object' }})
路径结果
http://localhost:8080/#/05?name=query&type=object
路由信息对象
{
...
- query: {
- name: "query",
- type: "object"
- }
...
}
获取数据
获取数据和 params 是一样的.
- template
- <h2> {{ $route.query.name }} </h2>
- script
- console.log(this.$route.query.type)
来源: http://www.jianshu.com/p/af076f5792a0