diff --git a/src/guide/instance.md b/src/guide/instance.md index dde7a251..24030e99 100644 --- a/src/guide/instance.md +++ b/src/guide/instance.md @@ -29,44 +29,46 @@ We'll talk about [the component system](TODO:components.html) in detail later. F ## Data and Methods -When a Vue instance is created, it adds all the properties found in its `data` object to Vue's **reactivity system**. When the values of those properties change, the view will "react", updating to match the new values. +When a Vue instance is created, it adds all the properties found in its `data` to Vue's **reactivity system**. When the values of those properties change, the view will "react", updating to match the new values. ```js // Our data object -const data = { a: 1 }; +const data = { a: 1 } // The object is added to a Vue instance const vm = Vue.createApp().mount({ - data: { - a: 1 + data() { + return data } }) // Getting the property on the instance // returns the one from the original data -vm.a === data.a; // => true +vm.a === data.a // => true // Setting the property on the instance // also affects the original data -vm.a = 2; -data.a; // => 2 +vm.a = 2 +data.a // => 2 ``` When this data changes, the view will re-render. It should be noted that properties in `data` are only **reactive** if they existed when the instance was created. That means if you add a new property, like: ```js -vm.b = "hi"; +vm.b = 'hi' ``` Then changes to `b` will not trigger any view updates. If you know you'll need a property later, but it starts out empty or non-existent, you'll need to set some initial value. For example: ```js -data: { - newTodoText: '', - visitCount: 0, - hideCompletedTodos: false, - todos: [], - error: null +data() { + return { + newTodoText: '', + visitCount: 0, + hideCompletedTodos: false, + todos: [], + error: null + } } ``` @@ -74,14 +76,18 @@ The only exception to this being the use of `Object.freeze()`, which prevents ex ```js const obj = { - foo: "bar" -}; + foo: 'bar' +} -Object.freeze(obj); +Object.freeze(obj) -const vm = Vue.createApp().mount({ - data: obj - },'#app' +const vm = Vue.createApp().mount( + { + data() { + return obj + } + }, + '#app' ) ``` @@ -96,10 +102,16 @@ const vm = Vue.createApp().mount({ In addition to data properties, Vue instances expose a number of useful instance properties and methods. These are prefixed with `$` to differentiate them from user-defined properties. For example: ```js -const data = { a: 1 }; -const vm = Vue.createApp().mount({ - data: data -}, '#example'); +const vm = Vue.createApp().mount( + { + data() { + return { + a: 1 + } + } + }, + '#example' +) vm.$data.a // => 1 ``` @@ -115,16 +127,20 @@ Each Vue instance goes through a series of initialization steps when it's create For example, the [`created`](TODO:../api/#created) hook can be used to run code after an instance is created: ```js -Vue.createApp().mount({ - data: { - a: 1 +Vue.createApp().mount( + { + data() { + return { + a: 1 + } + }, + created() { + // `this` points to the vm instance + console.log('a is: ' + this.a) // => "a is: 1" + } }, - created() { - // `this` points to the vm instance - console.log("a is: " + this.a); - } -}, '#app'); -// => "a is: 1" + '#app' +) ``` There are also other hooks which will be called at different stages of the instance's lifecycle, such as [`mounted`](TODO:../api/#mounted), [`updated`](TODO:../api/#updated), and [`destroyed`](TODO:../api/#destroyed). All lifecycle hooks are called with their `this` context pointing to the Vue instance invoking it. diff --git a/src/guide/introduction.md b/src/guide/introduction.md index ab6f04d2..a83e6694 100644 --- a/src/guide/introduction.md +++ b/src/guide/introduction.md @@ -14,20 +14,20 @@ If you are an experienced frontend developer and want to know how Vue compares t Installation -::: tip +::: tip The official guide assumes intermediate level knowledge of HTML, CSS, and JavaScript. If you are totally new to frontend development, it might not be the best idea to jump right into a framework as your first step - grasp the basics then come back! Prior experience with other frameworks helps, but is not required. ::: The easiest way to try out Vue.js is using the [JSFiddle Hello World example](https://jsfiddle.net/chrisvfritz/50wL7mdz/). Feel free to open it in another tab and follow along as we go through some basic examples. Or, you can create an index.html file and include Vue with: -``` html +```html ``` or: -``` html +```html ``` @@ -38,43 +38,51 @@ The [Installation](installation.md) page provides more options of installing Vue At the core of Vue.js is a system that enables us to declaratively render data to the DOM using straightforward template syntax: -``` html +```html
{{ message }}
``` -``` js + +```js const App = { - data: { - message: 'Hello Vue!' + data() { + return { + message: 'Hello Vue!' + } } } Vue.createApp().mount(App, '#app') ``` + We have already created our very first Vue app! This looks pretty similar to rendering a string template, but Vue has done a lot of work under the hood. The data and the DOM are now linked, and everything is now **reactive**. How do we know? Change the `message` property in the code snippet below to a different value. You the rendered example update accordingly: ![placeholder sandbox link](https://codesandbox.io/s/xenodochial-meninsky-rxlt4) In addition to text interpolation, we can also bind element attributes like this: -``` html +```html
- Hover your mouse over me for a few seconds - to see my dynamically bound title! + Hover your mouse over me for a few seconds to see my dynamically bound + title!
``` -``` js + +```js const App2 = { - data: { - message: 'You loaded this page on ' + new Date().toLocaleString() + data() { + return { + message: 'You loaded this page on ' + new Date().toLocaleString() + } } } Vue.createApp().mount(App2, '#app-2') ``` + Here we are encountering something new. The `v-bind` attribute you are seeing is called a **directive**. Directives are prefixed with `v-` to indicate that they are special attributes provided by Vue, and as you may have guessed, they apply special reactive behavior to the rendered DOM. Here, it is basically saying "keep this element's `title` attribute up-to-date with the `message` property on the Vue instance." @@ -82,20 +90,24 @@ Here we are encountering something new. The `v-bind` attribute you are seeing is It's easy to toggle the presence of an element, too: -``` html +```html
Now you see me
``` + ```js const App3 = { - data: { - message: 'You loaded this page on ' + new Date().toLocaleString() + data() { + return { + message: 'You loaded this page on ' + new Date().toLocaleString() + } } } Vue.createApp().mount(App3, '#app-3') ``` + This 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](TODO) when elements are inserted/updated/removed by Vue. @@ -104,7 +116,7 @@ You can change `seen` from `true` to `false` in the sandbox below to check the e There are quite a few other directives, each with its own special functionality. For example, the `v-for` directive can be used for displaying a list of items using the data from an Array: -``` html +```html
  1. @@ -113,66 +125,81 @@ There are quite a few other directives, each with its own special functionality.
``` -``` js + +```js const App4 = { - data: { - todos: [ - { text: 'Learn JavaScript' }, - { text: 'Learn Vue' }, - { text: 'Build something awesome' } - ] + data() { + return { + todos: [ + { text: 'Learn JavaScript' }, + { text: 'Learn Vue' }, + { text: 'Build something awesome' } + ] + } } } Vue.createApp().mount(App4, '#app-4') ``` + ## Handling User Input To let users interact with your app, we can use the `v-on` directive to attach event listeners that invoke methods on our Vue instances: -``` html +```html

{{ message }}

``` -``` js + +```js const App5 = { - data: { - message: 'Hello Vue.js!' + data() { + return { + message: 'Hello Vue.js!' + } }, methods: { reverseMessage() { - this.message = this.message.split('').reverse().join('') + this.message = this.message + .split('') + .reverse() + .join('') } } } Vue.createApp().mount(App5, '#app-5') ``` + Note that in this method we update the state of our app without touching the DOM - all DOM manipulations are handled by Vue, and the code you write is focused on the underlying logic. Vue also provides the `v-model` directive that makes two-way binding between form input and app state a breeze: -``` html +```html

{{ message }}

- +
``` -``` js + +```js const App6 = { - data: { - message: 'Hello Vue!' + data() { + return { + message: 'Hello Vue!' + } } } Vue.createApp().mount(App6, '#app-6') ``` + ## Composing with Components @@ -183,7 +210,7 @@ The component system is another important concept in Vue, because it's an abstra In Vue, a component is essentially a Vue instance with pre-defined options. Registering a component in Vue is straightforward: we create a component object as we did with `App` objects and we define it in parent's `components` option: -``` js +```js // Define a new component called todo-item const TodoItem = { template: '
  • This is a todo
  • ' @@ -209,7 +236,7 @@ Now you can compose it in another component's template: But this would render the same text for every todo, which is not super interesting. We should be able to pass data from the parent scope into child components. Let's modify the component definition to make it accept a [prop](TODO:components.html#Props): -``` js +```js const TodoItem = { props: ['todo'], template: '
  • {{ todo.text }}
  • ' @@ -218,7 +245,7 @@ const TodoItem = { Now we can pass the todo into each repeated component using `v-bind`: -``` html +```html