Skip to content

Commit 6bbe60d

Browse files
committed
Merge remote-tracking branch 'upstream/master'
# Conflicts: # README.md # package.json # src/v2/api/index.md # src/v2/cookbook/adding-instance-properties.md # src/v2/cookbook/serverless-blog.md # src/v2/guide/components.md # src/v2/guide/render-function.md # src/v2/guide/state-management.md # src/v2/style-guide/index.md
2 parents 60f35b7 + 6edb501 commit 6bbe60d

29 files changed

+2330
-575
lines changed

_config.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,3 @@ alias:
187187
examples/svg.html: v2/examples/svg.html
188188
examples/todomvc.html: v2/examples/todomvc.html
189189
examples/tree-view.html: v2/examples/tree-view.html
190-

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,27 @@
22
"name": "vuejs.org",
33
"private": true,
44
"hexo": {
5-
"version": "3.4.4"
5+
"version": "3.7.0"
66
},
77
"scripts": {
88
"start": "hexo server",
99
"build": "node pre-deploy.js && hexo clean && hexo generate",
1010
"deploy": "npm run build && hexo deploy"
1111
},
1212
"dependencies": {
13-
"hexo": "^3.4.4",
13+
"hexo": "^3.6.0",
1414
"hexo-deployer-git": "0.3.1",
1515
"hexo-generator-alias": "git+https://github.com/chrisvfritz/vuejs.org-hexo-generator-alias.git",
1616
"hexo-generator-archive": "^0.1.5",
1717
"hexo-generator-category": "^0.1.3",
1818
"hexo-generator-feed": "^1.2.2",
1919
"hexo-generator-index": "^0.2.1",
2020
"hexo-generator-tag": "^0.2.0",
21-
"hexo-offline": "^0.2.2",
21+
"hexo-offline": "^0.2.3",
2222
"hexo-renderer-ejs": "^0.3.1",
2323
"hexo-renderer-marked": "^0.3.0",
2424
"hexo-renderer-stylus": "^0.3.3",
25-
"hexo-server": "^0.2.2",
26-
"request": "^2.83.0"
25+
"hexo-server": "^0.3.1",
26+
"request": "^2.85.0"
2727
}
2828
}

src/v2/api/index.md

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,11 @@ type: api
460460
})
461461
```
462462

463-
<p class="tip">Notez que __vous ne devriez pas utiliser de fonctions fléchées pour la propriété `data`__ (exemple: `data: () => { return { a: this.maPropriete }}`). La raison est que les fonctions fléchées sont liées au contexte parent, donc `this` ne correspondra pas à l'instance de Vue et `this.maPropriete` vaudra `undefined`.</p>
463+
Notez que si vous utilisez la fonctions fléchées avec la propriété `data`, `this` ne sera plus l'instance du composant, mais vous pouvez toujours la récupérer en tant que premier argument de la fonction :
464+
465+
```js
466+
data: vm => ({ a: vm.myProp })
467+
```
464468

465469
- **Voir aussi :** [Réactivité dans le détail](../guide/reactivity.html)
466470

@@ -533,7 +537,13 @@ type: api
533537

534538
Les propriétés calculées qui seront ajoutées à l'instance de Vue. Tous les accesseurs (« getters ») et mutateurs (« setters ») ont leur contexte `this` automatiquement lié à l'instance de Vue.
535539

536-
<p class="tip">Notez que __vous ne devriez pas utiliser de fonctions fléchées pour définir une propriété calculée__ (exemple: `aDouble: () => this.a * 2`). La raison est que les fonctions fléchées sont liées au contexte parent, donc `this` ne correspondra pas à l'instance de Vue et `this.a` vaudra `undefined`.</p>
540+
Notez que si vous utilisez la fonctions fléchées avec la propriété `data`, `this` ne sera plus l'instance du composant, mais vous pouvez toujours la récupérer en tant que premier argument de la fonction :
541+
542+
```js
543+
computed: {
544+
aDouble: vm => vm.a * 2
545+
}
546+
```
537547

538548
Les propriétés calculées sont mises en cache, et réévaluées uniquement lorsque leurs dépendances réactives changent. Notez que si une certaine dépendance est en dehors de la portée de l'instance (et donc non réactive), la propriété calculée ne sera __pas__ mise à jour.
539549

@@ -1396,7 +1406,7 @@ type: api
13961406
13971407
- **Détails :**
13981408
1399-
Un objet contenant les composants enfants ayant une référence `ref` enregistrée.
1409+
Un objet contenant des éléments du DOM et des composants, ayant des [attributs `ref`](#ref) enregistrée.
14001410
14011411
- **Voir aussi :**
14021412
- [Les refs des composants enfants](../guide/components.html#Les-refs-des-composants-enfants)
@@ -1859,21 +1869,18 @@ type: api
18591869
18601870
Attache un écouteur d'évènement à l'élément. Le type d'évènement écouté est indiqué comme argument. L'expression peut être soit un nom de méthode, soit une ligne d'instruction, ou simplement omise si des modificateurs sont présents.
18611871
1862-
À partir de la 2.4.0+, `v-on` supporte aussi la liaison à un objet de paires évènement/écouteur sans argument. Notez que lorsque vous utilisez la syntaxe objet, elle ne supporte aucun modificateur.
1863-
1864-
Quand utilisé sur un élément HTML standard, il écoute uniquement les [**évènements natifs du DOM**](https://developer.mozilla.org/fr/docs/Web/Events). Quand utilisé sur un élément personnalisé de composant, il écoute également les **évènements personnalisés** émis depuis ce composant enfant.
1872+
Quand utilisé sur un élément standard, il écoute uniquement les [**évènements natifs du DOM**](https://developer.mozilla.org/fr/docs/Web/Events). Quand utilisé sur un élément personnalisé de composant, il écoute également les **évènements personnalisés** émis depuis ce composant enfant.
18651873
18661874
Lorsque des évènements natifs du DOM sont écoutés, la méthode reçoit l'évènement natif comme unique argument. Si la valeur de la directive est une ligne d'instruction, l'instruction a accès à la propriété spéciale `$event` : `v-on:click="handle('ok', $event)"`.
18671875
1876+
À partir de la 2.4.0+, `v-on` supporte aussi la liaison à un objet de paires évènement/écouteur sans argument. Notez que lorsque vous utilisez la syntaxe objet, elle ne supporte aucun modificateur.
1877+
18681878
- **Exemple :**
18691879
18701880
```html
18711881
<!-- nom de méthode -->
18721882
<button v-on:click="faireCeci"></button>
18731883

1874-
<!-- syntaxe objet (2.4.0+) -->
1875-
<button v-on="{ mousedown: faireCeci, mouseup: faireCela }"></button>
1876-
18771884
<!-- ligne d'instruction -->
18781885
<button v-on:click="faireCela('hello', $event)"></button>
18791886
@@ -1900,6 +1907,9 @@ type: api
19001907
19011908
<!-- l'évènement click sera déclenché une seule fois maximum -->
19021909
<button v-on:click.once="faireCeci"></button>
1910+
1911+
<!-- syntaxe objet (2.4.0+) -->
1912+
<button v-on="{ mousedown: faireCeci, mouseup: faireCela }"></button>
19031913
```
19041914
19051915
Écouter des évènements personnalisés sur un composant enfant (le gestionnaire est appelé quand `mon-evenement` est émis depuis l'enfant):

src/v2/cookbook/adding-instance-properties.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ Si ce que vous voulez ajouter n'a rien à voir avec Vue spécifiquement, cela pe
165165
```js
166166
var App = Object.freeze({
167167
name: 'Mon App',
168-
description: '2.1.4',
168+
version: '2.1.4',
169169
helpers: {
170170
// Ceci est une version purement fonctionnelle
171171
// de la méthode $reverseText décrite plus haut

src/v2/cookbook/form-validation.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ Given a form of three fields, make two required. Let's look at the HTML first:
2121
</p>
2222

2323
<p>
24-
<label for="name">Name<label>
24+
<label for="name">Name</label>
2525
<input type="text" name="name" id="name" v-model="name">
2626
</p>
2727

2828
<p>
29-
<label for="age">Age<label>
29+
<label for="age">Age</label>
3030
<input type="number" name="age" id="age" v-model="age" min="0">
3131
</p>
3232

3333
<p>
34-
<label for="movie">Favorite Movie<label>
34+
<label for="movie">Favorite Movie</label>
3535
<select name="movie" id="movie" v-model="movie">
3636
<option>Star Wars</option>
3737
<option>Vanilla Sky</option>
@@ -93,17 +93,17 @@ For the second example, the second text field (age) was switched to email which
9393
</p>
9494

9595
<p>
96-
<label for="name">Name<label>
96+
<label for="name">Name</label>
9797
<input type="text" name="name" id="name" v-model="name">
9898
</p>
9999

100100
<p>
101-
<label for="email">Email<label>
101+
<label for="email">Email</label>
102102
<input type="email" name="email" id="email" v-model="email">
103103
</p>
104104

105105
<p>
106-
<label for="movie">Favorite Movie<label>
106+
<label for="movie">Favorite Movie</label>
107107
<select name="movie" id="movie" v-model="movie">
108108
<option>Star Wars</option>
109109
<option>Vanilla Sky</option>

src/v2/cookbook/serverless-blog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ type: cookbook
44
order: 5
55
---
66

7-
<p>Cette page est en cours de traduction. Pour nous aider, vous pouvez participer sur <a href="https://github.com/vuejs-fr/vuejs.org" target="_blank">le dépôt GitHub dédié de Vuejs-FR</a>.</p><p>So you've just launched your Vue.js website, congrats! Now you want to add a blog that quickly plugs into your website and you don't want to have to spin up a whole server just to host a Wordpress instance (or any DB-powered CMS for that matter). You want to just be able to add a few Vue.js blog components and some routes and have it all just work, right? What you're looking for a blog that's powered entirely by API's you can consume directly from your Vue.js application. This tutorial will teach you how to do just that, let's dive in!</p>
7+
<p>Cette page est en cours de traduction. Pour nous aider, vous pouvez participer sur <a href="https://github.com/vuejs-fr/vuejs.org" target="_blank">le dépôt GitHub dédié de Vuejs-FR</a>.</p><p>So you've just launched your Vue.js website, congrats! Now you want to add a blog that quickly plugs into your website and you don't want to have to spin up a whole server just to host a Wordpress instance (or any DB-powered CMS for that matter). You want to just be able to add a few Vue.js blog components and some routes and have it all just work, right? What you're looking for is a blog that's powered entirely by API's you can consume directly from your Vue.js application. This tutorial will teach you how to do just that, let's dive in!</p>
88

99
We're going to quickly build a CMS-powered blog with Vue.js. It uses [ButterCMS](https://buttercms.com/), an API-first CMS that lets you manage content using the ButterCMS dashboard and integrate our content API into your Vue.js app. You can use ButterCMS for new or existing Vue.js projects.
1010

src/v2/cookbook/unit-testing-vue-components.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ describe('Foo', () => {
162162
// assert the error is rendered
163163
expect(wrapper.find('.error').exists()).toBeTruthy()
164164

165-
// update the `username` and assert error is longer rendered
165+
// update the `username` and assert error is no longer rendered
166166
wrapper.setData({ username: 'Lachlan' })
167167
expect(wrapper.find('.error').exists()).toBeFalsy()
168168
})
@@ -178,7 +178,7 @@ The below example improves the test by:
178178

179179
- only making one assertion per `it` block
180180
- having short, clear test descriptions
181-
- providing only the minimum data requires for the test
181+
- providing only the minimum data required for the test
182182
- refactoring duplicated logic (creating the `wrapper` and setting the `username` variable) into a factory function
183183

184184
*Updated test*:

src/v2/cookbook/using-axios-to-consume-apis.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ new Vue({
124124
.catch(error => {
125125
console.log(error)
126126
this.errored = true
127-
}).
127+
})
128128
.finally(() => this.loading = false)
129129
}
130130
})
@@ -157,7 +157,7 @@ You can hit the rerun button on this pen to see the loading status briefly while
157157
<p data-height="300" data-theme-id="32763" data-slug-hash="6c01922c9af3883890fd7393e8147ec4" data-default-tab="result" data-user="Vue" data-embed-version="2" data-pen-title="Fourth Step Axios and Vue" class="codepen">See the Pen <a href="https://codepen.io/team/Vue/pen/6c01922c9af3883890fd7393e8147ec4/">Fourth Step Axios and Vue</a> by Vue (<a href="https://codepen.io/Vue">@Vue</a>) on <a href="https://codepen.io">CodePen</a>.</p>
158158
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
159159

160-
This can be even futher improved with the use of components for different sections and more distinct error reporting, depending on the API you're using and the complexity of your application.
160+
This can be even further improved with the use of components for different sections and more distinct error reporting, depending on the API you're using and the complexity of your application.
161161

162162
## Alternative Patterns
163163

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
---
2+
title: Custom Events
3+
type: guide
4+
order: 103
5+
---
6+
7+
> This page assumes you've already read the [Components Basics](components.html). Read that first if you are new to components.
8+
9+
## Event Names
10+
11+
Unlike components and props, event names don't provide any automatic case transformation. Instead, the name of an emitted event must exactly match the name used to listen to that event. For example, if emitting a camelCased event name:
12+
13+
```js
14+
this.$emit('myEvent')
15+
```
16+
17+
Listening to the kebab-cased version will have no effect:
18+
19+
```html
20+
<my-component v-on:my-event="doSomething"></my-component>
21+
```
22+
23+
Unlike components and props, event names will never be used as variable or property names in JavaScript, so there's no reason to use camelCase or PascalCase. Additionally, `v-on` event listeners inside DOM templates will be automatically transformed to lowercase (due to HTML's case-insensitivity), so `v-on:myEvent` would become `v-on:myevent` -- making `myEvent` impossible to listen to.
24+
25+
For these reasons, we recommend you **always use kebab-case for event names**.
26+
27+
## Customizing Component `v-model`
28+
29+
> New in 2.2.0+
30+
31+
By default, `v-model` on a component uses `value` as the prop and `input` as the event, but some input types such as checkboxes and radio buttons may want to use the `value` attribute for a [different purpose](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#Value). Using the `model` option can avoid a conflict in such cases:
32+
33+
```js
34+
Vue.component('base-checkbox', {
35+
model: {
36+
prop: 'checked',
37+
event: 'change'
38+
},
39+
props: {
40+
checked: Boolean
41+
},
42+
template: `
43+
<input
44+
type="checkbox"
45+
v-bind:checked="checked"
46+
v-on:change="$emit('change', $event.target.checked)"
47+
>
48+
`
49+
})
50+
```
51+
52+
Now when using `v-model` on this component:
53+
54+
```js
55+
<base-checkbox v-model="lovingVue"></base-checkbox>
56+
```
57+
58+
the value of `lovingVue` will be passed to the `checked` prop. The `lovingVue` property will then be updated when `<base-checkbox>` emits a `change` event with a new value.
59+
60+
<p class="tip">Note that you still have to declare the <code>checked</code> prop in component's <code>props</code> option.</p>
61+
62+
## Binding Native Events to Components
63+
64+
There may be times when you want to listen directly to a native event on the root element of a component. In these cases, you can use the `.native` modifier for `v-on`:
65+
66+
```html
67+
<base-input v-on:focus.native="onFocus"></base-input>
68+
```
69+
70+
This can be useful sometimes, but it's not a good idea when you're trying to listen on a very specific element, like an `<input>`. For example, the `<base-input>` component above might refactor so that the root element is actually a `<label>` element:
71+
72+
```html
73+
<label>
74+
{{ label }}
75+
<input
76+
v-bind="$attrs"
77+
v-bind:value="value"
78+
v-on:input="$emit('input', $event.target.value)"
79+
>
80+
</label>
81+
```
82+
83+
In that case, the `.native` listener in the parent would silently break. There would be no errors, but the `onFocus` handler wouldn't be called when we expected it to.
84+
85+
To solve this problem, Vue provides a `$listeners` property containing an object of listeners being used on the component. For example:
86+
87+
```js
88+
{
89+
focus: function (event) { /* ... */ }
90+
input: function (value) { /* ... */ },
91+
}
92+
```
93+
94+
Using the `$listeners` property, you can forward all event listeners on the component to a specific child element with `v-on="$listeners"`. For elements like `<input>`, that you also want to work with `v-model`, it's often useful to create a new computed property for listeners, like `inputListeners` below:
95+
96+
```js
97+
Vue.component('base-input', {
98+
inheritAttrs: false,
99+
props: ['label', 'value'],
100+
computed: {
101+
inputListeners: function () {
102+
var vm = this
103+
// `Object.assign` merges objects together to form a new object
104+
return Object.assign({},
105+
// We add all the listeners from the parent
106+
this.$listeners,
107+
// Then we can add custom listeners or override the
108+
// behavior of some listeners.
109+
{
110+
// This ensures that the component works with v-model
111+
input: function (event) {
112+
vm.$emit('input', event.target.value)
113+
}
114+
}
115+
)
116+
}
117+
},
118+
template: `
119+
<label>
120+
{{ label }}
121+
<input
122+
v-bind="$attrs"
123+
v-bind:value="value"
124+
v-on="inputListeners"
125+
>
126+
</label>
127+
`
128+
})
129+
```
130+
131+
Now the `<base-input>` component is a **fully transparent wrapper**, meaning it can be used exactly like a normal `<input>` element: all the same attributes and listeners will work.
132+
133+
## `.sync` Modifier
134+
135+
> New in 2.3.0+
136+
137+
In some cases, we may need "two-way binding" for a prop. Unfortunately, true two-way binding can create maintenance issues, because child components can mutate the parent without the source of that mutation being obvious in both the parent and the child.
138+
139+
That's why instead, we recommend emitting events in the pattern of `update:my-prop-name`. For example, in a hypothetical component with a `title` prop, we could communicate the intent of assigning a new value with:
140+
141+
```js
142+
this.$emit('update:title', newTitle)
143+
```
144+
145+
Then the parent can listen to that event and update a local data property, if it wants to. For example:
146+
147+
```html
148+
<text-document
149+
v-bind:title="doc.title"
150+
v-on:update:title="doc.title = $event"
151+
></text-document>
152+
```
153+
154+
For convenience, we offer a shorthand for this pattern with the `.sync` modifier:
155+
156+
```html
157+
<text-document v-bind:title.sync="doc.title"></text-document>
158+
```
159+
160+
The `.sync` modifier can also be used with `v-bind` when using an object to set multiple props at once:
161+
162+
```html
163+
<text-document v-bind.sync="doc"></text-document>
164+
```
165+
166+
This passes each property in the `doc` object (e.g. `title`) as an individual prop, then adds `v-on` update listeners for each one.
167+
168+
<p class="tip">Using <code>v-bind.sync</code> with a literal object, such as in <code>v-bind.sync="{ title: doc.title }"</code>, will not work, because there are too many edge cases to consider in parsing a complex expression like this.</p>

0 commit comments

Comments
 (0)