|
1 |
| -# The Application Instance |
| 1 | +# Application & Component Instances |
2 | 2 |
|
3 |
| -## Creating an Instance |
| 3 | +## Creating an Application Instance |
4 | 4 |
|
5 | 5 | Every Vue application starts by creating a new **application instance** with the `createApp` function:
|
6 | 6 |
|
7 | 7 | ```js
|
8 |
| -Vue.createApp(/* options */) |
| 8 | +const app = Vue.createApp({ /* options */ }) |
9 | 9 | ```
|
10 | 10 |
|
11 |
| -After the instance is created, we can _mount_ it, passing a container to `mount` method. For example, if we want to mount a Vue application on `<div id="app"></div>`, we should pass `#app`: |
| 11 | +The application instance is used to register 'globals' that can then be used by components within that application. We'll discuss that in detail later in the guide but as a quick example: |
12 | 12 |
|
13 | 13 | ```js
|
14 |
| -Vue.createApp(/* options */).mount('#app') |
| 14 | +const app = Vue.createApp({}) |
| 15 | +app.component('SearchInput', SearchInputComponent) |
| 16 | +app.directive('focus', FocusDirective) |
| 17 | +app.use(LocalePlugin) |
15 | 18 | ```
|
16 | 19 |
|
17 |
| -Although not strictly associated with the [MVVM pattern](https://en.wikipedia.org/wiki/Model_View_ViewModel), Vue's design was partly inspired by it. As a convention, we often use the variable `vm` (short for ViewModel) to refer to our instance. |
18 |
| - |
19 |
| -When you create an instance, you pass in an **options object**. The majority of this guide describes how you can use these options to create your desired behavior. For reference, you can also browse the full list of options in the [API reference](../api/options-data.html). |
20 |
| - |
21 |
| -A Vue application consists of a **root instance** created with `createApp`, optionally organized into a tree of nested, reusable components. For example, a `todo` app's component tree might look like this: |
22 |
| - |
23 |
| -``` |
24 |
| -Root Instance |
25 |
| -└─ TodoList |
26 |
| - ├─ TodoItem |
27 |
| - │ ├─ DeleteTodoButton |
28 |
| - │ └─ EditTodoButton |
29 |
| - └─ TodoListFooter |
30 |
| - ├─ ClearTodosButton |
31 |
| - └─ TodoListStatistics |
32 |
| -``` |
33 |
| - |
34 |
| -We'll talk about [the component system](component-basics.html) in detail later. For now, just know that all Vue components are also instances, and so accept the same options object. |
35 |
| - |
36 |
| -## Data and Methods |
37 |
| - |
38 |
| -When an instance is created, it adds all the properties found in its `data` to [Vue's **reactivity system**](reactivity.html). When the values of those properties change, the view will "react", updating to match the new values. |
| 20 | +Most of the methods exposed by the application instance return that same instance, allowing for chaining: |
39 | 21 |
|
40 | 22 | ```js
|
41 |
| -// Our data object |
42 |
| -const data = { a: 1 } |
| 23 | +Vue.createApp({}) |
| 24 | + .component('SearchInput', SearchInputComponent) |
| 25 | + .directive('focus', FocusDirective) |
| 26 | + .use(LocalePlugin) |
| 27 | +``` |
43 | 28 |
|
44 |
| -// The object is added to the root instance |
45 |
| -const vm = Vue.createApp({ |
46 |
| - data() { |
47 |
| - return data |
48 |
| - } |
49 |
| -}).mount('#app') |
| 29 | +You can browse the full application API in the [API reference](../api/application-api.html). |
50 | 30 |
|
51 |
| -// Getting the property on the instance |
52 |
| -// returns the one from the original data |
53 |
| -vm.a === data.a // => true |
| 31 | +## The Root Component |
54 | 32 |
|
55 |
| -// Setting the property on the instance |
56 |
| -// also affects the original data |
57 |
| -vm.a = 2 |
58 |
| -data.a // => 2 |
59 |
| -``` |
| 33 | +The options passed to `createApp` are used to configure the **root component**. That component is used as the starting point for rendering when we **mount** the application. |
60 | 34 |
|
61 |
| -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: |
| 35 | +An application needs to be mounted into a DOM element. For example, if we want to mount a Vue application into `<div id="app"></div>`, we should pass `#app`: |
62 | 36 |
|
63 | 37 | ```js
|
64 |
| -vm.b = 'hi' |
| 38 | +const RootComponent = { /* options */ } |
| 39 | +const app = Vue.createApp(RootComponent) |
| 40 | +const vm = app.mount('#app') |
65 | 41 | ```
|
66 | 42 |
|
67 |
| -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: |
| 43 | +Unlike most of the application methods, `mount` does not return the application. Instead it returns the root component instance. |
68 | 44 |
|
69 |
| -```js |
70 |
| -data() { |
71 |
| - return { |
72 |
| - newTodoText: '', |
73 |
| - visitCount: 0, |
74 |
| - hideCompletedTodos: false, |
75 |
| - todos: [], |
76 |
| - error: null |
77 |
| - } |
78 |
| -} |
79 |
| -``` |
| 45 | +Although not strictly associated with the [MVVM pattern](https://en.wikipedia.org/wiki/Model_View_ViewModel), Vue's design was partly inspired by it. As a convention, we often use the variable `vm` (short for ViewModel) to refer to a component instance. |
80 | 46 |
|
81 |
| -The only exception to this being the use of `Object.freeze()`, which prevents existing properties from being changed, which also means the reactivity system can't _track_ changes. |
| 47 | +While all the examples on this page only need a single component, most real applications are organized into a tree of nested, reusable components. For example, a Todo application's component tree might look like this: |
82 | 48 |
|
83 |
| -```js |
84 |
| -const obj = { |
85 |
| - foo: 'bar' |
86 |
| -} |
| 49 | +``` |
| 50 | +Root Component |
| 51 | +└─ TodoList |
| 52 | + ├─ TodoItem |
| 53 | + │ ├─ DeleteTodoButton |
| 54 | + │ └─ EditTodoButton |
| 55 | + └─ TodoListFooter |
| 56 | + ├─ ClearTodosButton |
| 57 | + └─ TodoListStatistics |
| 58 | +``` |
87 | 59 |
|
88 |
| -Object.freeze(obj) |
| 60 | +Each component will have its own component instance, `vm`. For some components, such as `TodoItem`, there will likely be multiple instances rendered at any one time. All of the component instances in this application will share the same application instance. |
89 | 61 |
|
90 |
| -const vm = Vue.createApp({ |
91 |
| - data() { |
92 |
| - return obj |
93 |
| - } |
94 |
| -}).mount('#app') |
95 |
| -``` |
| 62 | +We'll talk about [the component system](component-basics.html) in detail later. For now, just be aware that the root component isn't really any different from any other component. The configuration options are the same, as is the behavior of the corresponding component instance. |
96 | 63 |
|
97 |
| -```html |
98 |
| -<div id="app"> |
99 |
| - <p>{{ foo }}</p> |
100 |
| - <!-- this will no longer update `foo`! --> |
101 |
| - <button v-on:click="foo = 'baz'">Change it</button> |
102 |
| -</div> |
103 |
| -``` |
| 64 | +## Component Instance Properties |
104 | 65 |
|
105 |
| -In addition to data properties, instances expose a number of useful instance properties and methods. These are prefixed with `$` to differentiate them from user-defined properties. For example: |
| 66 | +Earlier in the guide we met `data` properties. Properties defined in `data` are exposed via the component instance: |
106 | 67 |
|
107 | 68 | ```js
|
108 |
| -const vm = Vue.createApp({ |
| 69 | +const app = Vue.createApp({ |
109 | 70 | data() {
|
110 |
| - return { |
111 |
| - a: 1 |
112 |
| - } |
| 71 | + return { count: 4 } |
113 | 72 | }
|
114 |
| -}).mount('#example') |
| 73 | +}) |
115 | 74 |
|
116 |
| -vm.$data.a // => 1 |
| 75 | +const vm = app.mount('#app') |
| 76 | + |
| 77 | +console.log(vm.count) // => 4 |
117 | 78 | ```
|
118 | 79 |
|
119 |
| -In the future, you can consult the [API reference](../api/instance-properties.html) for a full list of instance properties and methods. |
| 80 | +There are various other component options that add user-defined properties to the component instance, such as `methods`, `props`, `computed`, `inject` and `setup`. We'll discuss each of these in depth later in the guide. All of the properties of the component instance, no matter how they are defined, will be accessible in the component's template. |
| 81 | + |
| 82 | +Vue also exposes some built-in properties via the component instance, such as `$attrs` and `$emit`. These properties all have a `$` prefix to avoid conflicting with user-defined property names. |
120 | 83 |
|
121 |
| -## Instance Lifecycle Hooks |
| 84 | +## Lifecycle Hooks |
122 | 85 |
|
123 |
| -Each instance goes through a series of initialization steps when it's created - for example, it needs to set up data observation, compile the template, mount the instance to the DOM, and update the DOM when data changes. Along the way, it also runs functions called **lifecycle hooks**, giving users the opportunity to add their own code at specific stages. |
| 86 | +Each component instance goes through a series of initialization steps when it's created - for example, it needs to set up data observation, compile the template, mount the instance to the DOM, and update the DOM when data changes. Along the way, it also runs functions called **lifecycle hooks**, giving users the opportunity to add their own code at specific stages. |
124 | 87 |
|
125 | 88 | For example, the [created](../api/options-lifecycle-hooks.html#created) hook can be used to run code after an instance is created:
|
126 | 89 |
|
127 | 90 | ```js
|
128 | 91 | Vue.createApp({
|
129 | 92 | data() {
|
130 |
| - return { |
131 |
| - a: 1 |
132 |
| - } |
| 93 | + return { count: 1 } |
133 | 94 | },
|
134 | 95 | created() {
|
135 | 96 | // `this` points to the vm instance
|
136 |
| - console.log('a is: ' + this.a) // => "a is: 1" |
| 97 | + console.log('count is: ' + this.count) // => "count is: 1" |
137 | 98 | }
|
138 | 99 | })
|
139 | 100 | ```
|
|
0 commit comments