diff --git a/.gitignore b/.gitignore index 7c13a2dbcd..a719c7c361 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ node_modules/ public/ .deploy*/ src/_drafts +.avoscloud/ \ No newline at end of file diff --git a/README.md b/README.md index 4ef988a0d8..cb27dd589a 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,107 @@ -# vuejs.org +## vue.js 2.0 中文文档 https://vuefe.cn -This site is built with [hexo](http://hexo.io/). Site content is written in Markdown format located in `src`. Pull requests welcome! +> 欢迎大家一起参与校对工作 -## Developing +## 镜像站点 -Start a dev server at `localhost:4000`: +### LeanCloud https://vuefe.leanapp.cn/ + +## 贡献要求 + +### 参与: + +- 加群参与 `427447379` +- 发布网址 [vuefe.cn](https://vuefe.cn) +- 翻译仓库 [中文翻译分支 2.0-cn](https://github.com/vuefe/vuefe.github.io) +- [基础指引](https://github.com/vuefe/vuefe.github.io/issues/25) +- 如果你看到错别字、漏译、错译,请直接提交 pr ([帮助](https://help.github.com/articles/using-pull-requests/))。 +- 如果你看到网站问题,或者创建一个 issue ,或者直接提交 pr 。 +- 如果你对已有翻译有异议,建议创建一个 issue 讨论。 +- 如果你想修改英文内容,请去 [vuejs.org 项目](http://vuejs.org/)。 +- 如果你想求教 Vue.js 使用问题,请去[论坛](http://forum.vuejs.org/)。 +- 如果你遇到 Vue.js 的问题,请去 [vue 项目](https://github.com/vuejs/vuejs.org),创建 issue 并提供演示。
+ 可以在 JSBin , JSFiddle , Codepen 等网站创建演示。 + +### 翻译要求 + +- 保持一致,清晰。 +- 汉字,字母,数字等之间以一个空格隔开。 +- 中文使用中文符号,英文使用英文符号。 +- 专有词注意大小写,如 HTML ,CSS , JavaScript 。 +- 术语与已有译文保持一致,如果有异议请先在 issue 中讨论。 +- 代码只翻译注释。 +- 标题会转化为链接,文档其它地方可能会用到,所以标题应尽量简短。
+ 在修改标题时搜索一下它是否还用在其它地方。
+ 同样的,在修改文档内链接时也应搜索一下。 +- 校对后对应修改提交合并请求 + +### 统一固定词汇翻译 + +- type => 类型 +- see also => 另见 +- details => 详细 +- options => 选项 +- example => 示例 +- restriction => 限制 +- default => 默认值 +- prop => 特性(是指 API 的时候,不要翻译成中文) +- attribute => 特性 +- transition => 过渡 + +### 不翻译的术语 + +- getter +- setter +- prop(指 API 时) + +### 认领说明 + +- 参与前,请在对应issue认领 +- 认领格式 : + - 未完成 + - [ ] 我校对 + `文档序号 ` + +- markdown语法 - 示例 + +```markdown +- [ ] 我xx `1` ``` -$ npm install -g hexo-cli -$ npm install -$ hexo server + + - 完成后,打钩表示完成,并附带发起的合并请求链接 + - [x] 我校对 + `文档序号 ` + https://github.com/vuefe/vuefe.github.io/pull/65 (发起的合并请求链接) + +- markdown语法 - 示例 + +```markdown +- [x] 我xx + `1 ` https://github.com/vuefe/vuefe.github.io/pull/65 (发起的合并请求链接) ``` + +- 支持多人协作翻译。已经认领过的翻译,如果你觉着他/她翻译的太慢,可以再次认领,加速翻译。 + + +## 翻译进度 + +### Guide +翻译已完成
+ +### API +翻译已完成
+ +### Examples +翻译已完成
+ +### Vuex 2.0 +翻译已完成
+校对中
+ +### webpack2 +翻译中 [webpack.js.org](https://github.com/vuefe/webpack2)
+ + + + +## 参与翻译&校对成员名单 +https://github.com/vuefe/vuefe.github.io/issues/192 + +### 感谢所有参与翻译的朋友们! diff --git a/_config.yml b/_config.yml index 182ed390e0..72788e187d 100644 --- a/_config.yml +++ b/_config.yml @@ -8,11 +8,11 @@ subtitle: description: "Reactive Components for Modern Web Interfaces" author: Evan You email: -language: +language: zh-CN # URL ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' -url: http://vuejs.org +url: http://vuefe.cn root: / permalink: :year/:month/:day/:title/ tag_dir: tags @@ -97,7 +97,8 @@ markdown: ## Docs: http://zespia.tw/hexo/docs/deployment.html deploy: type: git - repository: git@github.com:vuejs/vuejs.org.git + repository: https://github.com/vuefe/vuefe.github.io.git + branch: gh-pages feed: type: atom diff --git a/package.json b/package.json index 4e94bc532a..4d767e0f17 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "version": "3.2.2" }, "dependencies": { + "hexo-browsersync": "^0.2.0", "hexo": "^3.2.2", "hexo-deployer-git": "0.1.0", "hexo-generator-archive": "^0.1.4", diff --git a/server.js b/server.js new file mode 100644 index 0000000000..3b33885f20 --- /dev/null +++ b/server.js @@ -0,0 +1,21 @@ +var express = require('express'); +var AV = require('leanengine'); +var path = require('path'); +var app = express(); + +var port = process.env.LEANCLOUD_APP_PORT || 3000; + +AV.init({ + appId: process.env.LEANCLOUD_APP_ID, + appKey: process.env.LEANCLOUD_APP_KEY, + masterKey: process.env.LEANCLOUD_APP_MASTER_KEY +}); +app.enable('trust proxy'); +app.use(AV.express()); +app.use(AV.Cloud.HttpsRedirect()); +app.use(express.static(__dirname + '/public')); +app.get('/', function(req, res) { + res.sendFile(path.resolve('./public/index.html')) +}); + +app.listen(port); \ No newline at end of file diff --git a/src/CNAME b/src/CNAME index 998cc417c8..ef5fa2c57b 100644 --- a/src/CNAME +++ b/src/CNAME @@ -1 +1 @@ -vuejs.org +vuefe.cn diff --git a/src/about/guide.md b/src/about/guide.md new file mode 100644 index 0000000000..bd73bde2d5 --- /dev/null +++ b/src/about/guide.md @@ -0,0 +1,91 @@ +--- +title: 参与指南 +type: about +order: 1 +--- + +> 目前急需校对 + + +## 参与要求 + +### 参与: + +> 参与请阅读 [翻译规范](https://github.com/vuefe/vuejs.org/wiki/%E7%BF%BB%E8%AF%91%E8%A7%84%E8%8C%83) + +- 加群参与 `427447379` +- [发布网址:vuefe.cn](http://vuefe.cn/) +- [翻译仓库](https://github.com/vuefe/vuejs.org) ,中文翻译分支 2.0-cn +- [基础指引](https://github.com/vuefe/vuejs.org/wiki/%E5%85%B3%E4%BA%8E%E7%BF%BB%E8%AF%91---%E5%9F%BA%E7%A1%80%E6%8C%87%E5%BC%95) +- 参与API翻译:https://github.com/vuefe/vuejs.org/issues/44 +- 参与Guide校对:https://github.com/vuefe/vuejs.org/issues/77 +- 提出建议:https://github.com/vuefe/vuejs.org/issues/48 +- 如果你看到错别字、漏译、错译,请直接提交 pr + ([帮助](https://help.github.com/articles/using-pull-requests/))。 +- 如果你看到网站问题,或者创建一个 issue,或者直接提交 pr。 +- 如果你对已有翻译有异议,建议创建一个 issue 讨论。 +- 如果你想修改英文内容,请去 [vuejs.org 项目][vuejs.org]。 +- 如果你想求教 Vue.js 使用问题,请去[论坛][forum]。 +- 如果你遇到 Vue.js 的问题,请去 [vue 项目][vue], + 创建 issue 并提供演示。可以在 JSBin, JSFiddle, Codepen 等网站创建演示。 + +### 翻译要求 + +- 保持一致,清晰 +- 汉字,字母,数字等之间以一个空格隔开。 +- 中文使用中文符号,英文使用英文符号。 +- 专有词注意大小写,如 HTML,CSS,JavaScript。 +- 术语与已有译文保持一致,如果有异议请先在 issue 中讨论。 +- 代码只翻译注释。 +- 标题会转化为链接,文档其它地方可能会用到,所以标题应尽量简短, + 在修改标题时搜索一下它是否还用在其它地方。 + 同样的,在修改文档内链接时也应搜索一下。 +- 校对后对应修改提交合并请求 + +### 统一固定词汇翻译 + +- Type => 类型 +- See also => 另见 +- Details => 详细 +- Options => 选项 +- Example => 示例 +- Restriction => 限制 +- default => 默认值 +- prop => 特性(是指 一个 API 时候,不要翻译成中文) +- attribute => 特性 +- transition => 过渡 + +### 术语翻译对照 + +- attribute 特性 +- transition 过渡 + +### 不翻译的术语 + +- getter +- setter +- prop(指API时) + +### 认领说明 + +- 参与前,请在对应issue认领 +- 认领格式 : + - 未完成 + - [ ] 我校对 + `文档序号 ` + +- markdown语法 - 示例 + +```markdown +- [ ] 我xx `1` +``` + + - 完成后,打钩表示完成,并附带 发起的合并请求链接 + - [x] 我校对 + `文档序号 ` + https://github.com/vuefe/vuejs.org/pull/65 (发起的合并请求链接) + +- markdown语法 - 示例 + +```markdown +- [x] 我xx + `1 ` https://github.com/vuefe/vuejs.org/pull/65 (发起的合并请求链接) +``` + +- 支持多人协作翻译,冲突可以解决,认领过的,如果你觉着他太慢,可以再次认领,加速翻译,知道大家都是牺牲业余时间来贡献,所以慢也是可以理解的,慢就需要大家一起帮帮忙了!谢谢。 diff --git a/src/about/index.md b/src/about/index.md new file mode 100644 index 0000000000..c7cb91b1c3 --- /dev/null +++ b/src/about/index.md @@ -0,0 +1,90 @@ +--- +title: 贡献者 +type: about +order: 0 +--- + +## 目前任务 + +- [vue 2.0 - Guide 翻译校对 (进度 / 认领)](https://github.com/vuefe/vuejs.org/issues/77) +- [vuex 2.0 - 文档翻译 (进度 / 认领)](https://github.com/vuefe/vuejs.org/issues/124) +- [webpack2 中文文档翻译(进度 / 认领)](https://github.com/vuefe/webpack.js.org/issues/2) + + + +## Guide 翻译贡献 + +### Essentials 基础 + +序号 | 对应文档文件名 | 中文标题 | 翻译贡献者 | 校对主要贡献者 +----- | ------------- | --- | --- | --- | --- | --- +1 | installation.md | 安装 | [dingyiming](https://github.com/dingyiming) | [ATLgo](https://github.com/ATLgo) [70data](https://github.com/70data) +2 | index.md | 介绍 | [hijiangtao](https://github.com/hijiangtao) | [70data](https://github.com/70data) [ATLgo](https://github.com/ATLgo) +3 | instance.md | 实例 | [dingyiming](https://github.com/dingyiming) | [70data](https://github.com/70data) [ATLgo](https://github.com/ATLgo) +4 | syntax.md | 模板语法 | [daix6](https://github.com/daix6) | [70data](https://github.com/70data) +5 | computed.md | 计算属 性 | [dingyiming](https://github.com/dingyiming) [70data](https://github.com/70data) | [70data](https://github.com/70data) +6 | class-and-style.md | Class 与 Style 绑定 | [595074187](https://github.com/595074187) | [70data](https://github.com/70data) +7 | conditional.md | 条件渲染 | [dingyiming](https://github.com/dingyiming) | [hgcoder](https://github.com/hgcoder) +8 | list.md | 列表渲染 | [tingtien](https://github.com/tingtien) | [hgcoder](https://github.com/hgcoder) +9 | events.md | 事件处理器 | [dingyiming](https://github.com/dingyiming) | [yangzj1992](https://github.com/yangzj1992) +10 | forms.md | 表单控件绑定 | [dingyiming](https://github.com/dingyiming) | [yangzj1992](https://github.com/yangzj1992) +11 | components.md | 组件 | [ezreally](https://github.com/ezreally) | [cuiyongjian](https://github.com/cuiyongjian) + +### Advanced 进阶 + +序号 | 对应文档文件名 | 中文标题 | 翻译贡献者 | 校对主要贡献者 +----- | ------------- | --- | --- | --- | --- +12 | transitions.md | 过渡: 进入, 离开, 和 列表 | [awe](https://github.com/hilongjw) | [bhnddowinf](https://github.com/bhnddowinf) [StoneQI](https://github.com/StoneQI) +13 | transitioning-state.md | 过渡状态 | [awe](https://github.com/hilongjw) | [bhnddowinf](https://github.com/bhnddowinf) +14 | render-function.md | Render 函数 | [awe](https://github.com/hilongjw) | [bhnddowinf](https://github.com/bhnddowinf) +15 | reactivity.md | 深入响应式原理 | [veaba](https://github.com/veaba) | [yangzj1992](https://github.com/yangzj1992) +16 | custom-directive.md | 自定义指令 | [harrytospring](https://github.com/harrytospring) | [yangzj1992](https://github.com/yangzj1992) +17 | mixins.md | 混合 | [harrytospring](https://github.com/harrytospring) | [bhnddowinf](https://github.com/bhnddowinf) +18 | plugins.md | 插件 | [hgcoder](https://github.com/hgcoder) | [hgcoder](https://github.com/hgcoder) +19 | single-file-components.md | 单文件组件 | [ATLgo](https://github.com/ATLgo) | [zhouzihanntu](https://github.com/zhouzihanntu) +20 | routing.md | 路由 | [dingyiming](https://github.com/dingyiming) | [mlyknown](https://github.com/mlyknown) +21 | state-management.md | 状态管理 | [dear-lizhihua](https://github.com/dear-lizhihua) | [mlyknown](https://github.com/mlyknown) +22 | unit-testing.md | 单元测试 | [70data](https://github.com/70data) | [mlyknown](https://github.com/mlyknown) +23 | ssr.md | 服务端渲染 | [dingyiming](https://github.com/dingyiming) | [yongbolv](https://github.com/yongbolv) + +### Migration 迁移 + +序号 | 对应文档文件名 | 中文标题 | 翻译贡献者 | 校对主要贡献者 +----- | ------------- | --- | --- | --- | --- +24 | migration.md | 1.x迁移 | [harrytospring](https://github.com/harrytospring) | [yongbolv](https://github.com/yongbolv) +27 | migration-vue-router.md | vue-router 0.7.x 迁移 | [forzajuve10](https://github.com/forzajuve10) | [yizhixiaolongxia](https://github.com/yizhixiaolongxia) + +### Meta 更多 + +序号 | 对应文档文件名 | 中文标题 | 翻译贡献者 | 校对主要贡献者 +----- | ------------- | --- | --- | --- | --- +25 | comparison.md | 对比其他框架 | [yongbolv](https://github.com/yongbolv) | [yangzj1992](https://github.com/yangzj1992) +26 | join.md | 加入 Vue.js 社区 | [daix6](https://github.com/daix6) | [zhouzihanntu](https://github.com/zhouzihanntu) + +## API翻译贡献 + +序号 | 对应小节名称 | 中文标题 | 翻译贡献者 | 校对主要贡献者 +----- | ------------- | --- | --- | --- | --- | --- +1 | Global Config | 全局配置 | [dear-lizhihua](https://github.com/dear-lizhihua) | [bhnddowinf](https://github.com/bhnddowinf) +2 | Global API | 全局 API | [dear-lizhihua](https://github.com/dear-lizhihua) | [bhnddowinf](https://github.com/bhnddowinf) +3 | Options / Data | 选项 / 数据 | [dear-lizhihua](https://github.com/dear-lizhihua) | [bhnddowinf](https://github.com/bhnddowinf) +4 | Options / DOM | 选项 / DOM | [ATLgo](https://github.com/ATLgo) | [bhnddowinf](https://github.com/bhnddowinf) +5 | Options / Lifecycle Hooks | 选项 / 生命周期钩子 | [ATLgo](https://github.com/ATLgo) | [bhnddowinf](https://github.com/bhnddowinf) +6 | Options / Assets | 选项 / 资源 | [dingyiming](https://github.com/dingyiming) | [bhnddowinf](https://github.com/bhnddowinf) +7 | Options / Misc | 选项 / 杂项 | [dingyiming](https://github.com/dingyiming) | [bhnddowinf](https://github.com/bhnddowinf) +8 | Instance Properties | 实例属性 | [coolzjy](https://github.com/coolzjy) | [bhnddowinf](https://github.com/bhnddowinf) +9 | Instance Methods / Data | 实例方法 / 数据 | [dingyiming](https://github.com/dingyiming) | [bhnddowinf](https://github.com/bhnddowinf) +10 | Instance Methods / Events | 实例方法 / 事件 | [mlyknown](https://github.com/mlyknown) | [bhnddowinf](https://github.com/bhnddowinf) +11 | Instance Methods / Lifecycle | 实例方法 / 生命周期 | [mlyknown](https://github.com/mlyknown)| [bhnddowinf](https://github.com/bhnddowinf) +12 | Directives | 指令| [dingyiming](https://github.com/dingyiming) | [bhnddowinf](https://github.com/bhnddowinf) +13 | Special Attributes | 特殊元素 | [70data](https://github.com/70data) | [bhnddowinf](https://github.com/bhnddowinf) +14 | Built-In Components | 内置的组件 | [dear-lizhihua](https://github.com/dear-lizhihua) | [bhnddowinf](https://github.com/bhnddowinf) +15 | VNode Interface | VNode 接口 | [70data](https://github.com/70data) | [dear-lizhihua](https://github.com/dear-lizhihua) +16 | Server-Side Rendering | 服务端渲染| [70data](https://github.com/70data) | [dear-lizhihua](https://github.com/dear-lizhihua) + +## 示例翻译 + +翻译贡献者 : [lindazhang102](https://github.com/lindazhang102) + + +## 感谢所有参与翻译的朋友们! diff --git a/src/api/index.md b/src/api/index.md index f53bc3dcd7..8408577490 100644 --- a/src/api/index.md +++ b/src/api/index.md @@ -2,31 +2,31 @@ type: api --- -## Global Config +## 全局配置 -`Vue.config` is an object containing Vue's global configurations. You can modify its properties listed below before bootstrapping your application: +`Vue.config` 是一个对象,包含 Vue 的全局配置。可以在启动应用之前修改下列属性: ### silent -- **Type:** `boolean` +- **类型:** `boolean` -- **Default:** `false` +- **默认值:** `false` -- **Usage:** +- **用法:** ``` js Vue.config.silent = true ``` - Suppress all Vue logs and warnings. + 取消 Vue 所有的日志与警告。 ### optionMergeStrategies -- **Type:** `{ [key: string]: Function }` +- **类型:** `{ [key: string]: Function }` -- **Default:** `{}` +- **默认值:** `{}` -- **Usage:** +- **用法:** ``` js Vue.config.optionMergeStrategies._my_option = function (parent, child, vm) { @@ -40,34 +40,34 @@ type: api // Profile.options._my_option = 2 ``` - Define custom merging strategies for options. + 自定义合并策略的选项。 - The merge strategy receives the value of that option defined on the parent and child instances as the first and second arguments, respectively. The context Vue instance is passed as the third argument. + 合并策略选项分别接受第一个参数作为父实例,第二个参数为子实例,Vue实例上下文被作为第三个参数传入。 -- **See also:** [Custom Option Merging Strategies](/guide/mixins.html#Custom-Option-Merge-Strategies) +- **参考:** [自定义选项的混合策略](/guide/mixins.html#Custom-Option-Merge-Strategies) ### devtools -- **Type:** `boolean` +- **类型:** `boolean` -- **Default:** `true` (`false` in production builds) +- **默认值:** `true` (生产版为 `false`) -- **Usage:** +- **用法:** ``` js - // make sure to set this synchronously immediately after loading Vue + // 务必在加载 Vue 之后,立即同步设置以下内容 Vue.config.devtools = true ``` - Configure whether to allow [vue-devtools](https://github.com/vuejs/vue-devtools) inspection. This option's default value is `true` in development builds and `false` in production builds. You can set it to `true` to enable inspection for production builds. + 配置是否允许 [vue-devtools](https://github.com/vuejs/vue-devtools) 检查代码。开发版本默认为 `true`,生产版本默认为 `false`。生产版本设为 `true` 可以启用检查。 ### errorHandler -- **Type:** `Function` +- **类型:** `Function` -- **Default:** Error is thrown in place +- **默认值:** 默认抛出错误 -- **Usage:** +- **用法:** ``` js Vue.config.errorHandler = function (err, vm) { @@ -75,17 +75,17 @@ type: api } ``` - Assign a handler for uncaught errors during component render and watchers. The handler gets called with the error and the Vue instance. + 指定组件的渲染和观察期间未捕获错误的处理函数。这个处理函数被调用时,可获取错误信息和 Vue 实例。 > [Sentry](https://sentry.io), an error tracking service, provides [official integration](https://sentry.io/for/vue/) using this option. ### keyCodes -- **Type:** `{ [key: string]: number }` +- **类型:** `{ [key: string]: number }` -- **Default:** `{}` +- **默认值:** `{}` -- **Usage:** +- **用法:** ``` js Vue.config.keyCodes = { @@ -95,27 +95,27 @@ type: api } ``` - Define custom key alias(es) for v-on. + 给 v-on 自定义键位别名。 -## Global API +## 全局 API

Vue.extend( options )

-- **Arguments:** +- **参数:** - `{Object} options` -- **Usage:** +- **用法:** - Create a "subclass" of the base Vue constructor. The argument should be an object containing component options. + 使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。 - The special case to note here is the `data` option - it must be a function when used with `Vue.extend()`. + `data` 选项是特例,需要注意 - 在 `Vue.extend()` 中它必须是函数 ``` html
``` ``` js - // create constructor + // 创建构造器 var Profile = Vue.extend({ template: '

{{firstName}} {{lastName}} aka {{alias}}

', data: function () { @@ -126,82 +126,82 @@ type: api } } }) - // create an instance of Profile and mount it on an element + // 创建 Profile 实例,并挂载到一个元素上。 new Profile().$mount('#mount-point') ``` - Will result in: + 结果如下: ``` html

Walter White aka Heisenberg

``` -- **See also:** [Components](/guide/components.html) +- **参考:** [组件](/guide/components.html)

Vue.nextTick( callback, [context] )

-- **Arguments:** +- **参数:** - `{Function} callback` - `{Object} [context]` -- **Usage:** +- **用法:** - Defer the callback to be executed after the next DOM update cycle. Use it immediately after you've changed some data to wait for the DOM update. + 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。 ``` js - // modify data + // 修改数据 vm.msg = 'Hello' - // DOM not updated yet + // DOM 还没有更新 Vue.nextTick(function () { - // DOM updated + // DOM 更新了 }) ``` -- **See also:** [Async Update Queue](/guide/reactivity.html#Async-Update-Queue) +- **参考:** [异步更新队列](/guide/reactivity.html#Async-Update-Queue)

Vue.set( object, key, value )

-- **Arguments:** +- **参数:** - `{Object} object` - `{string} key` - `{any} value` -- **Returns:** the set value. +- **返回值:** 设置的值. -- **Usage:** +- **用法:** - Set a property on an object. If the object is reactive, ensure the property is created as a reactive property and trigger view updates. This is primarily used to get around the limitation that Vue cannot detect property additions. + 设置对象的属性。如果对象是响应式的,确保属性被创建后也是响应式的,同时触发视图更新。这个方法主要用于避开 Vue 不能检测属性被添加的限制。 - **Note the object cannot be a Vue instance, or the root data object of a Vue instance.** + **注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象** -- **See also:** [Reactivity in Depth](/guide/reactivity.html) +- **参考:** [深入响应式原理](/guide/reactivity.html)

Vue.delete( object, key )

-- **Arguments:** +- **参数:** - `{Object} object` - `{string} key` -- **Usage:** +- **用法:** - Delete a property on an object. If the object is reactive, ensure the deletion triggers view updates. This is primarily used to get around the limitation that Vue cannot detect property deletions, but you should rarely need to use it. + 删除对象的属性。如果对象是响应式的,确保删除能触发更新视图。这个方法主要用于避开 Vue 不能检测到属性被删除的限制,但是你应该很少会使用它。 - **Note the object cannot be a Vue instance, or the root data object of a Vue instance.** + **注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象** -- **See also:** [Reactivity in Depth](/guide/reactivity.html) +- **参考:** [深入响应式原理](/guide/reactivity.html)

Vue.directive( id, [definition] )

-- **Arguments:** +- **参数:** - `{string} id` - `{Function | Object} [definition]` -- **Usage:** +- **用法:** - Register or retrieve a global directive. + 注册或获取全局指令。 ``` js - // register + // 注册 Vue.directive('my-directive', { bind: function () {}, inserted: function () {}, @@ -210,92 +210,92 @@ type: api unbind: function () {} }) - // register (simple function directive) + // 注册(传入一个简单的指令函数) Vue.directive('my-directive', function () { - // this will be called as `bind` and `update` + // 这里将会被 `bind` 和 `update` 调用 }) - // getter, return the directive definition if registered + // getter,返回已注册的指令 var myDirective = Vue.directive('my-directive') ``` -- **See also:** [Custom Directives](/guide/custom-directive.html) +- **参考:** [自定义指令](/guide/custom-directive.html)

Vue.filter( id, [definition] )

-- **Arguments:** +- **参数:** - `{string} id` - `{Function} [definition]` -- **Usage:** +- **用法:** - Register or retrieve a global filter. + 注册或获取全局过滤器。 ``` js - // register + // 注册 Vue.filter('my-filter', function (value) { - // return processed value + // 返回处理后的值 }) - // getter, return the filter if registered + // getter,返回已注册的过滤器 var myFilter = Vue.filter('my-filter') ```

Vue.component( id, [definition] )

-- **Arguments:** +- **参数:** - `{string} id` - `{Function | Object} [definition]` -- **Usage:** +- **用法:** - Register or retrieve a global component. + 注册或获取全局组件。 ``` js - // register an extended constructor + // 注册组件,传入一个扩展过的构造器 Vue.component('my-component', Vue.extend({ /* ... */ })) - // register an options object (automatically call Vue.extend) + // 注册组件,传入一个选项对象(自动调用 Vue.extend) Vue.component('my-component', { /* ... */ }) - // retrieve a registered component (always return constructor) + // 获取注册的组件(始终返回构造器) var MyComponent = Vue.component('my-component') ``` -- **See also:** [Components](/guide/components.html) +- **参考:** [组件](/guide/components.html)

Vue.use( plugin )

-- **Arguments:** +- **参数:** - `{Object | Function} plugin` -- **Usage:** +- **用法:** - Install a Vue.js plugin. If the plugin is an Object, it must expose an `install` method. If it is a function itself, it will be treated as the install method. The install method will be called with Vue as the argument. + 安装 Vue.js 插件。如果插件是一个对象,必须提供 `install` 方法。如果插件是一个函数,它会被作为 install 方法。install 方法将被作为 Vue 的参数调用。 - When this method is called on the same plugin multiple times, the plugin will be installed only once. + 当 install 方法被同一个插件多次调用,插件将只会被安装一次。 -- **See also:** [Plugins](/guide/plugins.html) +- **参考:** [插件](/guide/plugins.html)

Vue.mixin( mixin )

-- **Arguments:** +- **参数:** - `{Object} mixin` -- **Usage:** +- **用法:** - Apply a mixin globally, which affects every Vue instance created afterwards. This can be used by plugin authors to inject custom behavior into components. **Not recommended in application code**. + 全局注册一个混合,影响注册之后所有创建的每个 Vue 实例。插件作者可以使用混合,向组件注入自定义的行为。**不推荐在应用代码中使用**。 -- **See also:** [Global Mixins](/guide/mixins.html#Global-Mixin) +- **参考:** [全局混合](/guide/mixins.html#Global-Mixin)

Vue.compile( template )

-- **Arguments:** +- **参数:** - `{string} template` -- **Usage:** +- **用法:** - Compiles a template string into a render function. **Only available in the standalone build.** + 在render函数中编译模板字符串。**只在独立构建时有效** ``` js var res = Vue.compile('
{{ msg }}
') @@ -309,43 +309,44 @@ type: api }) ``` -- **See also:** [Render Functions](/guide/render-function.html) +- **参考:** [Render 函数](/guide/render-function.html) -## Options / Data +## 选项 / 数据 ### data -- **Type:** `Object | Function` -- **Restriction:** Only accepts `Function` when used in a component definition. +- **类型:** `Object | Function` + +- **限制:** 组件的定义只接受 `function`。 -- **Details:** +- **详细:** - The data object for the Vue instance. Vue will recursively convert its properties into getter/setters to make it "reactive". **The object must be plain**: native objects such as browser API objects and prototype properties are ignored. A rule of thumb is that data should just be data - it is not recommended to observe objects with its own stateful behavior. + Vue 实例的数据对象。Vue 将会递归将 data 的属性转换为 getter/setter,从而让 data 的属性能够响应数据变化。**对象必须是纯粹的对象(含有零个或多个的key/value对)**:浏览器 API 创建的原生对象,原型上的属性会被忽略。大概来说,data 应该只能是数据 - 不推荐观察拥有状态行为的对象。 - Once observed, you can no longer add reactive properties to the root data object. It is therefore recommended to declare all root-level reactive properties upfront, before creating the instance. + 一旦观察过,不需要再次在数据对象上添加响应式属性。因此推荐在创建实例之前,就声明所有的根级响应式属性。 - After the instance is created, the original data object can be accessed as `vm.$data`. The Vue instance also proxies all the properties found on the data object, so `vm.a` will be equivalent to `vm.$data.a`. + 实例创建之后,可以通过 `vm.$data` 访问原始数据对象。Vue 实例也代理了 data 对象上所有的属性,因此访问 `vm.a` 等价于访问 `vm.$data.a`。 - Properties that start with `_` or `$` will **not** be proxied on the Vue instance because they may conflict with Vue's internal properties and API methods. You will have to access them as `vm.$data._property`. + 以 `_` 或 `$` 开头的属性 **不会** 被 Vue 实例代理,因为它们可能和 Vue 内置的属性、 API 方法冲突。你可以使用例如 `vm.$data._property` 的方式访问这些属性。 - When defining a **component**, `data` must be declared as a function that returns the initial data object, because there will be many instances created using the same definition. If we still use a plain object for `data`, that same object will be **shared by reference** across all instances created! By providing a `data` function, every time a new instance is created, we can simply call it to return a fresh copy of the initial data. + 当一个**组件**被定义, `data` 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 `data` 仍然是一个纯粹的对象,则所有的实例将**共享引用**同一个数据对象!通过提供 `data` 函数,每次创建一个新实例后,我们能够调用 `data` 函数,从而返回初始数据的一个全新副本数据对象。 - If required, a deep clone of the original object can be obtained by passing `vm.$data` through `JSON.parse(JSON.stringify(...))`. + 如果需要,可以通过将 `vm.$data` 传入 `JSON.parse(JSON.stringify(...))` 得到深拷贝的原始数据对象。 -- **Example:** +- **示例:** ``` js var data = { a: 1 } - // direct instance creation + // 直接创建一个实例 var vm = new Vue({ data: data }) vm.a // -> 1 vm.$data === data // -> true - // must use function when in Vue.extend() + // Vue.extend() 中 data 必须是函数 var Component = Vue.extend({ data: function () { return { a: 1 } @@ -353,32 +354,32 @@ type: api }) ``` -

Note that __you should not use an arrow function with the `data` property__ (e.g. `data: () => { return { a: this.myProp }}`). The reason is arrow functions bind the parent context, so `this` will not be the Vue instance as you expect and `this.myProp` will be undefined.

+

注意,__不应该对 `data` 属性使用箭头函数__ (例如`data: () => { return { a: this.myProp }}`)。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,`this.myProp` 将是 undefined。

-- **See also:** [Reactivity in Depth](/guide/reactivity.html) +- **另见:** [深入响应式原理](/guide/reactivity.html) ### props -- **Type:** `Array | Object` +- **类型:** `Array | Object` -- **Details:** +- **详细:** - A list/hash of attributes that are exposed to accept data from the parent component. It has a simple Array-based syntax and an alternative Object-based syntax that allows advanced configurations such as type checking, custom validation and default values. + props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义校验和设置默认值。 -- **Example:** +- **示例:** ``` js - // simple syntax + // 简单语法 Vue.component('props-demo-simple', { props: ['size', 'myMessage'] }) - // object syntax with validation + // 对象语法,提供校验 Vue.component('props-demo-advanced', { props: { - // just type check + // 只检测类型 height: Number, - // type check plus other validations + // 检测类型 + 其他验证 age: { type: Number, default: 0, @@ -391,19 +392,19 @@ type: api }) ``` -- **See also:** [Props](/guide/components.html#Props) +- **另见:** [Props](/guide/components.html#Props) ### propsData -- **Type:** `{ [key: string]: any }` +- **类型:** `{ [key: string]: any }` -- **Restriction:** only respected in instance creation via `new`. +- **限制:** 只用于 `new` 创建的实例中。 -- **Details:** +- **详细:** - Pass props to an instance during its creation. This is primarily intended to make unit testing easier. + 创建实例时传递 props。主要作用是方便测试。 -- **Example:** +- **示例:** ``` js var Comp = Vue.extend({ @@ -417,30 +418,31 @@ type: api } }) ``` +- **另见:** [Props](/guide/components.html#Props) ### computed -- **Type:** `{ [key: string]: Function | { get: Function, set: Function } }` +- **类型:** `{ [key: string]: Function | { get: Function, set: Function } }` -- **Details:** +- **详细:** - Computed properties to be mixed into the Vue instance. All getters and setters have their `this` context automatically bound to the Vue instance. + 计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。 -

Note that __you should not use an arrow function to define a computed property__ (e.g. `aDouble: () => this.a * 2`). The reason is arrow functions bind the parent context, so `this` will not be the Vue instance as you expect and `this.a` will be undefined.

+

注意,__不应该使用箭头函数来定义计算属性函数__ (例如 `aDouble: () => this.a * 2`)。理由是箭头函数绑定了父级作用域的上下文,所以 `this` 将不会按照期望指向 Vue 实例,`this.a` 将是 undefined。

- Computed properties are cached, and only re-computed on reactive dependency changes. + 计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。 -- **Example:** +- **示例:** ```js var vm = new Vue({ data: { a: 1 }, computed: { - // get only, just need a function + // 仅读取,值只须为函数 aDouble: function () { return this.a * 2 }, - // both get and set + // 读取和设置 aPlus: { get: function () { return this.a + 1 @@ -457,20 +459,20 @@ type: api vm.aDouble // -> 4 ``` -- **See also:** - - [Computed Properties](/guide/computed.html) +- **另见:** + - [计算属性](/guide/computed.html) ### methods -- **Type:** `{ [key: string]: Function }` +- **类型:** `{ [key: string]: Function }` -- **Details:** +- **详细:** - Methods to be mixed into the Vue instance. You can access these methods directly on the VM instance, or use them in directive expressions. All methods will have their `this` context automatically bound to the Vue instance. + methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的 `this` 自动绑定为 Vue 实例。 -

Note that __you should not use an arrow function to define a method__ (e.g. `plus: () => this.a++`). The reason is arrow functions bind the parent context, so `this` will not be the Vue instance as you expect and `this.a` will be undefined.

+

注意,__不应该使用箭头函数来定义 method 函数__ (例如 `plus: () => this.a++`)。理由是箭头函数绑定了父级作用域的上下文,所以 `this` 将不会按照期望指向 Vue 实例,`this.a` 将是 undefined。

-- **Example:** +- **示例:** ```js var vm = new Vue({ @@ -485,17 +487,17 @@ type: api vm.a // 2 ``` -- **See also:** [Methods and Event Handling](/guide/events.html) +- **另见:** [方法与事件处理器](/guide/events.html) ### watch -- **Type:** `{ [key: string]: string | Function | Object }` +- **类型:** `{ [key: string]: string | Function | Object }` -- **Details:** +- **详细:** - An object where keys are expressions to watch and values are the corresponding callbacks. The value can also be a string of a method name, or an Object that contains additional options. The Vue instance will call `$watch()` for each entry in the object at instantiation. + 一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 `$watch()`,遍历 watch 对象的每一个属性。 -- **Example:** +- **示例:** ``` js var vm = new Vue({ @@ -508,9 +510,9 @@ type: api a: function (val, oldVal) { console.log('new: %s, old: %s', val, oldVal) }, - // string method name + // 方法名 b: 'someMethod', - // deep watcher + // 深度 watcher c: { handler: function (val, oldVal) { /* ... */ }, deep: true @@ -520,246 +522,245 @@ type: api vm.a = 2 // -> new: 2, old: 1 ``` -

Note that __you should not use an arrow function to define a watcher__ (e.g. `searchQuery: newValue => this.updateAutocomplete(newValue)`). The reason is arrow functions bind the parent context, so `this` will not be the Vue instance as you expect and `this.updateAutocomplete` will be undefined.

+

注意,__不应该使用箭头函数来定义 watcher 函数__ (例如 `searchQuery: newValue => this.updateAutocomplete(newValue)`)。理由是箭头函数绑定了父级作用域的上下文,所以 `this` 将不会按照期望指向 Vue 实例,`this.updateAutocomplete` 将是 undefined。

-- **See also:** [Instance Methods - vm.$watch](#vm-watch) +- **另见:** [实例方法 - vm.$watch](#vm-watch) -## Options / DOM +## 选项 / DOM ### el -- **Type:** `string | HTMLElement` +- **类型:** `string | HTMLElement` -- **Restriction:** only respected in instance creation via `new`. +- **限制:** 只在由 `new` 创建的实例中遵守。 -- **Details:** +- **详细:** - Provide the Vue instance an existing DOM element to mount on. It can be a CSS selector string or an actual HTMLElement. + 为 Vue 实例提供 DOM 元素挂载。值可以是 CSS 选择符,或实际 HTML 元素。 - After the instance is mounted, the resolved element will be accessible as `vm.$el`. + 在实例挂载之后, 元素可以用 `vm.$el` 访问。 - If this option is available at instantiation, the instance will immediately enter compilation; otherwise, the user will have to explicitly call `vm.$mount()` to manually start the compilation. + 如果这个选项在实例化时有作用,实例将立即进入编译过程,否则,需要显式调用 `vm.$mount()` 手动开启编译。 -

The provided element merely serves as a mounting point. Unlike in Vue 1.x, the mounted element will be replaced with Vue-generated DOM in all cases. It is therefore not recommended to mount the root instance to `` or ``.

+

提供的元素只能作为挂载点。不同于 Vue 1.x,所有的挂载元素会被 Vue 生成的 DOM 替换。因此不推荐挂载root实例到 `` 或者 `` 上。

-- **See also:** [Lifecycle Diagram](/guide/instance.html#Lifecycle-Diagram) +- **另见:** [生命周期图示](/guide/instance.html#Lifecycle-Diagram) ### template -- **Type:** `string` +- **类型:** `string` -- **Details:** +- **详细:** - A string template to be used as the markup for the Vue instance. The template will **replace** the mounted element. Any existing markup inside the mounted element will be ignored, unless content distribution slots are present in the template. + 一个字符串模板作为 Vue 实例的标识使用。模板将会 **替换** 挂载的元素。挂载元素的内容都将被忽略,除非模板的内容有分发 slot。 - If the string starts with `#` it will be used as a querySelector and use the selected element's innerHTML as the template string. This allows the use of the common `` -``` html - -``` -Then you can start writing Vue code and even ship the minified version to production without feeling guilty or having to worry about performance problems. +然后你就可以编写 Vue 代码并应用到生产中,你只要用 min 版 Vue 文件替换掉就不用担心其他的性能问题。 -Since you don't need to know about JSX, ES2015, or build systems to get started with Vue, it also typically takes developers less than a day reading [the guide](/guide) to learn enough to build non-trivial applications. +由于起步阶段不需学 JSX,ES2015 以及构建系统,所以开发者只需不到一天的时间阅读[指南](http://vuejs.org/guide/)就可以建立简单的应用程序。 -### Native Rendering +### 本地渲染 -ReactNative enables you to write native-rendered apps for iOS and Android using the same React component model. This is great in that as a developer, you can apply your knowledge of a framework across multiple platforms. On this front, Vue has an official collaboration with [Weex](https://alibaba.github.io/weex/), a cross-platform UI framework developed by Alibaba Group, which uses Vue as its JavaScript framework runtime. This means with Weex, you can use the same Vue component syntax to author components that can not only be rendered in the Browser, but also natively on iOS and Android! +ReactNative 能使你用相同的组件模型编写有本地渲染能力的 APP(IOS 和 Android)。能同时跨多平台开发,对开发者是非常棒的。相应地,Vue 和 [Weex](https://alibaba.github.io/weex/) 会进行官方合作,Weex 是阿里的跨平台用户界面开发框架,Weex 的 JavaScript 框架运行时用的就是 Vue。这意味着在 Weex 的帮助下,你使用 Vue 语法开发的组件不仅仅可以运行在浏览器端,还能被用于开发 IOS 和 Android 上的原生应用。 -At this moment, Weex is still in active development and is not as mature and battle-tested as ReactNative, but its development is driven by the production needs of the largest e-commerce business in the world, and the Vue team will also actively collaborate with the Weex team to ensure a smooth experience for Vue developers. +在现在,Weex 还在积极发展,成熟度也不能和 ReactNative 相抗衡。但是,Weex 的发展是由世界上最大的电子商务企业的需求在驱动,Vue 团队也会和 Weex 团队积极合作确保为开发者带来良好的开发体验。 -### With MobX +### MobX -MobX has become quite popular in the React community and it actually uses a nearly identical reactivity system to Vue. To a limited extent, the React + MobX workflow can be thought of as a more verbose Vue, so if you're using that combination and are enjoying it, jumping into Vue is probably the next logical step. +Mobx 在 React 社区很流行,实际上在 Vue 也采用了几乎相同的反应系统。在有限程度上,React + Mobx 也可以被认为是更繁琐的 Vue,所以如果你习惯组合使用它们,那么选择 Vue 会更合理。 ## Angular 1 -Some of Vue's syntax will look very similar to Angular (e.g. `v-if` vs `ng-if`). This is because there were a lot of things that Angular got right and these were an inspiration for Vue very early in its development. There are also many pains that come with Angular however, where Vue has attempted to offer a significant improvement. +Vue 的一些语法和 Angular 的很相似(例如 `v-if` vs `ng-if`)。因为 Angular 是 Vue 早期开发的灵感来源。然而,Augular 中存在的许多问题,在 Vue 中已经得到解决。 -### Complexity +### 复杂性 -Vue is much simpler than Angular 1, both in terms of API and design. Learning enough to build non-trivial applications typically takes less than a day, which is not true for Angular 1. +在 API 与设计两方面上 Vue.js 都比 Angular 1 简单得多,因此你可以快速地掌握它的全部特性并投入开发。 -### Flexibility and Modularity +### 灵活性和模块化 -Angular 1 has strong opinions about how your applications should be structured, while Vue is a more flexible, modular solution. While this makes Vue more adaptable to a wide variety of projects, we also recognize that sometimes it's useful to have some decisions made for you, so that you can just get started coding. +Vue.js 是一个更加灵活开放的解决方案。它允许你以希望的方式组织应用程序,而不是在任何时候都必须遵循 Angular 1 制定的规则,这让 Vue 能适用于各种项目。我们知道把决定权交给你是非常必要的。 +这也就是为什么我们提供[Webpack template](https://github.com/vuejs-templates/webpack),让你可以用几分钟,去选择是否启用高级特性,比如热模块加载、linting、CSS 提取等等。 -That's why we offer a [Webpack template](https://github.com/vuejs-templates/webpack) that can set you up within minutes, while also granting you access to advanced features such as hot module reloading, linting, CSS extraction, and much more. +### 数据绑定 -### Data binding +Angular 1 使用双向绑定,Vue 在不同组件间强制使用单向数据流。这使应用中的数据流更加清晰易懂。 -Angular 1 uses two-way binding between scopes, while Vue enforces a one-way data flow between components. This makes the flow of data easier to reason about in non-trivial applications. +### 指令与组件 -### Directives vs Components +在 Vue 中指令和组件分得更清晰。指令只封装 DOM 操作,而组件代表一个自给自足的独立单元 —— 有自己的视图和数据逻辑。在 Angular 中两者有不少相混的地方。 -Vue has a clearer separation between directives and components. Directives are meant to encapsulate DOM manipulations only, while components are self-contained units that have their own view and data logic. In Angular, there's a lot of confusion between the two. +### 性能 -### Performance +Vue 有更好的性能,并且非常非常容易优化,因为它不使用脏检查。 -Vue has better performance and is much, much easier to optimize because it doesn't use dirty checking. Angular 1 becomes slow when there are a lot of watchers, because every time anything in the scope changes, all these watchers need to be re-evaluated again. Also, the digest cycle may have to run multiple times to "stabilize" if some watcher triggers another update. Angular users often have to resort to esoteric techniques to get around the digest cycle, and in some situations, there's simply no way to optimize a scope with many watchers. +在 Angular 1 中,当 watcher 越来越多时会变得越来越慢,因为作用域内的每一次变化,所有 watcher 都要重新计算。并且,如果一些 watcher 触发另一个更新,脏检查循环(digest cycle)可能要运行多次。Angular 用户常常要使用深奥的技术,以解决脏检查循环的问题。有时没有简单的办法来优化有大量 watcher 的作用域。 -Vue doesn't suffer from this at all because it uses a transparent dependency-tracking observation system with async queueing - all changes trigger independently unless they have explicit dependency relationships. +Vue 则根本没有这个问题,因为它使用基于依赖追踪的观察系统并且异步队列更新,所有的数据变化都是独立触发,除非它们之间有明确的依赖关系。 -Interestingly, there are quite a few similarities in how Angular 2 and Vue are addressing these Angular 1 issues. +有意思的是,Angular 2 和 Vue 用相似的设计解决了一些 Angular 1 中存在的问题。 ## Angular 2 -We have a separate section for Angular 2 because it really is a completely new framework. For example, it features a first-class component system, many implementation details have been completely rewritten, and the API has also changed quite drastically. +我们单独将 Augluar 2 作分类,因为它完全是一个全新的框架。例如:它具有优秀的组件系统,并且许多实现已经完全重写,API 也完全改变了。 ### TypeScript -While Angular 1 could be used for smaller applications, Angular 2 has shifted focus to best facilitate large enterprise applications. As part of this, it almost requires TypeScript, which can be very useful for developers that desire the type safety of languages such as Java and C#. +Angular 1 面向的是较小的应用程序,Angular 2 已转移焦点,面向的是大型企业应用。在这一点上 TypeScript 经常会被引用,它对那些喜欢用 Java 或者 C# 等类型安全的语言的人是非常有用的。 -Vue is also well-suited to [enterprise environments](https://github.com/vuejs/awesome-vue#enterprise-usage) and can even be used with TypeScript via our [official typings](https://github.com/vuejs/vue/tree/dev/types) and [user-contributed decorators](https://github.com/itsFrank/vue-typescript), though it's definitely optional in our case. +Vue 也十分适合制作[企业应用](https://github.com/vuejs/awesome-vue#enterprise-usage),你也可以通过使用[官方类型](https://github.com/vuejs/vue/tree/dev/types)或[用户贡献的装饰器](https://github.com/itsFrank/vue-typescript)来支持 TypeScript,这完全是自由可选的。 -### Size and Performance +### 大小和性能 -In terms of performance, both frameworks are exceptionally fast and there isn't enough data from real world use cases to make a verdict. However if you are determined to see some numbers, Vue 2.0 seems to be ahead of Angular 2 according to this [3rd party benchmark](http://stefankrause.net/js-frameworks-benchmark4/webdriver-ts/table.html). +在性能方面,这两个框架都非常的快。但目前尚没有足够的数据用例来具体展示。如果你一定要量化这些数据,你可以查看[第三方参照](http://stefankrause.net/js-frameworks-benchmark4/webdriver-ts/table.html),它表明 Vue 2 相比 Angular2 是更快的。 -Size wise, although Angular 2 with offline compilation and tree-shaking is able to get its size down considerably, a full-featured Vue 2.0 with compiler included (23kb) is still lighter than a tree-shaken bare-bone example of Angular 2 (50kb). And do note the Angular 2 app's size is small due to tree-shaking, which removes code for features that you are not using. It will eventually grow back to its actual size as you import and use more features from the framework. +在大小方面,虽然 Angular 2 使用 tree-shaking 和离线编译技术使代码体积减小了许多。但包含编译器和全部功能的 Vue2(23kb) 相比 Angular 2(50kb) 还是要小的多。但是要注意,用 Angular 2 的 App 的体积缩减是使用了 tree-shaking 移除了那些框架中没有用到的功能,但随着功能引入的不断增多,尺寸会变得越来越大。 -### Flexibility +### 灵活性 -Vue is much less opinionated than Angular 2, offering official support for a variety of build systems, with no restrictions on how you structure your application. Many developers enjoy this freedom, while some prefer having only one Right Way to build any application. +Vue 相比于 Angular 2 则更加灵活,Vue 官方提供了构建工具来协助你构建项目,但它并不限制你去如何构建。有人可能喜欢用统一的方式来构建,也有很多开发者喜欢这种灵活自由的方式。 -### Learning Curve +### 学习曲线 -To get started with Vue, all you need is familiarity with HTML and ES5 JavaScript (i.e. plain JavaScript). With these basic skills, you can start building non-trivial applications within less than a day of reading [the guide](/guide). +开始使用 Vue,你使用的是熟悉的 HTML、符合 ES5 规则的 JavaScript(也就是纯 JavaScript)。有了这些基本的技能,你可以快速地掌握它([指南](/guide))并投入开发 。 -Angular 2's learning curve is much steeper. Even without TypeScript, their [Quickstart guide](https://angular.io/docs/js/latest/quickstart.html) starts out with an app that uses ES2015 JavaScript, NPM with 18 dependencies, 4 files, and over 3,000 words to explain it all - just to say Hello World. It's an understatement to say that [Vue's Hello World](index.html#Hello-World) is considerably simpler. It's so trivial in fact, that we don't even dedicate a whole page in the guide to it. +Angular 2 的学习曲线是非常陡峭的。即使不包括 TypeScript,它的[开始指南](https://angular.io/docs/js/latest/quickstart.html)中所用的就有 ES2015 标准的 JavaScript,18个 NPM 依赖包,4 个文件和超过 3 千多字的介绍,这一切都是为了完成个 Hello World。而[Vue's Hello World](index.html#Hello-World)就非常简单。甚至我们并不用花费一整个页面去介绍它。 ## Ember -Ember is a full-featured framework that is designed to be highly opinionated. It provides a lot of established conventions and once you are familiar enough with them, it can make you very productive. However, it also means the learning curve is high and flexibility suffers. It's a trade-off when you try to pick between an opinionated framework and a library with a loosely coupled set of tools that work together. The latter gives you more freedom but also requires you to make more architectural decisions. +Ember 是一个全能框架。它提供了大量的约定,一旦你熟悉了它们,开发会变得很高效。不过,这也意味着学习曲线较高,而且并不灵活。这意味着在框架和库(加上一系列松散耦合的工具)之间做权衡选择。后者会更自由,但是也要求你做更多架构上的决定。 -That said, it would probably make a better comparison between Vue core and Ember's [templating](https://guides.emberjs.com/v2.7.0/templates/handlebars-basics/) and [object model](https://guides.emberjs.com/v2.7.0/object-model/) layers: +也就是说,我们最好比较的是 Vue 内核和 Ember 的[模板](https://guides.emberjs.com/v2.7.0/templates/handlebars-basics/)与[数据模型](https://guides.emberjs.com/v2.7.0/object-model/)层: -- Vue provides unobtrusive reactivity on plain JavaScript objects and fully automatic computed properties. In Ember, you need to wrap everything in Ember Objects and manually declare dependencies for computed properties. +* Vue 在普通 JavaScript 对象上建立响应,提供自动化的计算属性。在 Ember 中需要将所有东西放在 Ember 对象内,并且手工为计算属性声明依赖。 -- Vue's template syntax harnesses the full power of JavaScript expressions, while Handlebars' expression and helper syntax is intentionally quite limited in comparison. +* Vue 的模板语法可以用全功能的 JavaScript 表达式,而 Handlebars 的语法和帮助函数相比来说非常受限。 -- Performance-wise, Vue outperforms Ember by a fair margin, even after the latest Glimmer engine update in Ember 2.0. Vue automatically batches updates, while in Ember you need to manually manage run loops in performance-critical situations. +* 在性能上,Vue 甩开 Ember 几条街,即使是 Ember 2.0 的最新 Glimmer 引擎。Vue 能够自动批量更新,而 Ember 在关键性能场景时需要手动管理。 ## Knockout -Knockout was a pioneer in the MVVM and dependency tracking spaces and its reactivity system is very similar to Vue's. Its [browser support](http://knockoutjs.com/documentation/browser-support.html) is also very impressive considering everything it does, with support back to IE6! Vue on the other hand only supports IE9+. +Knockout 是 MVVM 领域内的先驱,并且追踪依赖。它的响应系统和 Vue 也很相似。它在[浏览器支持](http://knockoutjs.com/documentation/browser-support.html)以及其他方面的表现也是让人印象深刻的。它最低能支持到 IE6,而 Vue 最低只能支持到 IE9。 -Over time though, Knockout development has slowed and it's begun to show its age a little. For example, its component system lacks a full set of lifecycle hooks and although it's a very common use case, the interface for passing children to a component feels a little clunky compared to [Vue's](components.html#Content-Distribution-with-Slots). +随着时间的推移,Knockout 的发展已有所放缓,并且略显有点老旧了。比如,它的组件系统缺少完备的生命周期事件方法,尽管这些在现在是非常常见的。以及相比于 [Vue](components.html#Content-Distribution-with-Slots) 调用子组件的接口它的方法显得有点笨重。 -There also seem to be philosophical differences in the API design which if you're curious, can be demonstrated by how each handles the creation of a [simple todo list](https://gist.github.com/chrisvfritz/9e5f2d6826af00fcbace7be8f6dccb89). It's definitely somewhat subjective, but many consider Vue's API to be less complex and better structured. +如果你有兴趣研究,你还会发现二者在接口设计的理念上是不同的。这可以通过各自创建的 [simple Todo List](https://gist.github.com/chrisvfritz/9e5f2d6826af00fcbace7be8f6dccb89) 体现出来。或许有点主观,但是很多人认为 Vue 的 API 接口更简单结构更优雅。 ## Polymer -Polymer is yet another Google-sponsored project and in fact was a source of inspiration for Vue as well. Vue's components can be loosely compared to Polymer's custom elements and both provide a very similar development style. The biggest difference is that Polymer is built upon the latest Web Components features and requires non-trivial polyfills to work (with degraded performance) in browsers that don't support those features natively. In contrast, Vue works without any dependencies or polyfills down to IE9. +Polymer 是另一个由谷歌赞助的项目,事实上也是 Vue 的一个灵感来源。Vue 的组件可以粗略的类比于 Polymer 的自定义元素,并且两者具有相似的开发风格。最大的不同之处在于,Polymer 是基于最新版的 Web Components 标准之上,并且需要重量级的 polyfills 来帮助工作(性能下降),浏览器本身并不支持这些功能。相比而言,Vue 在支持到 IE9 的情况下并不需要依赖 polyfills 来工作,。 + +在 Polymer 1.0 版本中,为了弥补性能,团队非常有限的使用数据绑定系统。例如,在 Polymer 中唯一支持的表达式只有布尔值否定和单一的方法调用,它的 computed 方法的实现也并不是很灵活。 -In Polymer 1.0, the team has also made its data-binding system very limited in order to compensate for the performance. For example, the only expressions supported in Polymer templates are boolean negation and single method calls. Its computed property implementation is also not very flexible. +Polymer 自定义的元素是用 HTML 文件来创建的,这会限制使用 JavaScript/CSS(和被现代浏览器普遍支持的语言特性)。相比之下,Vue 的单文件组件允许你非常容易的使用 ES2015 和你想用的 CSS 预编译处理器。 -Polymer custom elements are authored in HTML files, which limits you to plain JavaScript/CSS (and language features supported by today's browsers). In comparison, Vue's single file components allows you to easily use ES2015+ and any CSS preprocessors you want. +在部署生产环境时,Polymer 建议使用 HTML Imports 加载所有资源。而这要求服务器和客户端都支持 Http 2.0 协议,并且浏览器实现了此标准。这是否可行就取决于你的目标用户和部署环境了。如果状况不佳,你必须用 Vulcanizer 工具来打包 Polymer 元素。而在这方面,Vue 可以结合异步组件的特性和 Webpack 的代码分割特性来实现懒加载(lazy-loaded)。这同时确保了对旧浏览器的兼容且又能更快加载。 -When deploying to production, Polymer recommends loading everything on-the-fly with HTML Imports, which assumes browsers implementing the spec, and HTTP/2 support on both server and client. This may or may not be feasible depending on your target audience and deployment environment. In cases where this is not desirable, you will have to use a special tool called Vulcanizer to bundle your Polymer elements. On this front, Vue can combine its async component feature with Webpack's code-splitting feature to easily split out parts of the application bundle to be lazy-loaded. This ensures compatibility with older browsers while retaining great app loading performance. - -It is also totally feasible to offer deeper integration between Vue with Web Component specs such as Custom Elements and Shadow DOM style encapsulation - however at this moment we are still waiting for the specs to mature and be widely implemented in all mainstream browsers before making any serious commitments. +而 Vue 和 Web Component 标准进行深层次的整合也是完全可行的,比如使用 Custom Elements、Shadow DOM 的样式封装。然而在我们做出严肃的实现承诺之前,我们目前仍在等待相关标准成熟,进而再广泛应用于主流的浏览器中。 ## Riot -Riot 2.0 provides a similar component-based development model (which is called a "tag" in Riot), with a minimal and beautifully designed API. Riot and Vue probably share a lot in design philosophies. However, despite being a bit heavier than Riot, Vue does offer some significant advantages: +Riot 2.0 提供了一个类似于基于组件的开发模型(在 Riot 中称之为 Tag),它提供了小巧精美的 API。Riot 和 Vue 在设计理念上可能有许多相似处。尽管相比 Riot ,Vue 要显得重一点,Vue 还是有很多显著优势的: + +- 根据真实条件来渲染,Riot 根据是否有分支简单显示或隐藏所有内容。 +- 功能更加强大的路由机制,Riot 的路由功能的 API 是极少的。 +- 更多成熟工具的支持。Vue 提供官方支持[Webpack](https://github.com/vuejs/vue-loader)、[Browserify](https://github.com/vuejs/vueify)和[SystemJS](https://github.com/vuejs/systemjs-plugin-vue),而 Riot 是依靠社区来建立集成系统。 +- [过渡效果系统](transitions.html)。Riot 现在还没有提供。 +- 更好的性能。Riot [尽管声称](https://github.com/vuejs/vuejs.org/issues/346)其使用了虚拟 DOM,但实际上用的还是脏检查机制,因此和 Angular 1 患有相同的性能问题。 + + +*** + +> 原文:http://vuejs.org/guide/comparison.html -- True conditional rendering. Riot renders all if branches and simply shows/hides them. -- A far more powerful router. Riot’s routing API is extremely minimal. -- More mature tooling support. Vue provides official support for [Webpack](https://github.com/vuejs/vue-loader), [Browserify](https://github.com/vuejs/vueify), and [SystemJS](https://github.com/vuejs/systemjs-plugin-vue), while Riot relies on community support for build system integration. -- [Transition effect system](transitions.html). Riot has none. -- Better performance. [Despite advertising](https://github.com/vuejs/vuejs.org/issues/346) use of a virtual DOM, Riot in fact uses dirty checking and thus suffers from the same performance issues as Angular 1. +*** diff --git a/src/guide/components.md b/src/guide/components.md index 5fbf7e4f0f..f64dc34d8a 100644 --- a/src/guide/components.md +++ b/src/guide/components.md @@ -1,37 +1,37 @@ --- -title: Components +title: 组件 type: guide order: 11 --- -## What are Components? +## 什么是组件? -Components are one of the most powerful features of Vue. They help you extend basic HTML elements to encapsulate reusable code. At a high level, components are custom elements that Vue's compiler attaches behavior to. In some cases, they may also appear as a native HTML element extended with the special `is` attribute. +组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。 -## Using Components +## 使用组件 -### Registration +### 注册 -We've learned in the previous sections that we can create a new Vue instance with: +之前说过,我们可以通过以下方式创建一个Vue实例: ``` js new Vue({ el: '#some-element', - // options + // 选项 }) ``` -To register a global component, you can use `Vue.component(tagName, options)`. For example: +要注册一个全局组件,你可以使用 `Vue.component(tagName, options)`。 例如: ``` js Vue.component('my-component', { - // options + // 选项 }) ``` -

Note that Vue does not enforce the [W3C rules](http://www.w3.org/TR/custom-elements/#concepts) for custom tag names (all-lowercase, must contain a hyphen) though following this convention is considered good practice.

+

对于自定义标签名,Vue.js 不强制要求遵循 [W3C规则](https://www.w3.org/TR/custom-elements/#concepts) (小写,并且包含一个短杠),尽管遵循这个规则比较好。

-Once registered, a component can be used in an instance's template as a custom element, ``. Make sure the component is registered **before** you instantiate the root Vue instance. Here's the full example: +组件在注册之后,便可以在父实例的模块中以自定义元素 `` 的形式使用。要确保在初始化根实例 **之前** 注册了组件: ``` html
@@ -40,18 +40,18 @@ Once registered, a component can be used in an instance's template as a custom e ``` ``` js -// register +// 注册 Vue.component('my-component', { template: '
A custom component!
' }) -// create a root instance +// 创建根实例 new Vue({ el: '#example' }) ``` -Which will render: +渲染为: ``` html
@@ -71,9 +71,9 @@ new Vue({ el: '#example' }) {% endraw %} -### Local Registration +### 局部注册 -You don't have to register every component globally. You can make a component available only in the scope of another instance/component by registering it with the `components` instance option: +不需要全局注册每个组件。可以让组件只能用在其它组件内,用实例选项 `components` 注册: ``` js var Child = { @@ -83,19 +83,19 @@ var Child = { new Vue({ // ... components: { - // will only be available in parent's template + // 将只在父模板可用 'my-component': Child } }) ``` -The same encapsulation applies for other registerable Vue features, such as directives. +这种封装也适用于其它可注册的功能,如指令。 -### DOM Template Parsing Caveats +### DOM 模版解析说明 -When using the DOM as your template (e.g. using the `el` option to mount an element with existing content), you will be subject to some restrictions that are inherent to how HTML works, because Vue can only retrieve the template content **after** the browser has parsed and normalized it. Most notably, some elements such as `
    `, `
      `, `` and `
      ` , `
      @@ -103,7 +103,7 @@ This will lead to issues when using custom components with elements that have su
      ``` -The custom component `` will be hoisted out as invalid content, thus causing errors in the eventual rendered output. A workaround is to use the `is` special attribute: +自定义组件 `` 被认为是无效的内容,因此在渲染的时候会导致错误。变通的方案是使用特殊的 `is` 属性: ``` html @@ -111,17 +111,17 @@ The custom component `` will be hoisted out as invalid content, thus cau
      ``` -**It should be noted that these limitations do not apply if you are using string templates from one of the following sources**: +**需要注意的是这些限制不适用于在以下场景中使用字符串模版时** - ` {% endraw %} -Since all three component instances share the same `data` object, incrementing one counter increments them all! Ouch. Let's fix this by instead returning a fresh data object: +由于这三个组件共享了同一个 `data` , 因此增加一个 counter 会影响所有组件!我们可以通过为每个组件返回新的 data 对象来解决这个问题: ``` js data: function () { @@ -190,7 +189,7 @@ data: function () { } ``` -Now all our counters each have their own internal state: +现在每个 counter 都有它自己内部的状态了: {% raw %}
      @@ -213,11 +212,11 @@ new Vue({ {% endraw %} -### Composing Components +### 构成组件 -Components are meant to be used together, most commonly in parent-child relationships: component A may use component B in its own template. They inevitably need to communicate to one another: the parent may need to pass data down to the child, and the child may need to inform the parent of something that happened in the child. However, it is also very important to keep the parent and the child as decoupled as possible via a clearly-defined interface. This ensures each component's code can be written and reasoned about in relative isolation, thus making them more maintainable and potentially easier to reuse. +组件意味着协同工作,通常父子组件会是这样的关系:组件 A 在它的模版中使用了组件 B 。它们之间必然需要相互通信:父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件。然而,在一个良好定义的接口中尽可能将父子组件解耦是很重要的。这保证了每个组件可以在相对隔离的环境中书写和理解,也大幅提高了组件的可维护性和可重用性。 -In Vue.js, the parent-child component relationship can be summarized as **props down, events up**. The parent passes data down to the child via **props**, and the child sends messages to the parent via **events**. Let's see how they work next. +在 Vue.js 中,父子组件的关系可以总结为 **props down, events up** 。父组件通过 **props** 向下传递数据给子组件,子组件通过 **events** 给父组件发送消息。看看它们是怎么工作的。

      props down, events up @@ -225,29 +224,29 @@ In Vue.js, the parent-child component relationship can be summarized as **props ## Props -### Passing Data with Props +### 使用Props传递数据 -Every component instance has its own **isolated scope**. This means you cannot (and should not) directly reference parent data in a child component's template. Data can be passed down to child components using **props**. +组件实例的作用域是**孤立的**。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。 -A prop is a custom attribute for passing information from parent components. A child component needs to explicitly declare the props it expects to receive using the [`props` option](/api/#props): +prop 是父组件用来传递数据的一个自定义属性。子组件需要显式地用 [`props` 选项](/api/#props) 声明 “prop”: ``` js Vue.component('child', { - // declare the props + // 声明 props props: ['message'], - // just like data, the prop can be used inside templates - // and is also made available in the vm as this.message + // 就像 data 一样,prop 可以用在模板内 + // 同样也可以在 vm 实例中像 “this.message” 这样使用 template: '{{ message }}' }) ``` -Then we can pass a plain string to it like so: +然后向它传入一个普通字符串: ``` html ``` -Result: +结果: {% raw %}

      @@ -268,7 +267,7 @@ new Vue({ ### camelCase vs. kebab-case -HTML attributes are case-insensitive, so when using non-string templates, camelCased prop names need to use their kebab-case (hyphen-delimited) equivalents: +HTML 特性不区分大小写。当使用非字符串模版时,名字形式为 camelCase 的 prop 用作特性时,需要转为 kebab-case(短横线隔开): ``` js Vue.component('child', { @@ -283,11 +282,11 @@ Vue.component('child', { ``` -Again, if you're using string templates, then this limitation does not apply. +再次说明,如果你使用字符串模版,不用在意这些限制。 -### Dynamic Props +### 动态 Props -Similar to binding a normal attribute to an expression, we can also use `v-bind` for dynamically binding props to data on the parent. Whenever the data is updated in the parent, it will also flow down to the child: +类似于用 `v-bind` 绑定 HTML 特性到一个表达式,也可以用 `v-bind` 绑定动态 props 到父组件的数据。每当父组件的数据变化时,也会传导给子组件: ``` html
      @@ -297,13 +296,13 @@ Similar to binding a normal attribute to an expression, we can also use `v-bind`
      ``` -It's often simpler to use the shorthand syntax for `v-bind`: +使用 `v-bind` 的缩写语法通常更简单: ``` html ``` -Result: +结果: {% raw %}
      @@ -327,74 +326,73 @@ new Vue({ {% endraw %} -### Literal vs Dynamic +### 字面量语法 vs 动态语法 -A common mistake beginners tend to make is attempting to pass down a number using the literal syntax: +初学者常犯的一个错误是使用字面量语法传递数值: ``` html - + ``` -However, since this is a literal prop, its value is passed down as a plain string `"1"` instead of an actual number. If we want to pass down an actual JavaScript number, we need to use `v-bind` so that its value is evaluated as a JavaScript expression: +因为它是一个字面 prop ,它的值以字符串 `"1"` 而不是以实际的数字传下去。如果想传递一个实际的 JavaScript 数字,需要使用 `v-bind` ,从而让它的值被当作 JavaScript 表达式计算: ``` html - + ``` -### One-Way Data Flow +### 单向数据流 -All props form a **one-way-down** binding between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around. This prevents child components from accidentally mutating the parent's state, which can make your app's data flow harder to reason about. +prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解. -In addition, every time the parent component is updated, all props in the child component will be refreshed with the latest value. This means you should **not** attempt to mutate a prop inside a child component. If you do, Vue will warn you in the console. +另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你**不应该**在子组件内部改变 prop 。如果你这么做了,Vue 会在控制台给出警告。 -There are usually two cases where it's tempting to mutate a prop: +通常有两种改变 prop 的情况: -1. The prop is used to only pass in an initial value, the child component simply wants to use it as a local data property afterwards; +1. prop 作为初始值传入,子组件之后只是将它的初始值作为本地数据的初始值使用; -2. The prop is passed in as a raw value that needs to be transformed. +2. prop 作为需要被转变的原始值传入。 -The proper answer to these use cases are: +更确切的说这两种情况是: -1. Define a local data property that uses the prop's initial value as its initial value; +1. 定义一个本地数据,并且将 prop 的初始值设为本地数据的初始值。 -2. Define a computed property that is computed from the prop's value. +2. 定义一个基于 prop 值的计算属性。 -

      Note that objects and arrays in JavaScript are passed by reference, so if the prop is an array or object, mutating the object or array itself inside the child **will** affect parent state.

      +

      注意在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它**会影响**父组件的状态。

      -### Prop Validation +### Prop 验证 -It is possible for a component to specify requirements for the props it is receiving. If a requirement is not met, Vue will emit warnings. This is especially useful when you are authoring a component that is intended to be used by others. +组件可以为 props 指定验证要求。如果未指定验证要求,Vue会发出警告。当组件给其他人使用时这很有用。 -Instead of defining the props as an array of strings, you can use an object with validation requirements: +prop 是一个对象而不是字符串数组时,它包含验证要求: ``` js Vue.component('example', { props: { - // basic type check (`null` means accept any type) + // 基础类型检测 (`null` 意思是任何类型都可以) propA: Number, - // multiple possible types + // 多种类型 propB: [String, Number], - // a required string + // 必须且是字符串 propC: { type: String, required: true }, - // a number with default value + // 数字,有默认值 propD: { type: Number, default: 100 }, - // object/array defaults should be returned from a - // factory function + // 数组/对象的默认值应当由一个工厂函数返回 propE: { type: Object, default: function () { return { message: 'hello' } } }, - // custom validator function + // 自定义验证函数 propF: { validator: function (value) { return value > 10 @@ -404,7 +402,7 @@ Vue.component('example', { }) ``` -The `type` can be one of the following native constructors: +`type` 可以是下面原生构造器: - String - Number @@ -413,24 +411,24 @@ The `type` can be one of the following native constructors: - Object - Array -In addition, `type` can also be a custom constructor function and the assertion will be made with an `instanceof` check. +`type` 也可以是一个自定义构造器,使用 `instanceof` 检测。 -When a prop validation fails, Vue will produce a console warning (if using the development build). +当 prop 验证失败了, Vue 将拒绝在子组件上设置此值,如果使用的是开发版本会抛出一条警告。 -## Custom Events +## 自定义事件 -We have learned that the parent can pass data down to the child using props, but how do we communicate back to the parent when something happens? This is where custom events come in. +我们知道,父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,应该怎样做?那就是自定义事件! -### Using `v-on` with Custom Events +### 使用 `v-on` 绑定自定义事件 -Every Vue instance implements the [Events interface](/api/#Instance-Methods-Events), which means it can: +每个 Vue 实例都实现了事件接口 [Events interface](/api/#Instance-Methods-Events),即: -- Listen to an event using `$on(eventName)` -- Trigger an event using `$emit(eventName)` +- 使用 `$on(eventName)` 监听事件 +- 使用 `$emit(eventName)` 触发事件 -In addition, a parent component can listen to the events emitted from a child component using `v-on` directly in the template where the child component is used. +另外,父组件可以在使用子组件的地方直接用 `v-on` 来监听子组件触发的事件。 -Here's an example: +下面是一个例子: ``` html
      @@ -504,42 +502,42 @@ new Vue({ {% endraw %} -In this example, it's important to note that the child component is still completely decoupled from what happens outside of it. All it does is report information about its own activity, just in case a parent component might care. +在本例中,子组件已经和它外部完全解耦了。它所做的只是触发一个父组件关心的内部事件。 -#### Binding Native Events to Components +#### 给组件绑定原生事件 -There may be times when you want to listen for a native event on the root element of a component. In these cases, you can use the `.native` modifier for `v-on`. For example: +有时候,你可能想在某个组件的根元素上监听一个原生事件。可以使用 `.native` 修饰 `v-on` 。例如: ``` html ``` -### Form Input Components using Custom Events +### 使用自定义事件的表单输入组件 -This strategy can also be used to create custom form inputs that work with `v-model`. Remember: +自定义事件也可以用来创建自定义的表单输入组件,使用 `v-model` 来进行数据双向绑定。记住,表单控件进行数据绑定时的语法: ``` html ``` -is just syntactic sugar for: +仅仅是一个语法糖: ``` html ``` -When used with a component, this simplifies to: +所以在组件中使用时,它相当于下面的简写: ``` html ``` -So for a component to work with `v-model`, it must: +所以要让组件的 `v-model` 生效,它必须: -- accept a `value` prop -- emit an `input` event with the new value +- 接受一个 `value` 属性 +- 在有新的 value 时触发 `input` 事件 -Let's see it in action: +实战看看: ``` html
      @@ -617,7 +615,7 @@ new Vue({ {% endraw %} -This interface can be used not only to connect with form inputs inside a component, but also to easily integrate input types that you invent yourself. Imagine these possibilities: +这个接口不仅仅可以用来连接组件内部的表单输入,也很容易集成你自己创造的输入类型。想象一下: ``` html @@ -625,29 +623,29 @@ This interface can be used not only to connect with form inputs inside a compone ``` -### Non Parent-Child Communication +### 非父子组件通信 -Sometimes two components may need to communicate with one-another but they are not parent/child to each other. In simple scenarios, you can use an empty Vue instance as a central event bus: +有时候非父子关系的组件也需要通信。在简单的场景下,使用一个空的 Vue 实例作为中央事件总线: ``` js var bus = new Vue() ``` ``` js -// in component A's method +// 触发组件 A 中的事件 bus.$emit('id-selected', 1) ``` ``` js -// in component B's created hook +// 在组件 B 创建的钩子中监听事件 bus.$on('id-selected', function (id) { // ... }) ``` -In more complex cases, you should consider employing a dedicated [state-management pattern](/guide/state-management.html). +在更多复杂的情况下,你应该考虑使用专门的 [状态管理模式](/guide/state-management.html). -## Content Distribution with Slots +## 使用 Slots 分发内容 -When using components, it is often desired to compose them like this: +在使用组件时,常常要像这样组合它们: ``` html @@ -656,17 +654,17 @@ When using components, it is often desired to compose them like this: ``` -There are two things to note here: +注意两点: -1. The `` component does not know what content may be present inside its mount target. It is decided by whatever parent component that is using ``. +1. `` 组件不知道它的挂载点会有什么内容。挂载点的内容是由``的父组件决定的。 -2. The `` component very likely has its own template. +2. `` 组件很可能有它自己的模版。 -To make the composition work, we need a way to interweave the parent "content" and the component's own template. This is a process called **content distribution** (or "transclusion" if you are familiar with Angular). Vue.js implements a content distribution API that is modeled after the current [Web Components spec draft](https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Slots-Proposal.md), using the special `` element to serve as distribution outlets for the original content. +为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个处理称为 **内容分发** (或 "transclusion" 如果你熟悉 Angular)。Vue.js 实现了一个内容分发 API ,参照了当前 [Web组件规范草案](https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Slots-Proposal.md),使用特殊的 `` 元素作为原始内容的插槽。 -### Compilation Scope +### 编译作用域 -Before we dig into the API, let's first clarify which scope the contents are compiled in. Imagine a template like this: +在深入内容分发 API 之前,我们先明确内容的编译作用域。假定模板为: ``` html @@ -674,24 +672,24 @@ Before we dig into the API, let's first clarify which scope the contents are com ``` -Should the `message` be bound to the parent's data or the child data? The answer is the parent. A simple rule of thumb for component scope is: +`message` 应该绑定到父组件的数据,还是绑定到子组件的数据?答案是父组件。组件作用域简单地说是: -> Everything in the parent template is compiled in parent scope; everything in the child template is compiled in child scope. +父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。 -A common mistake is trying to bind a directive to a child property/method in the parent template: +一个常见错误是试图在父组件模板内将一个指令绑定到子组件的属性/方法: ``` html - + ``` -Assuming `someChildProperty` is a property on the child component, the example above would not work. The parent's template is not aware of the state of a child component. +假定 `someChildProperty` 是子组件的属性,上例不会如预期那样工作。父组件模板不应该知道子组件的状态。 -If you need to bind child-scope directives on a component root node, you should do so in the child component's own template: +如果要绑定子组件内的指令到一个组件的根节点,应当在它的模板内这么做: ``` js Vue.component('child-component', { - // this does work, because we are in the right scope +  // 有效,因为是在正确的作用域内 template: '
      Child
      ', data: function () { return { @@ -701,27 +699,26 @@ Vue.component('child-component', { }) ``` -Similarly, distributed content will be compiled in the parent scope. +类似地,分发内容是在父组件作用域内编译。 -### Single Slot +### 单个 Slot -Parent content will be **discarded** unless the child component template contains at least one `` outlet. When there is only one slot with no attributes, the entire content fragment will be inserted at its position in the DOM, replacing the slot itself. +除非子组件模板中包含``,否则父组件的内容将会被**抛弃**。如果子组件模板只有一个没有特性的 slot,父组件整个内容片段将插到 slot 所在的 DOM 位置并替换掉 slot 标签。 -Anything originally inside the `` tags is considered **fallback content**. Fallback content is compiled in the child scope and will only be displayed if the hosting element is empty and has no content to be inserted. +`` 标签的内容视为**回退内容**。回退内容在子组件的作用域内编译,当宿主元素为空并且没有内容供插入时显示这个回退内容。 -Suppose we have a component called `my-component` with the following template: +假定 `my-component` 组件有下面模板: ``` html

      I'm the child title

      - This will only be displayed if there is no content - to be distributed. + 如果没有分发内容则显示我。
      ``` -And a parent that uses the component: +父组件模版: ``` html
      @@ -733,7 +730,7 @@ And a parent that uses the component:
      ``` -The rendered result will be: +渲染结果: ``` html
      @@ -746,13 +743,13 @@ The rendered result will be:
      ``` -### Named Slots +### 具名Slots -`` elements have a special attribute, `name`, which can be used to further customize how content should be distributed. You can have multiple slots with different names. A named slot will match any element that has a corresponding `slot` attribute in the content fragment. +`` 元素可以用一个特殊的属性 `name` 来配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 `slot` 特性的元素。 -There can still be one unnamed slot, which is the **default slot** that serves as a catch-all outlet for any unmatched content. If there is no default slot, unmatched content will be discarded. +仍然可以有一个匿名 slot ,它是**默认 slot** ,作为找不到匹配的内容片段的回退插槽。如果没有默认的 slot ,这些找不到匹配的内容片段将被抛弃。 -For example, suppose we have an `app-layout` component with the following template: +例如,假定我们有一个 `app-layout` 组件,它的模板为: ``` html
      @@ -768,7 +765,7 @@ For example, suppose we have an `app-layout` component with the following templa
      ``` -Parent markup: +父组件模版: ``` html @@ -781,7 +778,7 @@ Parent markup: ``` -The rendered result will be: +渲染结果为: ``` html
      @@ -798,11 +795,11 @@ The rendered result will be:
      ``` -The content distribution API is a very useful mechanism when designing components that are meant to be composed together. +在组合组件时,内容分发 API 是非常有用的机制。 -## Dynamic Components +## 动态组件 -You can use the same mount point and dynamically switch between multiple components using the reserved `` element and dynamically bind to its `is` attribute: +多个组件可以使用同一个挂载点,然后动态地在它们之间切换。使用保留的 `` 元素,动态地绑定到它的 `is` 特性: ``` js var vm = new Vue({ @@ -820,11 +817,11 @@ var vm = new Vue({ ``` html - + ``` -If you prefer, you can also bind directly to component objects: +也可以直接绑定到组件对象上: ``` js var Home = { @@ -841,33 +838,33 @@ var vm = new Vue({ ### `keep-alive` -If you want to keep the switched-out components in memory so that you can preserve their state or avoid re-rendering, you can wrap a dynamic component in a `` element: +如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 `keep-alive` 指令参数: ``` html - + ``` -Check out more details on `` in the [API reference](/api/#keep-alive). +在[API reference](/api/#keep-alive)查看更多 `` 的细节。 -## Misc +## 杂项 -### Authoring Reusable Components +### 编写可复用组件 -When authoring components, it's good to keep in mind whether you intend to reuse it somewhere else later. It's OK for one-off components to be tightly coupled, but reusable components should define a clean public interface and make no assumptions about the context it's used in. +在编写组件时,记住是否要复用组件有好处。一次性组件跟其它组件紧密耦合没关系,但是可复用组件应当定义一个清晰的公开接口。 -The API for a Vue component comes in three parts - props, events, and slots: +Vue 组件 API 来自三部分—— props , events ,和 slots : -- **Props** allow the external environment to pass data into the component +- **Props** 允许外部环境传递数据给组件 -- **Events** allow the component to trigger side effects in the external environment +- **Events** 允许组件触发外部环境的副作用 -- **Slots** allow the external environment to compose the component with extra content. +- **Slots** 允许外部环境将额外的内容组合在组件中。 -With the dedicated shorthand syntaxes for `v-bind` and `v-on`, the intents can be clearly and succinctly conveyed in the template: +使用 `v-bind` 和 `v-on` 的简写语法,模板的缩进清楚且简洁: ``` html ``` -### Child Component Refs +### 子组件索引 -Despite the existence of props and events, sometimes you might still need to directly access a child component in JavaScript. To achieve this you have to assign a reference ID to the child component using `ref`. For example: +尽管有 props 和 events ,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 `ref` 为子组件指定一个索引 ID 。例如: ``` html
      @@ -893,17 +890,17 @@ Despite the existence of props and events, sometimes you might still need to dir ``` js var parent = new Vue({ el: '#parent' }) -// access child component instance +// 访问子组件 var child = parent.$refs.profile ``` -When `ref` is used together with `v-for`, the ref you get will be an array or an object containing the child components mirroring the data source. +当 `ref` 和 `v-for` 一起使用时, ref 是一个数组或对象,包含相应的子组件。 -

      `$refs` are only populated after the component has been rendered, and it is not reactive. It is only meant as an escape hatch for direct child manipulation - you should avoid using `$refs` in templates or computed properties.

      +

      `$refs` 只在组件渲染完成后才填充,并且它是非响应式的。它仅仅作为一个直接访问子组件的应急方案——应当避免在模版或计算属性中使用 `$refs` 。

      -### Async Components +### 异步组件 -In large applications, we may need to divide the app into smaller chunks and only load a component from the server when it's actually needed. To make that easier, Vue allows you to define your component as a factory function that asynchronously resolves your component definition. Vue will only trigger the factory function when the component actually needs to be rendered and will cache the result for future re-renders. For example: +在大型应用中,我们可能需要将应用拆分为多个小模块,按需从服务器下载。为了让事情更简单, Vue.js 允许将组件定义为一个工厂函数,动态地解析组件的定义。Vue.js 只在组件需要渲染时触发工厂函数,并且把结果缓存起来,用于后面的再次渲染。例如: ``` js Vue.component('async-example', function (resolve, reject) { @@ -915,18 +912,18 @@ Vue.component('async-example', function (resolve, reject) { }) ``` -The factory function receives a `resolve` callback, which should be called when you have retrieved your component definition from the server. You can also call `reject(reason)` to indicate the load has failed. The `setTimeout` here is simply for demonstration; How to retrieve the component is entirely up to you. One recommended approach is to use async components together with [Webpack's code-splitting feature](http://webpack.github.io/docs/code-splitting.html): +工厂函数接收一个 `resolve` 回调,在收到从服务器下载的组件定义时调用。也可以调用 `reject(reason)` 指示加载失败。这里 `setTimeout` 只是为了演示。怎么获取组件完全由你决定。推荐配合使用 :[Webpack 的代码分割功能](http://webpack.github.io/docs/code-splitting.html): ``` js Vue.component('async-webpack-example', function (resolve) { - // This special require syntax will instruct Webpack to - // automatically split your built code into bundles which - // are loaded over Ajax requests. + // 这个特殊的 require 语法告诉 webpack + // 自动将编译后的代码分割成不同的块, + // 这些块将通过 Ajax 请求自动下载。 require(['./my-async-component'], resolve) }) ``` -You can also return a `Promise` in the resolve function, so with Webpack 2 + ES2015 syntax you can do: +你可以使用 Webpack 2 + ES2015 的语法返回一个 `Promise` resolve 函数: ``` js Vue.component( @@ -935,77 +932,77 @@ Vue.component( ) ``` -

      If you're a Browserify user that would like to use async components, it's unfortunately not possible and probably never will be, as its creator has [made it clear](https://github.com/substack/node-browserify/issues/58#issuecomment-21978224) that async loading "is not something that Browserify will ever support." If this is a feature that's important to you, we recommend using Webpack instead.

      +

      如果你是Browserify用户,可能就无法使用异步组件了,它的作者已经[表明](https://github.com/substack/node-browserify/issues/58#issuecomment-21978224) Browserify 是不支持异步加载的。如果这个功能对你很重要,请使用 Webpack。

      -### Component Naming Conventions +### 组件命名约定 -When registering components (or props), you can use kebab-case, camelCase, or TitleCase. Vue doesn't care. +当注册组件时(或者 props ),可以使用 kebab-case ,camelCase ,或 TitleCase 。Vue 不关心这个。 ``` js -// in a component definition +// 在组件定义中 components: { - // register using camelCase + // 使用 camelCase 形式注册 'kebab-cased-component': { /* ... */ }, 'camelCasedComponent': { /* ... */ }, 'TitleCasedComponent': { /* ... */ } } ``` -Within HTML templates though, you have to use the kebab-case equivalents: +在 HTML 模版中,请使用 kebab-case形式: ``` html - + ``` -When using _string_ templates however, we're not bound by HTML's case-insensitive restrictions. That means even in the template, you reference your components and props using camelCase, PascalCase, or kebab-case: +当使用字符串模式时,可以不受 HTML 的 case-insensitive 限制。这意味即使是在模版中,引用、组件和 prop 可以使用 camelCase 、 PascalCase 或者 kebab-case: ``` html - + ``` -If your component isn't passed content via `slot` elements, you can even make it self-closing with a `/` after the name: +如果组件未经 `slot` 元素传递内容,你甚至可以在组件名后使用 `/` 使其自闭合: ``` html ``` -Again, this _only_ works within string templates, as self-closing custom elements are not valid HTML and your browser's native parser will not understand them. +当然,这只在字符串模版中有效。因为自闭的自定义元素是无效的 HTML ,浏览器原生的解析器也无法识别它。 -### Recursive Component +### 递归组件 -Components can recursively invoke themselves in their own template. However, they can only do so with the `name` option: +组件在它的模板内可以递归地调用自己,不过,只有当它有 name 选项时才可以: ``` js name: 'stack-overflow', template: '
      ' ``` -A component like the above will result in a "max stack size exceeded" error, so make sure recursive invocation is conditional (i.e. uses a `v-if` that will eventually be false). When you register a component globally using `Vue.component`, the global ID is automatically set as the component's `name` option. +上面组件会导致一个错误 “max stack size exceeded” ,所以要确保递归调用有终止条件 (比如递归调用时使用 `v-if` 并让他最终返回 false )。当使用 `Vue.component()` 全局注册一个组件时,全局的组件 ID 自动设置为该组件的 `name` 选项。 -### Inline Templates +### 内联模版 -When the `inline-template` special attribute is present on a child component, the component will use its inner content as its template, rather than treating it as distributed content. This allows more flexible template-authoring. +如果子组件有 inline-template 特性,组件将把它的内容当作它的模板,而不是把它当作分发内容。这让模板更灵活。 ``` html

      These are compiled as the component's own template.

      Not parent's transclusion content.

      -
      +
      ``` -However, `inline-template` makes the scope of your templates harder to reason about. As a best practice, prefer defining templates inside the component using the `template` option or in a `template` element in a `.vue` file. +但是 inline-template 让模板的作用域难以理解。最佳实践是使用 template 选项在组件内定义模板或者在 `.vue` 文件中使用 `template` 元素。 ### X-Templates -Another way to define templates is inside of a script element with the type `text/x-template`, then referencing the template by an id. For example: +另一种定义模版的方式是在 JavaScript 标签里使用 `text/x-template` 类型,并且指定一个id。例如: ``` html {% endraw %} -Here we have declared a computed property `reversedMessage`. The function we provided will be used as the getter function for the property `vm.reversedMessage`: + +这里我们声明了一个计算属性 `reversedMessage` 。我们提供的函数将用作属性 `vm.reversedMessage` 的 getter 。 ``` js console.log(vm.reversedMessage) // -> 'olleH' @@ -73,13 +76,13 @@ vm.message = 'Goodbye' console.log(vm.reversedMessage) // -> 'eybdooG' ``` -You can open the console and play with the example vm yourself. The value of `vm.reversedMessage` is always dependent on the value of `vm.message`. +你可以打开浏览器的控制台,修改 vm 。 `vm.reversedMessage` 的值始终取决于 `vm.message` 的值。 -You can data-bind to computed properties in templates just like a normal property. Vue is aware that `vm.reversedMessage` depends on `vm.message`, so it will update any bindings that depend on `vm.reversedMessage` when `vm.message` changes. And the best part is that we've created this dependency relationship declaratively: the computed getter function is pure and has no side effects, which makes it easy to test and reason about. +你可以像绑定普通属性一样在模板中绑定计算属性。 Vue 知道 `vm.reversedMessage` 依赖于 `vm.message` ,因此当 `vm.message` 发生改变时,依赖于 `vm.reversedMessage` 的绑定也会更新。而且最妙的是我们是声明式地创建这种依赖关系:计算属性的 getter 是干净无副作用的,因此也是易于测试和理解的。 -### Computed Caching vs Methods +### 计算缓存 vs Methods -You may have noticed we can achieve the same result by invoking a method in the expression: +你可能已经注意到我们可以通过调用表达式中的method来达到同样的效果: ``` html

      Reversed message: "{{ reverseMessage() }}"

      @@ -94,9 +97,9 @@ methods: { } ``` -Instead of a computed property, we can define the same function as a method instead. For the end result, the two approaches are indeed exactly the same. However, the difference is that **computed properties are cached based on its dependencies.** A computed property will only re-evaluate when some of its dependencies have changed. This means as long as `message` has not changed, multiple access to the `reversedMessage` computed property will immediately return the previously computed result without having to run the function again. +不经过计算属性,我们可以通过定义一个method来替代它。对于最终的结果,两种方式确实是相同的。然而,不同的是**计算缓存基于它的相关依赖**。计算属性只有在它的相关依赖发生改变时才会重新评估。这就意味着如果 `message` 没有发生改变,多次访问 `reversedMessage` 计算属性会立即返回之前的结果,而不必运行函数。 -This also means the following computed property will never update, because `Date.now()` is not a reactive dependency: +这也同样意味着如下计算属性将不会更新,因为 `Date.now()` 并不会被依赖: ``` js computed: { @@ -106,13 +109,13 @@ computed: { } ``` -In comparison, a method invocation will **always** run the function whenever a re-render happens. +相比而言,每当重新渲染的时候,method调用**总会**运行函数。 -Why do we need caching? Imagine we have an expensive computed property **A**, which requires looping through a huge Array and doing a lot of computations. Then we may have other computed properties that in turn depend on **A**. Without caching, we would be executing **A**’s getter many more times than necessary! In cases where you do not want caching, use a method instead. +我们为什么需要缓存?假设我们有一个重要的计算属性 **A** ,这个计算属性需要一个巨大的数组遍历和做大量的计算。然后我们可能有其他的计算属性依赖于 **A** 。如果没有缓存,我们将执行多次 **A** 的 getter ,然而这都是不必要的!如果你不希望有缓存,请用method替代。 -### Computed vs Watched Property +### 计算属性 vs Watched Property -Vue does provide a more generic way to observe and react to data changes on a Vue instance: **watch properties**. When you have some data that needs to change based on some other data, it is tempting to overuse `watch` - especially if you are coming from an AngularJS background. However, it is often a better idea to use a computed property rather than an imperative `watch` callback. Consider this example: +Vue.js 提供了一个方法 `$watch` ,它用于观察 Vue 实例上的数据变动。当一些数据需要根据其它数据变化时, `$watch` 很诱人 —— 特别是如果你来自 AngularJS 。不过,通常更好的办法是使用计算属性而不是一个命令式的 `$watch` 回调。思考下面例子: ``` html
      {{ fullName }}
      @@ -137,7 +140,7 @@ var vm = new Vue({ }) ``` -The above code is imperative and repetitive. Compare it with a computed property version: +上面代码是命令式的重复的。跟计算属性对比: ``` js var vm = new Vue({ @@ -154,11 +157,11 @@ var vm = new Vue({ }) ``` -Much better, isn't it? +这样更好,不是吗? -### Computed Setter +### 计算 setter -Computed properties are by default getter-only, but you can also provide a setter when you need it: +计算属性默认只是 getter ,不过在需要时你也可以提供一个 setter : ``` js // ... @@ -179,15 +182,15 @@ computed: { // ... ``` -Now when you run `vm.fullName = 'John Doe'`, the setter will be invoked and `vm.firstName` and `vm.lastName` will be updated accordingly. +现在在调用 `vm.fullName = 'John Doe'` 时, setter 会被调用, `vm.firstName` 和 `vm.lastName` 也会有相应更新。 -## Watchers +## 观察 Watchers -While computed properties are more appropriate in most cases, there are times when a custom watcher is necessary. That's why Vue provides a more generic way to react to data changes through the `watch` option. This is most useful when you want to perform asynchronous or expensive operations in response to changing data. +当计算属性使用在大多数场景下时,有时候也很需要一个自定义的 watcher 。这是为什么 Vue 提供一个更通用的方法通过 `watch` 的设置,来反应数据的变化。在你想要执行异步操作或需要响应不断变化昂贵的数据操作时这很有用。 -For example: +例如: -``` html +```html

      Ask a yes/no question: @@ -197,7 +200,7 @@ For example:

      ``` -``` html +```html @@ -212,20 +215,18 @@ var watchExampleVM = new Vue({ answer: 'I cannot give you an answer until you ask a question!' }, watch: { - // whenever question changes, this function will run +   // 如果 question 发生改变,这个函数就会运行 question: function (newQuestion) { this.answer = 'Waiting for you to stop typing...' this.getAnswer() } }, methods: { - // _.debounce is a function provided by lodash to limit how - // often a particularly expensive operation can be run. - // In this case, we want to limit how often we access - // yesno.wtf/api, waiting until the user has completely - // finished typing before making the ajax request. To learn - // more about the _.debounce function (and its cousin - // _.throttle), visit: https://lodash.com/docs#debounce +   // _.debounce 是一个通过 lodash 限制操作频率的函数。 +   // 在这个例子中,我们希望限制访问yesno.wtf/api的频率 +   // ajax请求直到用户输入完毕才会发出 +   // 学习更多关于 _.debounce function (and its cousin + // _.throttle), 参考: https://lodash.com/docs#debounce getAnswer: _.debounce( function () { var vm = this @@ -242,8 +243,7 @@ var watchExampleVM = new Vue({ vm.answer = 'Error! Could not reach the API. ' + error }) }, - // This is the number of milliseconds we wait for the - // user to stop typing. + // 这是我们为用户停止输入等待的毫秒数 500 ) } @@ -251,10 +251,11 @@ var watchExampleVM = new Vue({ ``` -Result: + +结果: {% raw %} -
      +

      Ask a yes/no question: @@ -271,6 +272,7 @@ var watchExampleVM = new Vue({ answer: 'I cannot give you an answer until you ask a question!' }, watch: { + // 如果 question 发生改变,这个函数就会运行 question: function (newQuestion) { this.answer = 'Waiting for you to stop typing...' this.getAnswer() @@ -293,6 +295,7 @@ var watchExampleVM = new Vue({ vm.answer = 'Error! Could not reach the API. ' + error }) }, + // 这是我们为用户停止输入等待的毫秒数 500 ) } @@ -300,6 +303,13 @@ var watchExampleVM = new Vue({ {% endraw %} -In this case, using the `watch` option allows us to perform an asynchronous operation (accessing an API), limit how often we perform that operation, and set intermediary states until we get a final answer. None of that would be possible with a computed property. +在这个示例中,使用 `watch` 的设置允许我们执行异步操作(访问一个接口),限制我们多久执行该操作,并在我们获取最终结果时立刻设置状态。这是计算属性无法做到的。 + +关于 `watch` 选项,可看API文档[vm.$watch API](/api/#vm-watch)。 + +*** + +> 原文:http://vuejs.org/guide/computed.html + +*** -In addition to the `watch` option, you can also use the imperative [vm.$watch API](/api/#vm-watch). diff --git a/src/guide/conditional.md b/src/guide/conditional.md index 7c8166aa59..796f15af97 100644 --- a/src/guide/conditional.md +++ b/src/guide/conditional.md @@ -1,36 +1,36 @@ --- -title: Conditional Rendering +title: 条件渲染 type: guide order: 7 --- ## v-if -In string templates, for example Handlebars, we would write a conditional block like this: +在字符串模板中,如 Handlebars ,我们得像这样写一个条件块: ``` html - + {{#if ok}}

      Yes

      {{/if}} ``` -In Vue, we use the `v-if` directive to achieve the same: +在 Vue.js ,我们使用 `v-if` 指令实现同样的功能: ``` html

      Yes

      ``` -It is also possible to add an "else" block with `v-else`: +也可以用 `v-else` 添加一个 "else" 块: ``` html

      Yes

      No

      ``` -### Template v-if +## template v-if -Because `v-if` is a directive, it has to be attached to a single element. But what if we want to toggle more than one element? In this case we can use `v-if` on a `