From 2c982fb1d2d608db5ca8719d923bbdd1dbc8881c Mon Sep 17 00:00:00 2001 From: veaba <908662421@qq.com> Date: Sat, 8 Oct 2016 00:57:50 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BA=86=E6=B7=B1?= =?UTF-8?q?=E5=85=A5=E5=93=8D=E5=BA=94=E5=BC=8F=E5=8E=9F=E7=90=86=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/guide/reactivity.md | 228 +++++----------------------------------- 1 file changed, 25 insertions(+), 203 deletions(-) diff --git a/src/guide/reactivity.md b/src/guide/reactivity.md index ac7abd9e0f..6f65a62e95 100644 --- a/src/guide/reactivity.md +++ b/src/guide/reactivity.md @@ -4,45 +4,43 @@ type: guide order: 15 --- -大部分的基础内容我们已经讲到了,现在讲点底层内容。Vue.js 最显著的一个功能是响应系统 —— 模型只是普通对象,修改它则更新视图。这让状态管理非常简单且直观,不过理解它的原理也很重要,可以避免一些常见问题。下面我们开始深挖 Vue.js 响应系统的底层细节。 +大部分的基础内容我们已经讲到了,现在讲点底层内容。Vue.js 最显著的一个功能是响应系统,只是普通的JavaScript对象模型,修改它则更新视图。这让状态管理非常简单且直观,不过理解它的原理也很重要,可以避免一些常见问题。本节中,下面我们开始深挖 Vue.js 响应系统的底层细节。 ## 如何追踪变化 -把一个普通对象传给 Vue 实例作为它的 `data` 选项,Vue.js 将遍历它的属性,用 [Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) 将它们转为 `getter/setter`。这是 ES5 特性,不能打补丁实现,这便是为什么 Vue.js 不支持 IE8 及更低版本。 +把一个普通Javascript对象传给 Vue 实例作为它的 `data` 选项,Vue.js 将遍历它的属性,用 [Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) 将它们转为 `getter/setter`。这是 ES5 特性,不能打补丁实现,这便是为什么 Vue.js 不支持 IE8 及更低版本。 -用户看不到 getter/setters,但是在内部它们让 Vue.js 追踪依赖,在属性被访问和修改时通知变化。一个问题是在浏览器控制台打印数据对象时 `getter/setter` 的格式化不同,使用 `vm.$log()` 实例方法可以得到更友好的输出。 +用户看不到 getter/setters,但是在内部它们让 Vue.js追踪依赖,在属性被访问和修改时通知变化。一个问题是在浏览器控制台打印数据对象时 getter/setter 的格式化不同,使用 `vm.$log()` 实例方法可以得到更友好的输出。所以你可能想要安装`vue-devtools`更多的检查接口。 模板中每个指令/数据绑定都有一个对应的 **watcher** 对象,在计算过程中它把属性记录为依赖。之后当依赖的 `setter` 被调用时,会触发 **watcher** 重新计算 ,也就会导致它的关联指令更新 DOM。 -> !!TODO: 因为vdom层的引入,这里可能会更新。 - ![data](/images/data.png) ## 变化检测问题 -受 ES5 的限制,Vue.js 不能检测到对象属性的添加或删除。因为 Vue.js 在初始化实例时将属性转为 `getter/setter`,所以属性必须在 `data` 对象上才能让 Vue.js 转换它,才能让它是响应的。例如: +受 ES5 的限制,Vue.js **不能检测到对象属性的添加或删除**。因为 Vue.js 在初始化实例时将属性转为 `getter/setter`,所以属性必须在 `data` 对象上才能让 Vue.js 转换它,才能让它是响应的。例如: ``` js -var data = { a: 1 } var vm = new Vue({ - data: data + data:{ + a:1 + } }) -// `vm.a` and `data.a` 现在是响应的 +//`vm.a`是响应 vm.b = 2 -// `vm.b` 不是响应的 - -data.b = 2 -// `data.b` 不是响应的 +// `vm.b` 是非响应 ``` -不过,有办法在实例创建之后**添加属性并且让它是响应的**。 - -对于 Vue 实例,可以使用 `Vue.$set(key, value)` 实例方法: +Vue 不允许动态地将新的顶级响应属性添加到已经创建的实例。然而,它是可能将响应属性添加到嵌套的对象,可以使用 `Vue.$set(key, value)` 实例方法: ``` js -Vue.set(data, 'c', 3) -// `vm.c` and `data.c` 现在是响应的 +Vue.set(vm.someObject, 'b', 2) + +``` +您还可以使用`vm.$set`实例方法,也是全局 `Vue.set`的别名: +```js +this.$set(this.someObject,'b',2) ``` 有时你想向已有对象上添加一些属性,例如使用 `Object.assign()` 或 `_.extend()`添加属性。但是,添加到对象上的新属性不会触发更新。这时可以创建一个新的对象,包含原对象的属性和新的属性: @@ -56,22 +54,7 @@ this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 }) ## 初始化数据 -尽管 Vue.js 提供了 API 动态地添加响应属性,还是推荐在 `data` 对象上声明所有的响应属性。 - -不这么做: - -不这么做: - -``` js -var vm = new Vue({ - template: '
{{ message }}
' -}) -// 之后设置 `message` -Vue.set(vm.$data, 'message', 'Hello!') -``` - -这么做: - +由于 Vue 不允许动态添加顶级响应属性,这意味着你必须初始化声明的所有顶级响应前期数据属性,哪怕是有空值的实例: ``` js var vm = new Vue({ data: { @@ -84,24 +67,18 @@ var vm = new Vue({ vm.message = 'Hello!' ``` -这么做有两个原因: +如果你不声明中数据选项的消息,Vue 将警告你的渲染功能试图访问一个不存在的属性。 -1. `data` 对象就像组件状态的模式(schema)。在它上面声明所有的属性让组件代码更易于理解。 - -2.添加一个顶级响应属性会强制所有的 watcher 重新计算,因为它之前不存在,没有 watcher 追踪它。这么做性能通常是可以接受的(特别是对比 Angular 的脏检查),但是可以在初始化时避免 +这种限制背后是有技术的原因,它消除了边缘情况下依赖项跟踪系统中一类,也使得 Vue 实例和类型检查系统发挥。但也是一个重要的考虑,在代码可维护性方面:数据对象就像组件状态的模式(Schema),在它上面声明所有的属性让组织代码更易于其他开发者阅读理解。 ## 异步更新队列 -> !!TODO: 我认为这里很大部分已经失效,需要尤小右来重写 - -By default, Vue performs DOM updates **asynchronously**. Whenever a data change is observed, it will open a queue and buffer all the data changes that happen in the same event loop. If the same watcher is triggered multiple times, it will be pushed into the queue only once. Then, in the next event loop "tick", Vue flushes the queue and performs only the necessary DOM updates. Internally Vue uses `MutationObserver` if available for the asynchronous queuing and falls back to `setTimeout(fn, 0)`. +默认情况下,Vue 执行 DOM 更新**异步**,只要观察到的数据更改,它将打开一个队列和缓冲区发生的所有数据更改在相同的事件循环。如果相同的观察者多次触发,它将会只有一次推送到队列。然后,在接下来的事件循环"时钟"中,Vue 刷新队列并执行仅有必要的 DOM 更新。Vue内部使用`MutationObserver` 如果可用的异步队列调用回调`setTimeout(fn, 0)`. -For example, when you set `vm.someData = 'new value'`, the DOM will not update immediately. It will update in the next "tick", when the queue is flushed. Most of the time we don't need to care about this, but it can be tricky when you want to do something that depends on the post-update DOM state. Although Vue.js generally encourages developers to think in a "data-driven" fashion and avoid touching the DOM directly, sometimes it might be necessary to get your hands dirty. In order to wait until Vue.js has finished updating the DOM after a data change, you can use `Vue.nextTick(callback)` immediately after the data is changed. The callback will be called after the DOM has been updated. For example: - -``` html -
{{ message }}
+例如,当你设置`vm.someData = 'new value'`,该组件不会马上被重新渲染。当刷新队列时,这个组件将会在下一个的'时钟'中更新。很多时候我们不需要关心这个,但可可能会非常的棘手,当你要执行某个动作的时候,将会取决于后更新的DOM状态。一般地,Vue.js鼓励开发人员用“数据驱动”的方式,尽量避免直接接触DOM,因为有时是完全没有必要。等待Vue.js已完成DOM数据更改后,可以使用`Vue.nextTick(callback)`实时更改数据,之后更新DOM会调用回调。例如: +```html +
{{message}}
``` - ``` js var vm = new Vue({ el: '#example', @@ -109,168 +86,13 @@ var vm = new Vue({ message: '123' } }) -vm.message = 'new message' // change data +vm.message = 'new message' // 更改数据 vm.$el.textContent === 'new message' // false Vue.nextTick(function () { vm.$el.textContent === 'new message' // true }) ``` - -There is also the `vm.$nextTick()` instance method, which is especially handy inside components, because it doesn't need global `Vue` and its callback's `this` context will be automatically bound to the current Vue instance: - -``` js -Vue.component('example', { - template: '{{ message }}', - data: function () { - return { - message: 'not updated' - } - }, - methods: { - updateMessage: function () { - this.message = 'updated' - console.log(this.$el.textContent) // => 'not updated' - this.$nextTick(function () { - console.log(this.$el.textContent) // => 'updated' - }) - } - } -}) -``` - -## Inside Computed Properties - -It should be noted that Vue's computed properties are **not** simple getters. Each computed property keeps track of its own reactive dependencies. When a computed property is evaluated, Vue updates its dependency list and caches the returned value. The cached value is only invalidated when one of the tracked dependencies have changed. Therefore, as long as the dependencies did not change, accessing the computed property will directly return the cached value instead of calling the getter. - -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! - -Because of computed property caching, the getter function is not always called when you access a computed property. Consider the following example: - -``` js -var vm = new Vue({ - data: { - message: 'hi' - }, - computed: { - example: function () { - return Date.now() + this.message - } - } -}) -``` - -The computed property `example` has only one dependency: `vm.message`. `Date.now()` is **not** a reactive dependency, because it has nothing to do with Vue's data observation system. Therefore, when you programmatically access `vm.example`, you will find the timestamp remains the same unless `vm.message` triggers a re-evaluation. - -In some use cases, you may want to preserve the simple getter-like behavior, where every time you access `vm.example` it simply calls the getter again. You can do that by turning off caching for a specific computed property: - -``` js -computed: { - example: { - cache: false, - get: function () { - return Date.now() + this.message - } - } -} -``` - -Now, every time you access `vm.example`, the timestamp will be up-to-date. **However, note this only affects programmatic access inside JavaScript; data-bindings are still dependency-driven.** When you bind to a computed property in the template as `{% raw %}{{ example }}{% endraw %}`, the DOM will only be updated when a reactive dependency has changed. - -We've covered most of the basics - now it's time to take a deep dive! One of Vue's most distinct features is the unobtrusive reactivity system. Models are just plain JavaScript objects. When you modify them, the view updates. It makes state management very simple and intuitive, but it's also important to understand how it works to avoid some common gotchas. In this section, we are going to dig into some of the lower-level details of Vue's reactivity system. - -## How Changes Are Tracked - -When you pass a plain JavaScript object to a Vue instance as its `data` option, Vue will walk through all of its properties and convert them to getter/setters using [Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty). This is an ES5-only and un-shimmable feature, which is why Vue doesn't support IE8 and below. - -The getter/setters are invisible to the user, but under the hood they enable Vue to perform dependency-tracking and change-notification when properties are accessed or modified. One caveat is that browser consoles format getter/setters differently when converted data objects are logged, so you may want to install [vue-devtools](https://github.com/vuejs/vue-devtools) for a more inspection-friendly interface. - -Every component instance has a corresponding **watcher** instance, which records any properties "touched" during the component's render as dependencies. Later on when a dependency's setter is triggered, it notifies the watcher, which in turn causes the component to re-render. - -![Reactivity Cycle](/images/data.png) - -## Change Detection Caveats - -Due to the limitations of modern JavaScript (and the abandonment of `Object.observe`), Vue **cannot detect property addition or deletion**. Since Vue performs the getter/setter conversion process during instance initialization, a property must be present in the `data` object in order for Vue to convert it and make it reactive. For example: - -``` js -var vm = new Vue({ - data: { - a: 1 - } -}) -// `vm.a` is now reactive - -vm.b = 2 -// `vm.b` is NOT reactive -``` - -Vue does not allow dynamically adding new root-level reactive properties to an already created instance. However, it's possible to add reactive properties to a nested object using the `Vue.set(object, key, value)` method: - -``` js -Vue.set(vm.someObject, 'b', 2) -``` - -You can also use the `vm.$set` instance method, which is just an alias to the global `Vue.set`: - -``` js -this.$set(this.someObject, 'b', 2) -``` - -Sometimes you may want to assign a number of properties to an existing object, for example using `Object.assign()` or `_.extend()`. However, new properties added to the object will not trigger changes. In such cases, create a fresh object with properties from both the original object and the mixin object: - -``` js -// instead of `Object.assign(this.someObject, { a: 1, b: 2 })` -this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 }) -``` - -There are also a few array-related caveats, which were discussed earlier in the [list rendering section](/guide/list.html#Caveats). - -## Declaring Reactive Properties - -Since Vue doesn't allow dynamically adding root-level reactive properties, this means you have to initialize you instances by declaring all root-level reactive data properties upfront, even just with an empty value: - -``` js -var vm = new Vue({ - data: { - // declare message with an empty value - message: '' - }, - template: '
{{ message }}
' -}) -// set `message` later -vm.message = 'Hello!' -``` - -If you don't declare `message` in the data option, Vue will warn you that the render function is trying to access a property that doesn't exist. - -There are technical reasons behind this restriction - it eliminates a class of edge cases in the dependency tracking system, and also makes Vue instances play nicer with type checking systems. But there is also an important consideration in terms of code maintainability: the `data` object is like the schema for your component's state. Declaring all reactive properties upfront makes the component code easier to understand when revisited later or read by another developer. - -## Async Update Queue - -In case you haven't noticed yet, Vue performs DOM updates **asynchronously**. Whenever a data change is observed, it will open a queue and buffer all the data changes that happen in the same event loop. If the same watcher is triggered multiple times, it will be pushed into the queue only once. This buffered de-duplication is important in avoiding unnecessary calculations and DOM manipulations. Then, in the next event loop "tick", Vue flushes the queue and performs the actual (already de-duped) work. Internally Vue uses `MutationObserver` if available for the asynchronous queuing and falls back to `setTimeout(fn, 0)`. - -For example, when you set `vm.someData = 'new value'`, the component will not re-render immediately. It will update in the next "tick", when the queue is flushed. Most of the time we don't need to care about this, but it can be tricky when you want to do something that depends on the post-update DOM state. Although Vue.js generally encourages developers to think in a "data-driven" fashion and avoid touching the DOM directly, sometimes it might be necessary to get your hands dirty. In order to wait until Vue.js has finished updating the DOM after a data change, you can use `Vue.nextTick(callback)` immediately after the data is changed. The callback will be called after the DOM has been updated. For example: - -``` html -
{{ message }}
-``` - -``` js -var vm = new Vue({ - el: '#example', - data: { - message: '123' - } -}) -vm.message = 'new message' // change data -vm.$el.textContent === 'new message' // false -Vue.nextTick(function () { - vm.$el.textContent === 'new message' // true -}) -``` - -There is also the `vm.$nextTick()` instance method, which is especially handy inside components, because it doesn't need global `Vue` and its callback's `this` context will be automatically bound to the current Vue instance: - +这也是`vm.$nextTick()`实例方法,是在组件内特别方便,因为它不需要全局`Vue`和其回调`this`上下文将自动绑定到当前的Vue实例: ``` js Vue.component('example', { template: '{{ message }}', From d787a21194efd2792980460d36277238c46c76ad Mon Sep 17 00:00:00 2001 From: apple Date: Sat, 8 Oct 2016 08:36:22 +0800 Subject: [PATCH 2/4] =?UTF-8?q?issue#70=20=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/examples/commits.md | 4 ++-- src/examples/elastic-header.md | 2 +- src/examples/firebase.md | 5 ++--- src/examples/grid-component.md | 4 ++-- src/examples/hackernews.md | 25 +++++++++++++------------ src/examples/index.md | 4 ++-- src/examples/modal.md | 4 ++-- src/examples/select2.md | 4 ++-- src/examples/svg.md | 4 ++-- src/examples/todomvc.md | 2 +- src/examples/tree-view.md | 4 ++-- 11 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/examples/commits.md b/src/examples/commits.md index 7481498d3a..0659787843 100644 --- a/src/examples/commits.md +++ b/src/examples/commits.md @@ -1,9 +1,9 @@ --- -title: GitHub Commits +title: GitHub 提交 type: examples order: 1 --- -> This example fetches latest Vue.js commits data from GitHub's API and displays them as a list. You can switch between the master and dev branches. +> 这个例子从 Github 的 API 中获取了最新的 Vue.js 提交数据,并且以列表形式将它们展示了出来。你可以轻松地切换 master 和 dev 分支。 diff --git a/src/examples/elastic-header.md b/src/examples/elastic-header.md index 186ba37a92..470fd00d54 100644 --- a/src/examples/elastic-header.md +++ b/src/examples/elastic-header.md @@ -1,5 +1,5 @@ --- -title: Elastic Header +title: 具有伸缩性的 Header type: examples order: 7 --- diff --git a/src/examples/firebase.md b/src/examples/firebase.md index a806e329dd..8cad5c6a1c 100644 --- a/src/examples/firebase.md +++ b/src/examples/firebase.md @@ -1,9 +1,8 @@ --- -title: Firebase + Validation +title: Firebase + 验证 type: examples order: 2 --- -> This example uses [Firebase](https://firebase.google.com/) as the data persistence backend and syncs between clients in real time (you can try opening it in multiple browser tabs). In addition, it performs instant validation using computed properties and triggers CSS transitions when adding/removing items. - +> 本示例使用 [Firebase](https://firebase.google.com/) 作为数据存储后端,同时在客户端进行数据实时同步(你可以在多个浏览器窗口去打开它来验证)。另外,它通过计算属性实时验证,并且添加/移除选项时触发 CSS 转变。 diff --git a/src/examples/grid-component.md b/src/examples/grid-component.md index 19b339cb15..879a2d7bd4 100644 --- a/src/examples/grid-component.md +++ b/src/examples/grid-component.md @@ -1,9 +1,9 @@ --- -title: Grid Component +title: 网格组件 type: examples order: 3 --- -> This is an example of creating a reusable grid component and using it with external data. +> 本示例创建了一个可复用组件,可结合外部数据来使用它。 diff --git a/src/examples/hackernews.md b/src/examples/hackernews.md index 0c0305a226..49143ba582 100644 --- a/src/examples/hackernews.md +++ b/src/examples/hackernews.md @@ -1,10 +1,10 @@ --- -title: HackerNews Clone +title: HackerNews 克隆 type: examples order: 10 --- -> This is a HackerNews clone built upon HN's official Firebase API, Vue 2.0 + vue-router + vuex, with server-side rendering. +> HackerNews 克隆是基于 HN 的官方 firebase API,Vue 2.0 、vue-router 和 vuex 来构建的,使用服务器端渲染。 {% raw %}
@@ -16,20 +16,21 @@ order: 10 > [Live Demo](https://vue-hn.now.sh/) > Note: the demo may need some spin up time if nobody has accessed it for a certain period. +笔记:如果没在特定时间段用到它,那么本示例需要一些加载时间。 > > [[Source](https://github.com/vuejs/vue-hackernews-2.0)] -## Features +## 特性 -- Server Side Rendering - - Vue + vue-router + vuex working together - - Server-side data pre-fetching - - Client-side state & DOM hydration -- Single-file Vue Components - - Hot-reload in development - - CSS extraction for production -- Real-time List Updates with FLIP Animation +- 服务器端渲染 + - Vue + vue-router + vuex + - 服务端数据提前获取 + - 客户端状态 & DOM 合并 +- 单文件 Vue 组件 + - 开发时进行热加载 + - 生产时抽出 CSS +- 使用 FLIP 动画进行实时列表更新 -## Architecture Overview +## 结构概览 Hackernew clone architecture overview diff --git a/src/examples/index.md b/src/examples/index.md index 3c4cdcf96c..56ee85c3c8 100644 --- a/src/examples/index.md +++ b/src/examples/index.md @@ -1,9 +1,9 @@ --- -title: Markdown Editor +title: Markdown 编辑器 type: examples order: 0 --- -> Dead simple Markdown editor. +> 蠢萌的 Markdown 编辑器。 diff --git a/src/examples/modal.md b/src/examples/modal.md index fc1e0a9e3f..2ab4ebd3aa 100644 --- a/src/examples/modal.md +++ b/src/examples/modal.md @@ -1,9 +1,9 @@ --- -title: Modal Component +title: 模式组件 type: examples order: 6 --- -> Features used: component, prop passing, content insertion, transitions. +> 使用到的特性:组件,prop 传递,内容插入(content insertion),过渡(transitions)。 diff --git a/src/examples/select2.md b/src/examples/select2.md index 2e00768eb2..e21f3beb2a 100644 --- a/src/examples/select2.md +++ b/src/examples/select2.md @@ -1,9 +1,9 @@ --- -title: Wrapper Component +title: 内嵌组件 type: examples order: 8 --- -> In this example we are integrating a 3rd party jQuery plugin (select2) by wrapping it inside a custom component. +> 在本例中,我们整合了第三方 jQuery 插件(select2),怎么做到的呢?就是把它内嵌在一个常用组件中== diff --git a/src/examples/svg.md b/src/examples/svg.md index 38756f623e..67e7c0059b 100644 --- a/src/examples/svg.md +++ b/src/examples/svg.md @@ -1,9 +1,9 @@ --- -title: SVG Graph +title: SVG 图表 type: examples order: 5 --- -> This example showcases a combination of custom component, computed property, two-way binding and SVG support. +> 本示例展示了一个结合体,它由常用组件、计算属性、2 种绑定方式和 SVG 的支持组成。 diff --git a/src/examples/todomvc.md b/src/examples/todomvc.md index c70ee3a395..8b6b8508d6 100644 --- a/src/examples/todomvc.md +++ b/src/examples/todomvc.md @@ -4,6 +4,6 @@ type: examples order: 9 --- -> This is a fully spec-compliant TodoMVC implementation in under 120 effective lines of JavaScript (excluding comments and blank lines). +> 本例是一个完全和规范一致的 TodoMVC 实现,只用了 120 行有效的 JavaScript(不包含注释和空行)。 diff --git a/src/examples/tree-view.md b/src/examples/tree-view.md index 071bfb1d5e..3c501a7f72 100644 --- a/src/examples/tree-view.md +++ b/src/examples/tree-view.md @@ -1,9 +1,9 @@ --- -title: Tree View +title: 树形视图 type: examples order: 4 --- -> Example of a simple tree view implementation showcasing recursive usage of components. +> 本示例是一个简单的树形视图实现,它展现了组件的递归使用。 From 2aa6ab0d5abdd7431ce580780b346bbdab8e8a21 Mon Sep 17 00:00:00 2001 From: hukee <651841877@qq.com> Date: Sat, 8 Oct 2016 08:58:45 +0800 Subject: [PATCH 3/4] Add files via upload --- src/plugins.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/plugins.md diff --git a/src/plugins.md b/src/plugins.md new file mode 100644 index 0000000000..5b98d60f69 --- /dev/null +++ b/src/plugins.md @@ -0,0 +1,85 @@ +--- +title: 插件 +type: guide +order: 18 +--- + +## 开发插件 + + +插件通常会为Vue添加全局功能。插件的范围没有限制--一般有下面几种: + +1. 添加全局方法或者属性,如: [vue-element](https://github.com/vuejs/vue-element) + +2. 添加全局资源:指令/过滤器/过渡等。如 vue-touch [vue-touch](https://github.com/vuejs/vue-touch) + +3. 通过全局 mixin方法 添加一些组件选项。 如: [vuex](https://github.com/vuejs/vuex) + +4. 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。 + +5. A一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 [vue-router](https://github.com/vuejs/vue-router) + +Vue.js 的插件应当有一个公开方法 `install` 。这个方法的第一个参数是 `Vue` 构造器 , 第二个参数是一个可选的选项对象: + +``` js +MyPlugin.install = function (Vue, options) { + // 1. 添加全局方法或属性 + Vue.myGlobalMethod = function () { + // something logic ... + } + + // 2. 添加全局资源 + Vue.directive('my-directive', { + bind (el, binding, vnode, oldVnode) { + // something logic ... + } + ... + }) + + // 3. 注入组件 + Vue.mixin({ + created: function () { + // something logic ... + } + ... + }) + + // 4. 添加事例方法 + Vue.prototype.$myMethod = function (options) { + // something logic ... + } +} +``` + +## 使用插件 + +通过 Vue.use() 全局方法使用插件: + +``` js +// 调用 `MyPlugin.install(Vue)` +Vue.use(MyPlugin) +``` + +也可以传入一个选项对象: + +``` js +Vue.use(MyPlugin, { someOption: true }) +``` + +`Vue.use` 会自动阻止注册相同插件多次,届时只会注册一次该插件。 + +一些插件,如 `vue-router` 如果 `Vue` 是全局变量则自动调用`Vue.use()` 。不过在模块环境中应当始终显式调用 `Vue.use()` : + +``` js +// 通过 Browserify 或 Webpack 使用 CommonJS 兼容模块 +var Vue = require('vue') +var VueRouter = require('vue-router') + +// 不要忘了调用此方法 +Vue.use(VueRouter) +``` + +[awesome-vue](https://github.com/vuejs/awesome-vue#libraries--plugins) 集合了来自社区贡献的数以千计的插件和库。 + + + From a95037aa4b556443c0354e8847c8ebf183bf4ebb Mon Sep 17 00:00:00 2001 From: lizhihua <275091674@qq.com> Date: Sat, 8 Oct 2016 11:06:31 +0800 Subject: [PATCH 4/4] index.md --- src/api/index.md | 92 ++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/api/index.md b/src/api/index.md index 5813bb176d..92bc38c67a 100644 --- a/src/api/index.md +++ b/src/api/index.md @@ -1629,37 +1629,36 @@ All lifecycle hooks automatically have their `this` context bound to the instanc - **See also:** [Named Slots](/guide/components.html#Named-Slots) -## Built-In Components +## 内置的组件 ### component -- **Props:** +- **特性:** - `is` - string | ComponentDefinition | ComponentConstructor - `inline-template` - boolean -- **Usage:** +- **用法:** - A "meta component" for rendering dynamic components. The actual component to render is determined by the `is` prop: + 动态渲染一个“元组件”。实际由 `is` 属性决定哪个渲染组件。 ```html - - + - + ``` -- **See also:** [Dynamic Components](/guide/components.html#Dynamic-Components) +- **另见:** [动态组件](/guide/components.html#动态组件) ### transition -- **Props:** - - `name` - string, Used to automatically generate transition CSS class names. e.g. `name: 'fade'` will auto expand to `.fade-enter`, `.fade-enter-active`, etc. Defaults to `"v"`. - - `appear` - boolean, Whether to apply transition on initial render. Defaults to `false`. - - `css` - boolean, Whether to apply CSS transition classes. Defaults to `true`. If set to `false`, will only trigger JavaScript hooks registered via component events. - - `type` - string, Specify the type of transition events to wait for to determine transition end timing. Available values are `"transition"` and `"animation"`. By default, it will automatically detect the type that has a longer duration. - - `mode` - string, Controls the timing sequence of leaving/entering transitions. Available modes are `"out-in"` and `"in-out"`; defaults to simultaneous. +- **特性:** + - `name` - string, 用于自动生成 CSS 过渡类名。例如:`name: 'fade'` 将自动拓展为`.fade-enter`,`.fade-enter-active`等。默认类名为 `"v"` + - `appear` - boolean, 是否在初始渲染时使用过渡。默认为 `false`。 + - `css` - boolean, 是否使用 CSS 过渡类。默认为 `true`。如果设置为 `false`,将只通过组件事件触发注册的 JavaScript 钩子。 + - `type` - string, 指定过渡事件类型,侦听过渡何时结束。有效值为 `"transition"` 和 `"animation"`。默认 Vue.js 将自动检测出持续时间长的为过渡事件类型。 + - `mode` - string, 控制离开/进入的过渡时间序列。有效的模式有 `"out-in"` 和 `"in-out"`;默认同时生效。 - `enter-class` - string - `leave-class` - string - `enter-active-class` - string @@ -1667,7 +1666,7 @@ All lifecycle hooks automatically have their `this` context bound to the instanc - `appear-class` - string - `appear-active-class` - string -- **Events:** +- **事件:** - `before-enter` - `enter` - `after-enter` @@ -1678,22 +1677,22 @@ All lifecycle hooks automatically have their `this` context bound to the instanc - `appear` - `after-appear` -- **Usage:** +- **用法:** - `` serve as transition effects for **single** element/component. The `` does not render an extra DOM element, nor does it show up in the inspected component hierarchy. It simply applies the transition behavior to the wrapped content inside. + `` 元素作为单个元素/组件的过渡效果。`` 不会渲染额外的 DOM 元素,也不会出现在检测过的组件层级中。它只是将内容包裹在其中,简单的运用过渡行为。 ```html - +
toggled content
- + - +
toggled content
@@ -1706,32 +1705,32 @@ All lifecycle hooks automatically have their `this` context bound to the instanc ... methods: { transitionComplete: function (el) { - // for passed 'el' that DOM element as the argument, something ... + // 传入 'el' 这个 DOM 元素作为参数。 } } ... }).$mount('#transition-demo') ``` -- **See also:** [Transitions: Entering, Leaving, and Lists](/guide/transitions.html) +- **另见:** [过渡:进入,离开和列表](/guide/transitions.html) ### transition-group -- **Props:** - - `tag` - string, defaults to `span`. - - `move-class` - overwrite CSS class applied during moving transition. - - exposes the same props as `` except `mode`. +- **特性:** + - `tag` - string, 默认为 `span` + - `move-class` - 覆盖移动过渡期间应用的 CSS 类。 + - 除了 `mode`,其他特性和 `` 相同。 -- **Events:** - - exposes the same events as ``. +- **事件:** + - 事件和 `` 相同. -- **Usage:** +- **用法:** - `` serve as transition effects for **multiple** elements/components. The `` renders a real DOM element. By default it renders a ``, and you can configure what element is should render via the `tag` attribute. + `` 元素作为多个元素/组件的过渡效果。`` 渲染一个真实的 DOM 元素。默认渲染 ``,可以通过 `tag` 属性配置哪个元素应该被渲染。 - Note every child in a `` must be **uniquely keyed** for the animations to work properly. + 注意,每个 `` 的子节点必须有 **独立的key** ,动画才能正常工作 - `` supports moving transitions via CSS transform. When a child's position on screen has changed after an updated, it will get applied a moving CSS class (auto generated from the `name` attribute or configured with the `move-class` attribute). If the CSS `transform` property is "transition-able" when the moving class is applied, the element will be smoothly animated to its destination using the [FLIP technique](https://aerotwist.com/blog/flip-your-animations/). + `` 支持通过 CSS transform 过渡移动。当一个子节点被更新,从屏幕上的位置发生变化,它将会获取应用 CSS 移动类(通过 `name` 属性或配置 `move-class` 属性自动生成)。如果 CSS `transform` 属性是“可过渡”属性,当应用移动类时,将会使用 [FLIP 技术](https://aerotwist.com/blog/flip-your-animations/) 使元素流畅地到达动画终点。 ```html @@ -1741,31 +1740,31 @@ All lifecycle hooks automatically have their `this` context bound to the instanc ``` -- **See also:** [Transitions: Entering, Leaving, and Lists](/guide/transitions.html) +- **另见:** [过渡:进入,离开和列表](/guide/transitions.html) ### keep-alive -- **Usage:** +- **用法:** - When wrapped around a dynamic component, `` caches the inactive component instances without destroying them. Similar to ``, `` is an abstract component: it doesn't render a DOM element itself, and doesn't show up in the component parent chain. + `` 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 `` 相似,`` 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。 - When a component is toggled inside ``, its `activated` and `deactivated` lifecycle hooks will be invoked accordingly. + 当组件在 `` 内被切换,它的 `activated` 和 `deactivated` 这两个生命周期钩子函数将会被对应执行。 - Primarily used with preserve component state or avoid re-rendering. + 主要用于保留组件状态或避免重新渲染。 ```html - + - + - + @@ -1773,22 +1772,23 @@ All lifecycle hooks automatically have their `this` context bound to the instanc ``` -

`` does not work with functional components because they do not have instances to be cached.

+

`` 不会在函数式组件中正常工作,因为它们没有缓存实例。

-- **See also:** [Dynamic Components - keep-alive](/guide/components.html#keep-alive) +- **另见:** [动态组件 - keep-alive](/guide/components.html#keep-alive) ### slot -- **Props:** - - `name` - string, Used for named slot. +- **特性:** + - `name` - string, 用于命名插槽。 - **Usage:** - `` serve as content distribution outlets in component templates. `` itself will be replaced. + `` 元素作为组件模板之中的内容分发插槽。 `` 元素自身将被替换。 + 详细用法,请参考下面 guide 部分的链接。 For detailed usage, see the guide section linked below. -- **See also:** [Content Distribution with Slots](/guide/components.html#Content-Distribution-with-Slots) +- **另见:** [使用Slots分发内容](/guide/components.html#使用Slots分发内容) ## VNode接口