Skip to content

Commit 14c2686

Browse files
authored
Merge pull request #21 from vuejs/2.0
2.0
2 parents 8eac980 + 059b1f1 commit 14c2686

File tree

8 files changed

+82
-46
lines changed

8 files changed

+82
-46
lines changed

src/api/index.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,6 @@ type: api
440440

441441
- **See also:**
442442
- [Computed Properties](/guide/computed.html)
443-
- [Reactivity in Depth: Inside Computed Properties](/guide/reactivity.html#Inside-Computed-Properties)
444443

445444
### methods
446445

src/examples/hackernews.md

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,32 @@ type: examples
44
order: 10
55
---
66

7-
> This is a HackerNews clone built upon HN's official Firebase API, and using Webpack + vue-loader for the build setup.
7+
> This is a HackerNews clone built upon HN's official Firebase API, Vue 2.0 + vue-router + vuex, with server-side rendering.
88
9+
{% raw %}
910
<div style="max-width:600px">
10-
<a href="http://vuejs.github.io/vue-hackernews" target="_blank"><img style="width:100%" src="/images/hn.png"></a>
11+
<a href="https://github.com/vuejs/vue-hackernews-2.0" target="_blank">
12+
<img style="width:100%" src="/images/hn.png">
13+
</a>
1114
</div>
15+
{% endraw %}
1216

13-
> [[Source](https://github.com/vuejs/vue-hackernews)]
17+
> [Live Demo](https://vue-hn.now.sh/)
18+
> Note: the demo may need some spin up time if nobody has accessed it for a certain period.
19+
>
20+
> [[Source](https://github.com/vuejs/vue-hackernews-2.0)]
21+
22+
## Features
23+
24+
- Server Side Rendering
25+
- Vue + vue-router + vuex working together
26+
- Server-side data pre-fetching
27+
- Client-side state & DOM hydration
28+
- Single-file Vue Components
29+
- Hot-reload in development
30+
- CSS extraction for production
31+
- Real-time List Updates with FLIP Animation
32+
33+
## Architecture Overview
34+
35+
<img width="973" alt="Hackernew clone architecture overview" src="/images/hn-architecture.png">

src/guide/computed.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,39 @@ You can open the console and play with the example vm yourself. The value of `vm
7777

7878
You can data-bind to computed properties in templates just like a normal property. Vue is aware that `vm.reversedMessage` depends on `vm.message`, so it will update any bindings that depend on `vm.reversedMessage` when `vm.message` changes. And the best part is that we've created this dependency relationship declaratively: the computed getter function is pure and has no side effects, which makes it easy to test and reason about.
7979

80+
### Computed Caching vs Methods
81+
82+
You may have noticed we can achieve the same result by invoking a method in the expression:
83+
84+
``` html
85+
<p>Reversed message: "{{ reverseMessage() }}"</p>
86+
```
87+
88+
``` js
89+
// in component
90+
methods: {
91+
reverseMessage: function () {
92+
return this.message.split('').reverse().join('')
93+
}
94+
}
95+
```
96+
97+
Instead of a computed property, we can define the same function as a method instead. For the end result, the two approaches are indeed exactly the same. However, the difference is that **computed properties are cached based on its dependencies.** A computed property will only re-evaluate when some of its dependencies have changed. This means as long as `message` has not changed, multiple access to the `reversedMessage` computed property will immediately return the previously computed result without having to run the function again.
98+
99+
This also means the following computed property will never update, because `Date.now()` is not a reactive dependency:
100+
101+
``` js
102+
computed: {
103+
now: function () {
104+
return Date.now()
105+
}
106+
}
107+
```
108+
109+
In comparison, a method invocation will **always** run the function whenever a re-render happens.
110+
111+
Why do we need caching? Imagine we have an expensive computed property **A**, which requires looping through a huge Array and doing a lot of computations. Then we may have other computed properties that in turn depend on **A**. Without caching, we would be executing **A**’s getter many more times than necessary! In cases where you do not want caching, use a method instead.
112+
80113
### Computed vs Watched Property
81114

82115
Vue does provide a more generic way to observe and react to data changes on a Vue instance: **watch properties**. When you have some data that needs to change based on some other data, it is tempting to overuse `watch` - especially if you are coming from an AngularJS background. However, it is often a better idea to use a computed property rather than an imperative `watch` callback. Consider this example:
@@ -148,8 +181,6 @@ computed: {
148181

149182
Now when you run `vm.fullName = 'John Doe'`, the setter will be invoked and `vm.firstName` and `vm.lastName` will be updated accordingly.
150183

151-
The technical details behind how computed properties are updated are discussed in [another section](reactivity.html#Inside-Computed-Properties) dedicated to the reactivity system.
152-
153184
## Watchers
154185

155186
While computed properties are more appropriate in most cases, there are times when a custom watcher is necessary. That's why Vue provides a more generic way to react to data changes through the `watch` option. This is most useful when you want to perform asynchronous or expensive operations in response to changing data.
@@ -270,3 +301,5 @@ var watchExampleVM = new Vue({
270301
{% endraw %}
271302

272303
In this case, using the `watch` option allows us to perform an asynchronous operation (accessing an API), limit how often we perform that operation, and set intermediary states until we get a final answer. None of that would be possible with a computed property.
304+
305+
In addition to the `watch` option, you can also use the imperative [vm.$watch API](/api/#vm-watch).

src/guide/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ var app3 = new Vue({
113113
</script>
114114
{% endraw %}
115115

116-
Go ahead and enter `app2.seen = false` in the console. You should see the message disappear.
116+
Go ahead and enter `app3.seen = false` in the console. You should see the message disappear.
117117

118118
This second example demonstrates that we can bind data to not only text and attributes, but also the **structure** of the DOM. Moreover, Vue also provides a powerful transition effect system that can automatically apply [transition effects](transitions.html) when elements are inserted/updated/removed by Vue.
119119

src/guide/installation.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ Detailed release notes for each version are available on [GitHub](https://github
1818

1919
## Standalone
2020

21-
Simply download and include with a script tag. `Vue` will be registered as a global variable. **Pro tip: Don't use the minified version during development. You will miss out all the nice warnings for common mistakes.**
21+
Simply download and include with a script tag. `Vue` will be registered as a global variable.
22+
23+
<p class="tip">Don't use the minified version during development. You will miss out all the nice warnings for common mistakes!</p>
2224

2325
<div id="downloads">
2426
<a class="button" href="/js/vue.js" download>Development Version</a><span class="light info">With full warnings and debug mode</span>
@@ -47,6 +49,24 @@ NPM is the recommended installation method when building large scale application
4749
$ npm install vue@next
4850
```
4951

52+
### Note on NPM Builds
53+
54+
Because Single File Components pre-compile the templates into render functions at build time, the default export of the `vue` NPM package is the **runtime-only build**, which does not support the `template` option. If you still wish to use the `template` option, you will need to configure your bundler to alias `vue` to the standalone build.
55+
56+
With webpack, add the following alias to your webpack config:
57+
58+
``` js
59+
resolve: {
60+
alias: {
61+
vue: 'vue/dist/vue.js'
62+
}
63+
}
64+
```
65+
66+
For Browserify, you can use [aliasify](https://github.com/benbria/aliasify) for the same effect.
67+
68+
<p class="tip">Do NOT do `import Vue from 'vue/dist/vue'` - since some tools or 3rd party libraries may import vue as well, this may cause the app to load both the runtime and standalone builds at the same time and lead to errors.</p>
69+
5070
## CLI
5171

5272
Vue.js provides an [official CLI](https://github.com/vuejs/vue-cli) for quickly scaffolding ambitious Single Page Applications. It provides batteries-included build setups for a modern frontend workflow. It takes only a few minutes to get up and running with hot-reload, lint-on-save, and production-ready builds:

src/guide/reactivity.md

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -135,41 +135,3 @@ Vue.component('example', {
135135
}
136136
})
137137
```
138-
139-
## Inside Computed Properties
140-
141-
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.
142-
143-
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!
144-
145-
Because of computed property caching, the getter function is not always called when you access a computed property. Consider the following example:
146-
147-
``` js
148-
var vm = new Vue({
149-
data: {
150-
message: 'hi'
151-
},
152-
computed: {
153-
example: function () {
154-
return Date.now() + this.message
155-
}
156-
}
157-
})
158-
```
159-
160-
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.
161-
162-
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:
163-
164-
``` js
165-
computed: {
166-
example: {
167-
cache: false,
168-
get: function () {
169-
return Date.now() + this.message
170-
}
171-
}
172-
}
173-
```
174-
175-
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.

src/images/hn-architecture.png

140 KB
Loading

src/images/hn.png

-108 KB
Loading

0 commit comments

Comments
 (0)