summaryrefslogtreecommitdiff
path: root/vue-notes.md
blob: 4c8fe41befadca2033e17a3674aa70454f2b65e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
---
LocalWords: Vue DOM JS
---

There are 4 primary pieces to the official Vue.js documentation:

 1. Guide
 2. API
 3. Style Guide
 4. Examples

The "Guide" is where concepts get introduced and explained; but fairly
little of the underlying machinery or details are explained; or it is
hard to find.  The "API" is where the machinery and details are
explained, but the concepts of how that fits together is missing; it
links to the Guide.

I think it's silly that those are 2 separate documents.

# Introduction

	import Vue from 'vue';

Vue (pronounced like "view") is a *progressive* framework for building
user interfaces; progressive means that you can use it for as much, or
as little, of the user interface as you like.

There are a few major object types in Vue that are helpful to
understanding Vue at a high-level:

 - *Vue Instances*: a Vue instance manages a part of the DOM.

 - *Components*: think of components as "custom HTML `<element>`s".
   An instance of a component is a type of Vue instance.  That is,
   your custom `<element>` obviously "owns" and manages the underlying
   real HTML elements in the DOM that are used to implement it.

 - *Directives*: think of directives as "custom HTML `attr="ibutes"`".

In addition to those objects:

 - *Reactive*: Each *component* has a "data" object associated with
   it; this is usually just a plain map Object.  If you (in the
   ordinary, plain, JS ways!) modify that object, the component will
   automatically *react* to that change, and update the DOM
   accordingly.

 - *Templates*: Vue has its own HTML templating language, that allows
   us to write markup such that Vue knows how to make it *reactive*.
   It's just plain HTML, but with (1) user-defined custom elements
   (via *components*), and (2) Vue-defined and user-defined custom
   attributes (via *directives*; the built-in Vue directives all start
   with `v-`).  If you don't like writing raw HTML, that's fine, you
   could write it via PUG or any other compile-to-HTML language, since
   Vue templates are *just HTML*.  From the JavaScript, they are just
   plain strings.

 - *Render functions*: Ultimately, *templates* compile to render
   functions.  If your application design and toolchain
   (WebPack/Babel/what-have-you) allow it, this can be done
   ahead-of-time as a server-side optimization step before being
   served to the client, or it can happen at runtime by calling
   `Vue.compile("template string")`, which returns a function.
   Anyway, having render functions exposed to programmers means that,
   if you want, you can write the render functions yourself, instead
   of writing templates.  Programmers coming from React will note that
   JSX is useful for writing render functions.

Tying it together: A *component* is mostly just a *Vue instance* that
manages its part of the DOM by calling a *render function* (compiled
from a *template*) in accordance with an object that the component is
assigned to be *reactive* to.

The premise of Vue is that this small set of objects and concepts
gives us the tools to effectively write dope-ass parts of a
user-interface, without requiring is to use Vue to do the entire
interface (though you could).

# IDK what section this belongs in.

Components don't work by literally registering custom elements with
the browser (though a W3C spec exists for allowing that, it isn't
(yet?) widely implemented).  Instead, it's the *template language*
that knows about them, the custom element names are registered with
the template compiler, and the compiler then knows that when it
encounters a node with that element name, it needs to emit a render
function that instantiates that component.  Ditto for directives.

THE ABOVE IS FALSE.  The render function calls
`something.createElement("element-name")`, the components are
registered with the `createElement`; the compiler doesn't need to know
this.

## Reactivity

Because of limitations in JavaScript, when implementing the magical
reactivity that Vue provides, Vue can detect attribute *modification*,
but not adding or removing attributes.  Lame!  So, Vue provides us
with a couple of silly magic functions to work around this limitation:

 - `Vue.set(object, key, value);` is like `object[key] = value;`, except
   that if the `key` attribute doesn't exist yet, it is created as a
   reactive attribute, working around the limitation that Vue can't
   detect attribute additions.
   
 - `Vue.delete(object, key);` is like `delete object[key];`, but
   ensures that the deletion triggers view updates, working around the
   limitation that Vue can't detect attribute deletions.

## Configuration

 - Global: `Vue.config`
   * Development Settings
     * `Vue.config.silent` Bool
     * `Vue.config.devtools` Bool
	 * `Vue.config.warnHandler` Function
     * `Vue.config.performance` Bool
     * `Vue.config.productionTip` Bool
   * For-reals Settings
     * `Vue.config.optionMergeStrategies` Map<String,Function>
     * `Vue.config.errorHandler` Function
     * `Vue.config.ignoredElements` Array<String|RegExp>
	 * `Vue.config.keyCodes` Map<String,Number|Array<Number>>


 > Unfortunately, that's custom `<element></element>`s; with Vue
 > components, we can't use the `<element />` shorthand, or
 > implied-closing (like with `<li>`).

## Root Vue Instance

	var vm = new Vue({ ... });
	
> As a convention, it is common to use the variable name `vm` for the
> root Vue instance; `vm` stands for ViewModel; a reference to the
> [Model+View+ViewModel (MVVM)][MVVM] application architecture; but
> don't worry about MVVM, since from your point of view of, your Vue
> program won't be following MVVM; just accept it as an arbitrary
> convention.

To use it, you will need to *mount* the instance to the part of the
DOM that it will manage.

You can do this after-the-fact like:

	vm.$mount("css-selector"); // the first matching element will be used
	// or
	vm.$mount(HTMLElement);

Or, you can do it at instance creation by specifying `el`:

	var vm = new Vue({
		el: CSS-selector-or-HTMLElement,
	});

The mount-point element will be *replaced* with the Vue-generated DOM,
so it is therefore not recommended to mount the root instance to
`<html>` or `<body>`.

## Components

We define a component like

	var MyComponent = Vue.extend({ ... });

But that doesn't give it a name!  We'll need to register our component
with an HTML tag name.  We can do that globally with:

	Vue.component('tag-name', MyComponent);
	
 > Vue does not enforce the rules on component names that are there
 > for [W3C Custom Element][W3C Custom Elements] tag names
 > (all-lowercase, must contain a hyphen), but it is conventional to
 > follow them anyway, and is considered good practice.

Since it's so common to immediately register components, and not
otherwise use them directly in the JS, we have a bit of shorthand that
we can use for convenience:

	Vue.component('tag-name', Vue.extend({ ... }));
	// can be written as
	Vue.component('tag-name', { ... });
	// and it will automatically call Vue.extend for us

 > Wait, that didn't actually save us much typing, and obscured the
 > fact that component creation and registration are two distinct
 > operations.  Lame shorthand!
 
 If we want to be able to retrieve a component that we know is
 registered, but the current code doesn't have an object for, we can
 get it like:
 
	// returns the component previously registered to 'tag-name'
	var MyComponent = Vue.component('tag-name'); 

## Directives

## Mixins

# other

 * Global API
   - `Vue.nextTick`
   - `Vue.directive`
   - `Vue.filter`
   - `Vue.use`
   - `Vue.mixin`

   - `Vue.version` return the Vue version as a String



Vue instances may have a "render" function, or a "template".  I
believe that templates compile to a render function (via
`vue-template-compiler`), either at run-time, or at bundle-time if
possible.

[MVVM]: https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel
[W3C Custom Elements]: https://www.w3.org/TR/custom-elements/#concepts