Skip to content

Commit b61829f

Browse files
zhenyongfnlctrl
authored andcommitted
translate into zh-cn (#701)
* translate into zh-cn * Fix docs/zh-cn according to #701#issuecomment-250633734
1 parent 17a0bb1 commit b61829f

23 files changed

+1343
-0
lines changed

docs/zh-cn/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SUMMARY.md

docs/zh-cn/SUMMARY.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# vue-router 2
2+
3+
> 注意: [email protected] 只适用于 Vue 2.x 版本。1.x 版本的文档在 [这里](https://github.com/vuejs/vue-router/tree/1.0/docs/en)
4+
5+
- [版本说明](https://github.com/vuejs/vue-router/releases)
6+
- [安装](installation.md)
7+
- 基础
8+
- [开始](essentials/getting-started.md)
9+
- [动态路由匹配](essentials/dynamic-matching.md)
10+
- [嵌套路由](essentials/nested-routes.md)
11+
- [编程式导航](essentials/navigation.md)
12+
- [命名路由](essentials/named-routes.md)
13+
- [命名视图](essentials/named-views.md)
14+
- [重定向 和 别名](essentials/redirect-and-alias.md)
15+
- [HTML5 History 模式](essentials/history-mode.md)
16+
- 进阶
17+
- [导航钩子](advanced/navigation-guards.md)
18+
- [路由元信息](advanced/meta.md)
19+
- [过渡动效](advanced/transitions.md)
20+
- [数据获取](advanced/data-fetching.md)
21+
- [滚动行为](advanced/scroll-behavior.md)
22+
- [懒加载](advanced/lazy-loading.md)
23+
- API 文档
24+
- [router-link](api/router-link.md)
25+
- [router-view](api/router-view.md)
26+
- [路由信息对象](api/route-object.md)
27+
- [Router 构造配置](api/options.md)
28+
- [Router 实例](api/router-instance.md)
29+
- [对组件注入](api/component-injections.md)

docs/zh-cn/advanced/data-fetching.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# 数据获取
2+
3+
有时候,进入某个路由后,需要从服务器获取数据。例如,在渲染用户信息时,你需要从服务器获取用户的数据。我们可以通过两种方式来实现:
4+
5+
- **导航完成之后获取**:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示『加载中』之类的指示。
6+
7+
- **导航完成之前获取**:导航完成前,在路由的 `enter` 钩子中获取数据,在数据获取成功后执行导航。
8+
9+
从技术角度讲,两种方式都不错 —— 就看你想要的用户体验是哪种。
10+
11+
## 导航完成后获取数据
12+
13+
当你使用这种方式时,我们会马上导航和渲染组件,然后在组件的 `create` 钩子中获取数据。这让我们有机会在数据获取期间展示一个 loading 状态,还可以在不同视图间展示不同的 loading 状态。
14+
15+
假设我们有一个 `Post` 组件,需要基于 `$route.params.id` 获取文章数据:
16+
17+
``` html
18+
<template>
19+
<div class="post">
20+
<div class="loading" v-if="loading">
21+
Loading...
22+
</div>
23+
24+
<div v-if="error" class="error">
25+
{{ error }}
26+
</div>
27+
28+
<div v-if="post" class="content">
29+
<h2>{{ post.title }}</h2>
30+
<p>{{ post.body }}</p>
31+
</div>
32+
</div>
33+
</template>
34+
```
35+
36+
``` js
37+
export default {
38+
data () {
39+
return {
40+
loading: false,
41+
post: null,
42+
error: null
43+
}
44+
},
45+
created () {
46+
// 组件创建完后获取数据,
47+
// 此时 data 已经被 observed 了
48+
this.fetchData()
49+
},
50+
watch: {
51+
// 如果路由有变化,会再次执行该方法
52+
'$route': 'fetchData'
53+
},
54+
methods: {
55+
fetchData () {
56+
this.error = this.post = null
57+
this.loading = true
58+
// replace getPost with your data fetching util / API wrapper
59+
getPost(this.$route.params.id, (err, post) => {
60+
this.loading = false
61+
if (err) {
62+
this.error = err.toString()
63+
} else {
64+
this.post = post
65+
}
66+
})
67+
}
68+
}
69+
}
70+
```
71+
72+
## 在导航完成前获取数据
73+
74+
通过这种方式,我们在导航转入新的路由前获取数据。我们可以在接下来的组件的 `beforeRouteEnter` 钩子中获取数据,当数据获取成功后只调用 `next` 方法。
75+
76+
``` js
77+
export default {
78+
data () {
79+
return {
80+
post: null,
81+
error: null
82+
}
83+
},
84+
beforeRouteEnter (to, from, next) {
85+
getPost(to.params.id, (err, post) =>
86+
if (err) {
87+
// display some global error message
88+
next(false)
89+
} else {
90+
next(vm => {
91+
vm.post = post
92+
})
93+
}
94+
})
95+
},
96+
// 路由改变前,组件就已经渲染完了
97+
// 逻辑稍稍不同
98+
watch: {
99+
$route () {
100+
this.post = null
101+
getPost(this.$route.params.id, (err, post) => {
102+
if (err) {
103+
this.error = err.toString()
104+
} else {
105+
this.post = post
106+
}
107+
})
108+
}
109+
}
110+
}
111+
```
112+
113+
在为后面的视图获取数据时,用户会停留在当前的界面,因此建议在数据获取期间,显示一些进度条或者别的指示。如果数据获取失败,同样有必要展示一些全局的错误提醒。

docs/zh-cn/advanced/lazy-loading.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# 路由懒加载
2+
3+
当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
4+
5+
结合 Vue 的 [异步组件](http://vuejs.org/guide/components.html#Async-Components) 和 Webpack 的 [code splitting feature](https://webpack.github.io/docs/code-splitting.html), 轻松实现路由组件的懒加载。
6+
7+
我们要做的就是把路由对应的组件定义成异步组件:
8+
9+
``` js
10+
const Foo = resolve => {
11+
// require.ensure 是 Webpack 的特殊语法,用来设置 code-split point
12+
// (代码分块)
13+
require.ensure(['./Foo.vue'], () => {
14+
resolve(require('./Foo.vue'))
15+
})
16+
}
17+
```
18+
19+
这里还有另一种代码分块的语法,使用 AMD 风格的 require,于是就更简单了:
20+
21+
``` js
22+
const Foo = resolve => require(['./Foo.vue'], resolve)
23+
```
24+
25+
不需要改变任何路由配置,跟之前一样使用 `Foo`
26+
27+
``` js
28+
const router = new VueRouter({
29+
routes: [
30+
{ path: '/foo', component: Foo }
31+
]
32+
})
33+
```
34+
35+
### 把组件按组分块
36+
37+
有时候我们想把某个路由下的所有组件都打包在同个异步 chunk 中。只需要 [给 chunk 命名](https://webpack.github.io/docs/code-splitting.html#named-chunks),提供 `require.ensure` 第三个参数作为 chunk 的名称:
38+
39+
``` js
40+
const Foo = r => require.ensure([], () => r(require('./Foo.vue')), 'group-foo')
41+
const Bar = r => require.ensure([], () => r(require('./Bar.vue')), 'group-foo')
42+
const Baz = r => require.ensure([], () => r(require('./Baz.vue')), 'group-foo')
43+
```
44+
45+
Webpack 将相同 chunk 下的所有异步模块打包到一个异步块里面 —— 这也意味着我们无须明确列出 `require.ensure` 的依赖(传空数组就行)。

docs/zh-cn/advanced/meta.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# 路由元信息
2+
3+
定义路由的时候可以配置 `meta` 字段:
4+
5+
``` js
6+
const router = new VueRouter({
7+
routes: [
8+
{
9+
path: '/foo',
10+
component: Foo,
11+
children: [
12+
{
13+
path: 'bar',
14+
component: Bar,
15+
// a meta field
16+
meta: { requiresAuth: true }
17+
}
18+
]
19+
}
20+
]
21+
})
22+
```
23+
24+
那么如何访问这个 `meta` 字段呢?
25+
26+
首先,我们称呼 `routes` 配置中的每个路由对象为 **路由记录**。路由记录可以是嵌套的,因此,当一个路由匹配成功后,他可能匹配多个路由记录
27+
28+
例如,根据上面的路由配置,`/foo/bar` 这个 URL 将会匹配父路由记录以及子路由记录。
29+
30+
一个路由匹配到的所有路由记录会暴露为 `$route` 对象(还有在导航钩子中的 route 对象)的 `$route.matched` 数组。因此,我们需要遍历 `$route.matched` 来检查路由记录中的 `meta` 字段。
31+
32+
下面例子展示在全局导航钩子中检查 meta 字段:
33+
34+
``` js
35+
router.beforeEach((to, from, next) => {
36+
if (to.matched.some(record => record.meta.requiresAuth)) {
37+
// this route requires auth, check if logged in
38+
// if not, redirect to login page.
39+
if (!auth.loggedIn()) {
40+
next({
41+
path: '/login',
42+
query: { redirect: to.fullPath }
43+
})
44+
} else {
45+
next()
46+
}
47+
} else {
48+
next() // 确保一定要调用 next()
49+
}
50+
})
51+
```
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# 导航钩子
2+
3+
>(译者:『导航』表示路由正在发生改变。)
4+
5+
正如其名,`vue-router` 提供的导航钩子主要用来拦截导航,让它完成跳转或取消。有多种方式可以在路由导航发生时执行钩子:全局的, 单个路由独享的, 或者组件级的。
6+
7+
### 全局钩子
8+
9+
你可以使用 `router.beforeEach` 注册一个全局的 `before` 钩子:
10+
11+
``` js
12+
const router = new VueRouter({ ... })
13+
14+
router.beforeEach((to, from, next) => {
15+
// ...
16+
})
17+
```
18+
19+
当一个导航触发时,全局的 `before` 钩子按照创建顺序调用。钩子是异步解析执行,此时导航在所有钩子 resolve 完之前一直处于 **等待中**
20+
21+
每个钩子方法接收三个参数:
22+
23+
- **`to: Route`**: 即将要进入的目标 [路由对象](../api/route-object.md)
24+
25+
- **`from: Route`**: 当前导航正要离开的路由
26+
27+
- **`next: Function`**: 一定要调用该方法来 **resolve** 这个钩子。执行效果依赖 `next` 方法的调用参数。
28+
29+
- **`next()`**: 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 **confirmed** (确认的)。
30+
31+
- **`next(false)`**: 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 `from` 路由对应的地址。
32+
33+
- **`next('/')` 或者 `next({ path: '/' })`**: 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
34+
35+
**确保要调用 `next` 方法,否则钩子就不会被 resolved。**
36+
37+
38+
同样可以注册一个全局的 `after` 钩子,不过它不像 `before` 钩子那样,`after` 钩子没有 `next` 方法,不能改变导航:
39+
40+
``` js
41+
router.afterEach(route => {
42+
// ...
43+
})
44+
```
45+
46+
### 某个路由独享的钩子
47+
48+
你可以在路由配置上直接定义 `beforeEnter` 钩子:
49+
50+
``` js
51+
const router = new VueRouter({
52+
routes: [
53+
{
54+
path: '/foo',
55+
component: Foo,
56+
beforeEnter: (to, from, next) => {
57+
// ...
58+
}
59+
}
60+
]
61+
})
62+
```
63+
64+
这些钩子与全局 `before` 钩子的方法参数是一样的。
65+
66+
### 组件内的钩子
67+
68+
最后,你可以使用 `beforeRouteEnter``beforeRouteLeave`,在路由组件内直接定义路由导航钩子,
69+
70+
``` js
71+
const Foo = {
72+
template: `...`,
73+
beforeRouteEnter (to, from, next) => {
74+
// 在渲染该组件的对应路由被 confirm 前调用
75+
// 不!能!获取组件实例 `this`
76+
// 因为当钩子执行前,组件实例还没被创建
77+
},
78+
beforeRouteLeave (to, from, next) => {
79+
// 导航离开该组件的对应路由时调用
80+
// 可以访问组件实例 `this`
81+
}
82+
}
83+
```
84+
85+
`beforeRouteEnter` 钩子 **不能** 访问 `this`,因为钩子在导航确认前被调用,因此即将登场的新组件还没被创建。
86+
87+
不过,你可以通过传一个回调给 `next`来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。
88+
89+
``` js
90+
beforeRouteEnter (to, from, next) => {
91+
next(vm => {
92+
// 通过 `vm` 访问组件实例
93+
})
94+
}
95+
```
96+
97+
你可以 在 `beforeRouteLeave` 中直接访问 `this`。这个 `leave` 钩子通常用来禁止用户在还未保存修改前突然离开。可以通过 `next(false)` 来取消导航。

0 commit comments

Comments
 (0)