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 eb016681d6..d1ce4c343d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,18 @@ -# 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 +> 镜像站: https://vuefe.cn -Start a dev server at `localhost:4000`: +> 贡献者: https://vuefe.cn/about + +## QQ群 + +- vue技术栈1群 `427447379` +- vue技术栈2群 `543234934` +- vue技术栈3群 `305473775` + +### 感谢所有参与翻译的朋友们! ``` $ npm install -g hexo-cli diff --git a/_config.yml b/_config.yml index 7021152df4..460b50c06f 100644 --- a/_config.yml +++ b/_config.yml @@ -3,16 +3,16 @@ ## Source: https://github.com/tommy351/hexo/ # Site -title: Vue.js -subtitle: -description: "The Progressive JavaScript Framework" +title: Vue.js v2 中文文档 +subtitle: Vue.js v2.0 中文文档 vuefe.cn +description: "Vue.js v2.0 中文文档 vuefe.cn vuefe.com" 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: https://vuefe.cn root: / permalink: :year/:month/:day/:title/ tag_dir: tags @@ -95,9 +95,10 @@ markdown: # Deployment ## Docs: http://zespia.tw/hexo/docs/deployment.html -deploy: - type: git - repository: git@github.com:vuejs/vuejs.org.git +# deploy: +# type: git +# repository: git@github.com:vuejs/cn.vuejs.org.git +# branch: gh-pages feed: type: atom diff --git a/package.json b/package.json index 31efd4527e..ad6057c0ea 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,12 @@ { - "name": "vuejs.org", + "name": "cn.vuejs.org", "version": "1.0.18", "private": true, "hexo": { "version": "3.2.2" }, "dependencies": { + "hexo-browsersync": "^0.2.0", "hexo": "^3.2.2", "hexo-deployer-git": "0.1.0", "hexo-generator-alias": "git+https://github.com/chrisvfritz/vuejs.org-hexo-generator-alias.git", diff --git a/src/CNAME b/src/CNAME index 998cc417c8..7d902c3e59 100644 --- a/src/CNAME +++ b/src/CNAME @@ -1 +1 @@ -vuejs.org +vuefe.cn \ No newline at end of file diff --git a/src/about/friend.md b/src/about/friend.md new file mode 100644 index 0000000000..5bcd497039 --- /dev/null +++ b/src/about/friend.md @@ -0,0 +1,13 @@ +--- +title: 友情链接 +type: about +order: 2 +--- + + + + + + + + \ No newline at end of file diff --git a/src/about/guide.md b/src/about/guide.md new file mode 100644 index 0000000000..8a3881f249 --- /dev/null +++ b/src/about/guide.md @@ -0,0 +1,88 @@ +--- +title: 参与指南 +type: about +order: 3 +--- + +## 参与要求 + +### 参与: + +> 参与请阅读 [翻译规范](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 100755 index 0000000000..a97c27f01b --- /dev/null +++ b/src/about/index.md @@ -0,0 +1,82 @@ +--- +title: 贡献者 +type: about +order: 1 +--- + +## 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/about/message.md b/src/about/message.md new file mode 100644 index 0000000000..cd94a8523d --- /dev/null +++ b/src/about/message.md @@ -0,0 +1,13 @@ +--- +title: 留言板 +type: about +order: 0 +--- + +- 我们还需要些什么?暂且来提 issue吧! [点击添加建议](https://github.com/vuefe/vuefe.github.io/issues) + +## QQ群 + +- vue技术栈1群 `427447379` +- vue技术栈2群 `543234934` +- vue技术栈3群 `305473775` \ No newline at end of file diff --git a/src/images/umoon.png b/src/images/umoon.png new file mode 100644 index 0000000000..f59c23f061 Binary files /dev/null and b/src/images/umoon.png differ diff --git a/src/perf/index.md b/src/perf/index.md deleted file mode 100644 index 0c53f0f2e0..0000000000 --- a/src/perf/index.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Performance Comparisons ---- - -## TodoMVC Benchmark - -> *Last Updated: 2014-10-12* - -Looking for the TodoMVC Benchmark? It's been removed because after discussion with some other framework authors we have agreed that: - -1. The original intention of these benchmarks were for comparing Browser performance rather than that of frameworks. The "synchrorously trigger an action xxx times" test routine doesn't reflect meaningful real world user actions. - -2. Due to internal implementation differences, frameworks that uses async rendering (e.g. Vue, Om, Mercury) gains the advantage by skipping part of the calculations that happened in the same event loop. The real world user experience doesn't demonstrate such dramatic difference. - -3. Overall this benchmark suite gave rise to more controversy than constructive insights, so it's been removed and I'd be happy to replace it with a more meaningful way to measure front-end performance. diff --git a/src/support-vuejs/index.md b/src/support-vuejs/index.md index 85fb29429f..c9e1a38003 100644 --- a/src/support-vuejs/index.md +++ b/src/support-vuejs/index.md @@ -1,4 +1,4 @@ -# Support Vue.js Development +# 支持 Vue.js 的开发 @@ -10,7 +10,7 @@ Donate via PayPal (one time) -## Current premium sponsors: +## 当前特级赞助商

@@ -42,11 +42,10 @@

-Vue.js is an MIT licensed open source project and completely free to use. -However, the amount of effort needed to maintain and develop new features for the project is not sustainable without proper financial backing. You can support Vue.js development by [pledging on Patreon](https://www.patreon.com/evanyou) or [donating on PayPal](https://www.paypal.me/evanyou). +Vue.js 是采用 MIT 许可的开源项目,使用完全免费。不过,如果没有资金的支持,维护和开发新功能是不可能持续的。你可以通过 [Patreon](https://www.patreon.com/evanyou) 或 [PayPal](https://www.paypal.me/evanyou) 来赞助。 -If you run a business and are using Vue in a revenue-generating product, it makes business sense to sponsor Vue development: **it ensures the project that your product relies on stays healthy and actively maintained.** It can also help your exposure in the Vue community and makes it easier to attract Vue developers. +如果你是企业经营者并且将 Vue 用在商业产品中,那么赞助 Vue 有商业上的益处:**可以让你的产品保持健康并得到积极的维护**,也能帮助你在 Vue 社区里曝光,从而更容易地吸引到 Vue 开发者。 -If you are a business that is building core products using Vue.js, I am also open to conversations regarding custom sponsorship / consulting arrangements. [Get in touch on Twitter](https://twitter.com/youyuxi). +如果你是企业经营者,并且使用 Vue.js 来开发核心产品,我也可以做顾问。[在 Twitter 上联系我。](https://twitter.com/youyuxi) -If you are an individual user and have enjoyed the productivity of using Vue, consider donating as a sign of appreciation - like buying me coffee once in a while :) +如果你是个人开发者并且享受 Vue 带来的高开发效率,可以用捐助来表示你的谢意——比如间或给我买杯咖啡 :) diff --git a/src/v2/api/index.md b/src/v2/api/index.md index 79c6ed56c3..3ee61e48d0 100644 --- a/src/v2/api/index.md +++ b/src/v2/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. ### ignoredElements -- **Type:** `Array` +- **类型:** `Array` -- **Default:** `[]` +- **默认值:** `[]` -- **Usage:** +- **用法:** ``` js Vue.config.ignoredElements = [ @@ -93,15 +93,15 @@ type: api ] ``` - Make Vue ignore custom elements defined outside of Vue (e.g., using the Web Components APIs). Otherwise, it will throw a warning about an `Unknown custom element`, assuming that you forgot to register a global component or misspelled a component name. + 须使 Vue 忽略在 Vue 之外的自定义元素 (e.g., 使用了 Web Components APIs)。否则,它会假设你忘记注册全局组件或者拼错了组件名称,从而抛出一个关于 `Unknown custom element` 的警告。 ### keyCodes -- **Type:** `{ [key: string]: number | Array }` +- **类型:** `{ [key: string]: number | Array }` -- **Default:** `{}` +- **默认值:** `{}` -- **Usage:** +- **用法:** ``` js Vue.config.keyCodes = { @@ -112,27 +112,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 () { @@ -143,84 +143,84 @@ 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 更新了 }) ``` - > New in 2.1.0: returns a Promise if no callback is provided and Promise is supported in the execution environment. + > 2.1.0新增:如果没有提供回调且支持 promise 的环境中返回 promise。 -- **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 () {}, @@ -229,92 +229,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. Registration also automatically sets the component's `name` with the given `id`. + 注册或获取全局组件。注册还会自动使用给定的`id`设置组件的名称 ``` 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 }}
') @@ -328,7 +328,7 @@ type: api }) ``` -- **See also:** [Render Functions](../guide/render-function.html) +- **参考:** [Render 函数](../guide/render-function.html)

Vue.version

@@ -348,41 +348,42 @@ if (version === 2) { } ``` -## Options / Data +## 选项 / 数据 ### data -- **Type:** `Object | Function` -- **Restriction:** Only accepts `Function` when used in a component definition. +- **类型:** `Object | Function` -- **Details:** +- **限制:** 组件的定义只接受 `function`。 - 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. +- **详细:** - 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. + Vue 实例的数据对象。Vue 将会递归将 data 的属性转换为 getter/setter,从而让 data 的属性能够响应数据变化。**对象必须是纯粹的对象(含有零个或多个的key/value对)**:浏览器 API 创建的原生对象,原型上的属性会被忽略。大概来说,data 应该只能是数据 - 不推荐观察拥有状态行为的对象。 - 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`. + 一旦观察过,不需要再次在数据对象上添加响应式属性。因此推荐在创建实例之前,就声明所有的根级响应式属性。 - 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`. + 实例创建之后,可以通过 `vm.$data` 访问原始数据对象。Vue 实例也代理了 data 对象上所有的属性,因此访问 `vm.a` 等价于访问 `vm.$data.a`。 - 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. + 以 `_` 或 `$` 开头的属性 **不会** 被 Vue 实例代理,因为它们可能和 Vue 内置的属性、 API 方法冲突。你可以使用例如 `vm.$data._property` 的方式访问这些属性。 - If required, a deep clone of the original object can be obtained by passing `vm.$data` through `JSON.parse(JSON.stringify(...))`. + 当一个**组件**被定义, `data` 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 `data` 仍然是一个纯粹的对象,则所有的实例将**共享引用**同一个数据对象!通过提供 `data` 函数,每次创建一个新实例后,我们能够调用 `data` 函数,从而返回初始数据的一个全新副本数据对象。 -- **Example:** + 如果需要,可以通过将 `vm.$data` 传入 `JSON.parse(JSON.stringify(...))` 得到深拷贝的原始数据对象。 + +- **示例:** ``` 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 } @@ -390,32 +391,32 @@ if (version === 2) { }) ``` -

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, @@ -428,19 +429,19 @@ if (version === 2) { }) ``` -- **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({ @@ -454,30 +455,31 @@ if (version === 2) { } }) ``` +- **参考:** [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. Note that if a certain dependency is out of the instance's scope (i.e. not reactive), the computed property will __not__ be updated. -- **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 @@ -494,20 +496,20 @@ if (version === 2) { 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({ @@ -522,17 +524,17 @@ if (version === 2) { 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({ @@ -545,9 +547,9 @@ if (version === 2) { 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 @@ -557,246 +559,247 @@ if (version === 2) { 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. + 提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例。 - 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](./) to learn enough to build non-trivial applications. +由于起步阶段不需学 JSX、ES2015 以及构建系统,所以开发者只需不到一天的时间阅读[指南](./)就可以建立简单的应用程序。 -### Native Rendering +### 本地渲染 -React Native 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 能使你用相同的 React 组件模型编写有本地渲染能力的 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 React Native, 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 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 + +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 早期开发的灵感来源。然而,Angular 中存在的许多问题,在 Vue 中已经得到解决。 + +### 复杂性 -### Complexity +在 API 与设计两方面上 Vue.js 都比 Angular 1 简单得多,因此你可以快速地掌握它的全部特性并投入开发。 -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. +### 灵活性和模块化 -### Flexibility and Modularity +Vue.js 是一个更加灵活开放的解决方案。它允许你以希望的方式组织应用程序,而不是在任何时候都必须遵循 Angular 1 制定的规则,这让 Vue 能适用于各种项目。我们知道把决定权交给你是非常必要的。 -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. +这也就是为什么我们提供 [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 中,当 watchers 越来越多时会变得越来越慢,因为作用域内的每一次变化,所有 watchers 都要重新计算。并且,如果一些 watchers 触发另一个更新,脏检查循环(digest cycle)可能要运行多次。Angular 用户常常要使用深奥的技术,以解决脏检查循环的问题。有时没有简单的办法来优化有大量 watchers 的作用域。 -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. +我们单独将 Angular 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 [official decorator](https://github.com/vuejs/vue-class-component), 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 相比 Angular 2 是更快的。 -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 和离线编译技术使代码体积减小了许多。但包含编译器和全部功能的 Vue 2(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](./). +开始使用 Vue,你使用的是熟悉的 HTML、符合 ES5 规则的 JavaScript(也就是纯 JavaScript)。有了这些基本的技能,你可以快速地掌握它([指南](./))并投入开发 。 -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 wouldn't be an exaggeration to say that [Vue's Hello World](https://jsfiddle.net/chrisvfritz/50wL7mdz/) is a little bit simpler. Maybe because of that, we don't even need to 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](https://jsfiddle.net/chrisvfritz/50wL7mdz/) 就非常简单。甚至我们并不用花费一整个页面去介绍它。 ## 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.10.0/templates/handlebars-basics/) and [object model](https://guides.emberjs.com/v2.10.0/object-model/) layers: +也就是说,我们最好比较的是 Vue 内核和 Ember 的[模板](https://guides.emberjs.com/v2.10.0/templates/handlebars-basics/)与[数据模型](https://guides.emberjs.com/v2.10.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 来工作。 -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 1.0 版本中,为了弥补性能,开发团队限制了数据绑定系统的使用。例如,在 Polymer 中唯一支持的表达式只有布尔值否定和单一的方法调用,它的 computed 方法的实现也并不是很灵活。 -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 文件中创建的,这限制了 JavaScript/CSS(以及被现代浏览器普遍支持的语言特性)的使用。相比之下,Vue 的单文件组件允许你非常容易的使用 ES2015 和你想用的 CSS 预编译处理器。 -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. +在部署生产环境时,Polymer 建议使用 HTML Imports 加载所有资源。而这要求服务器和客户端都支持 Http 2.0 协议,并且浏览器实现了此标准。这是否可行就取决于你的目标用户和部署环境了。如果状况不佳,你必须用 Vulcanizer 工具来打包 Polymer 元素。而在这方面,Vue 可以结合异步组件的特性和 Webpack 的代码分割特性来实现懒加载(lazy-loaded)。这确保了对旧浏览器的兼容,同时保留了良好的加载速度。 -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 还是有很多显著优势的: + +- [过渡效果系统](transitions.html)。Riot 现在还没有提供。 +- 功能更加强大的路由机制。Riot 路由的 API 非常轻量。 +- 更好的性能。Riot 使用了[遍历 DOM 树](http://riotjs.com/compare/#virtual-dom-vs-expressions-binding)而不是 Virtual DOM,但实际上用的还是脏检查机制,因此和 Angular 1 患有相同的性能问题。 +- 更多成熟工具的支持。Vue 提供官方的 [Webpack](https://github.com/vuejs/vue-loader) 和 [Browserify](https://github.com/vuejs/vueify) 支持,而 Riot 依赖社区支持来构建系统集成。 + +*** + +> 原文:http://vuejs.org/guide/comparison.html -- [Transition effect system](transitions.html). Riot has none. -- A far more powerful router. Riot’s routing API is extremely minimal. -- Better performance. Riot [traverses a DOM tree](http://riotjs.com/compare/#virtual-dom-vs-expressions-binding) rather than using a virtual DOM, so suffers from the same performance issues as Angular 1. -- More mature tooling support. Vue provides official support for [Webpack](https://github.com/vuejs/vue-loader) and [Browserify](https://github.com/vuejs/vueify), while Riot relies on community support for build system integration. +*** diff --git a/src/v2/guide/components.md b/src/v2/guide/components.md index a2c8028938..525fb849b2 100644 --- a/src/v2/guide/components.md +++ b/src/v2/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 元素的形式,以 js 特性扩展。 -## 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: +不必在全局注册每个组件。通过使用组件实例选项注册,可以使组件仅在另一个实例/组件的作用域中可用: ``` 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. +这种封装也适用于其它可注册的 Vue 功能,如指令。 -### 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,41 +212,41 @@ 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

      -## Props +## Prop -### Passing Data with Props +### 使用 Prop 传递数据 -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 特性是不区分大小写的。所以,当使用非字符串模版时,camelCased (驼峰式) 命名的 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 +### 动态 Prop -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,37 +326,37 @@ 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. 定义一个局部 data 属性,并将 prop 的初始值作为局部数据的初始值。 ``` js props: ['initialCounter'], @@ -366,7 +365,7 @@ The proper answer to these use cases are: } ``` -2. Define a computed property that is computed from the prop's value: +2. 定义一个 computed 属性,此属性从 prop 的值计算得出。 ``` js props: ['size'], @@ -377,40 +376,39 @@ The proper answer to these use cases are: } ``` -

      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 @@ -420,7 +418,7 @@ Vue.component('example', { }) ``` -The `type` can be one of the following native constructors: +`type` 可以是下面原生构造器: - String - Number @@ -429,28 +427,26 @@ 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 验证失败了,如果使用的是开发版本会抛出一条警告。 -## 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 Vue's custom event system comes in. +我们知道,父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,应该怎样做?那就是自定义事件! -### Using `v-on` with Custom Events +### 使用 `v-on` 绑定自定义事件 -Every Vue instance implements an [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)` 触发事件 -

      Note that Vue's event system is separate from the browser's [EventTarget API](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget). Though they work similarly, `$on` and `$emit` are __not__ aliases for `addEventListener` and `dispatchEvent`.

      +

      Vue的事件系统分离自浏览器的[EventTarget API](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget)。尽管它们的运行类似,但是`$on` 和 `$emit` __不是__`addEventListener` 和 `dispatchEvent` 的别名。

      -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` 来监听子组件触发的事件。 -

      You cannot use `$on` to listen to events emitted by children. You must use `v-on` directly in the template, as in the example below.

      - -Here's an example: +下面是一个例子: ``` html
      @@ -524,42 +520,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 +### 使用自定义事件的表单输入组件 -Custom events can also be used to create custom 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 with a very simple currency input: +一个非常简单的货币输入: ``` html @@ -567,33 +563,30 @@ Let's see it in action with a very simple currency input: ``` js Vue.component('currency-input', { - template: '\ - \ - $\ - \ - \ + template: ' + + $ + + ', props: ['value'], methods: { - // Instead of updating the value directly, this - // method is used to format and place constraints - // on the input's value + // 不是直接更新值,而是使用此方法来对输入值进行格式化和位数限制 updateValue: function (value) { var formattedValue = value - // Remove whitespace on either side + // 删除两侧的空格符 .trim() - // Shorten to 2 decimal places + // 保留 2 小数位 .slice(0, value.indexOf('.') + 3) - // If the value was not already normalized, - // manually override it to conform + // 如果值不统一,手动覆盖以保持一致 if (formattedValue !== value) { this.$refs.input.value = formattedValue } - // Emit the number value through the input event + // 通过 input 事件发出数值 this.$emit('input', Number(formattedValue)) } } @@ -606,15 +599,15 @@ Vue.component('currency-input', {
      {% endraw %} -The implementation above is pretty naive though. For example, users are allowed to enter multiple periods and even letters sometimes - yuck! So for those that want to see a non-trivial example, here's a more robust currency filter: +上面的实现方式太过理想化了。 比如,用户甚至可以输入多个小数点或句号 - 哦哦!因此我们需要一个更有意义的例子,下面是一个更加完善的货币过滤器: -The events interface can also be used to create more unusual inputs. For example, imagine these possibilities: +这个接口不仅仅可以用来连接组件内部的表单输入,也很容易集成你自己创造的输入类型。想象一下: ``` html @@ -648,29 +641,29 @@ The events interface can also be used to create more unusual inputs. For example ``` -### 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](state-management.html). +在更多复杂的情况下,你应该考虑使用专门的 [状态管理模式](state-management.html). -## Content Distribution with Slots +## 使用 Slot 分发内容 -When using components, it is often desired to compose them like this: +在使用组件时,常常要像这样组合它们: ``` html @@ -679,17 +672,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 @@ -697,24 +690,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 { @@ -724,58 +717,57 @@ 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
      -

      I'm the parent title

      +

      我是父组件的标题

      -

      This is some original content

      -

      This is some more original content

      +

      这是一些初始内容

      +

      这是更多的初始内容

      ``` -The rendered result will be: +渲染结果: ``` html
      -

      I'm the parent title

      +

      我是父组件的标题

      -

      I'm the child title

      -

      This is some original content

      -

      This is some more original content

      +

      我是子组件的标题

      +

      这是一些初始内容

      +

      这是更多的初始内容

      ``` -### Named Slots +### 具名 Slot -`` 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
      @@ -791,45 +783,46 @@ For example, suppose we have an `app-layout` component with the following templa
      ``` -Parent markup: +父组件模版: ``` html -

      Here might be a page title

      +

      这里可能是一个页面标题

      -

      A paragraph for the main content.

      -

      And another one.

      +

      主要内容的一个段落。

      +

      另一个主要段落。

      -

      Here's some contact info

      +

      这里有一些联系信息

      ``` -The rendered result will be: +渲染结果为: ``` html
      -

      Here might be a page title

      +

      这里可能是一个页面标题

      -

      A paragraph for the main content.

      -

      And another one.

      +

      主要内容的一个段落。

      +

      另一个主要段落。

      -

      Here's some contact info

      +

      这里有一些联系信息

      ``` -The content distribution API is a very useful mechanism when designing components that are meant to be composed together. +在组合组件时,内容分发 API 是非常有用的机制。 + -### Scoped Slots +### 作用域插槽 -> New in 2.1.0 +> 2.1.0 新增 -A scoped slot is a special type of slot that functions as a reusable template (that can be passed data to) instead of already-rendered-elements. +作用域插槽是一种特殊类型的插槽,用作使用一个(能够传递数据到)可重用模板替换已渲染元素。 -In a child component, simply pass data into a slot as if you are passing props to a component: +在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样: ``` html
      @@ -837,7 +830,7 @@ In a child component, simply pass data into a slot as if you are passing props t
      ``` -In the parent, a `