Introduction
Mastering Vue is an advanced take on building applications with Vue. The book takes the readers on a vuetiful journey of creating an app, undertaking a progressive learning approach. We begin with a minimal starter app and incrementally improve it throughout the book. We shall introduce new topics as required and discuss in detail before using in the example application. It focuses on real-world use, and we will consider every tool available to Vue ecosystem in detail.
For developers new to Vue, this chapter will provides an adequate base to work throughout the book and help you mastering Vue. We focus on following fundamentals:
What is Vue?
What is a Vue application?
Life cycle of a Vue application.
What is declarative rendering?
How to use template syntax?
Using programming logic in templates.
Handling events and form input.
What is component composition?
What are directives, mixins and filters?
What is Vue?
Vue (pronounced /vjuː/, like view) is user interface library built with high regards to developer experience and performance. The creator, Evan You, advertises it as a progressive framework. Progressive (aka continuing or developing); the core (hereafter referred as Vue) is just a view layer library, but with supporting libraries crafted to be incrementally adoptable, it creates a sense of framework.
It is first and foremost approachable. There is no need to scaffold a project, to learn new syntax or to set up complicated environment configuration. Add a script tag on an HTML page, and we are using Vue.
Along with approachability, it is versatile enough to serve reactive needs of a portion of a page to a full-blown enterprise application. It starts with declarative rendering and reactivity as base building blocks, then as the application grows, include features like client-side routing, shared state management, animations, server rendering and much more.
With user attention span growing shorter and shorter, modern applications strive to be fast. Vue's small size and blazing fast virtual DOM and reactivity system enable performance at scale.
A Vue Application
A Vue application is a component tree mounted to a DOM element. Components are building blocks of a Vue application. Functionally they are very much similar to HTML elements; we will know more about them in the following section.
Let us create a small Vue application. We would use jsfiddle.net for all examples in this chapter. The editor of jsfiddle.net has four sections:
HTML: Contents are used as markup in
<body>
.CSS: Styles are inlined in the
<head>
.JavaScript: Appended after the contents of HTML section.
Result: Renders preview of the above created webpage.
Let get to coding. Open jsfiddle.net.
First and foremost, we need Vue in our fiddle. We would be using Vue from a CDN service like JSDeliver or Unpkg. Go ahead and add the following code in HTML section.
Now, We have Vue
constructor available globally. Let's create a simple application. Put the following script in JavaScript section.
Hit Run button to preview the application. In Result section, we would find a "Hello World" printed. Just like that, we have created our first Vue application. (jsfiddle.net/znck/bvasvc32)
Let's break it up and understand what is happening.
We create an instance of
Vue
.The
el
property above is a selector string, and the target element of this selector is the mount point of our application. A Vue instance when mounted to a DOM element, renders content into the mount point and keeps DOM in sync with the application state.The inner content of
<div>
with idapp
is the template for the application.
Go ahead and inspect the page, we would find that Vue replaces the mount point (<div id="app">
) with the rendered content.
The Vue Instance
In above example, we created a Vue instance to demonstrate a "Hello World" application. Every application starts by creating an instance of Vue. The Vue constructor accepts an options object.
The options are same as component API except some root specific options. We will talk about these options in advanced components chapter. Next we will look into reactive state and life-cycle of Vue instance.
Data and Methods
When a Vue instance is created, it includes all the data
option properties found in the reactivity system and also surfaces them as instance properties.
The data
option properties are reactive.
Only the data
properties present at the time of instance creation are reactive.
Frozen objects are also not reactive.
In addition to surfacing data
properties, Vue instance exposes some useful instance properties and methods. These are prefixed with $
to prevent any possible collision with user-defined data
properties.
Similar to data
, all methods
properties are also surfaced as instance methods and bound to this
context of the Vue instance.
Life-cycle Hooks
A Vue instance on creation goes through a series of initialization steps, e.g., observe data, compile template, mount instance into the DOM, update DOM when data changes. It is possible to execute custom logic at specific stages using special functions called life-cycle hooks. Following are the hooks called at different stages of Vue instance:
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed
The life-cycle hooks are invoked with their this
context pointing to the Vue instance calling it.
Getting Started
Before diving into the world of Vue applications, we will look into the very fundamentals.
Declarative Rendering
The core function of Vue is declaratively rendering data/state into the page DOM. Let's try a quick example. (jsfiddle.net/znck/xtv4c5mg)
The data
property defines the state of the application. The values defined in data
property are available on the instance, i.e., app.name
is 'John'
. The template renders in the data scope of the instance, i.e., when say name
, it is name
property of the data part of the component.
We use the mustache syntax to use the state in our template. We see the page has text as "Hello John".
It may look similar to template processors like handlebars, but there is a lot more going on here. The data and DOM are bound together and it's reactive, i.e., if we update name
, it would reflect in the DOM. Let's try this out, append following snippet to above script.
Here, we set the name to 'Jane' after 3 seconds. We would see that the text on the page would change from "Hello John" to "Hello Jane". We can use component state in the template, and the page would update when the state changes. In the next section, we will explore the template syntax in detail.
Template Syntax
Vue uses HTML-based template syntax which can be parsed by spec-complaint browsers and parsers. The template is declarative way of rendering application state into DOM node.
The template is converted to JavaScript render function which in turn generates virtual DOM. When state changes, the reactivity system figures outs the effected components and the re-render is triggered to generate new virtual DOM nodes. Vue compares the new virtual DOM nodes with the old virtual DOM tree to find a minimum number of DOM changes.
The template syntax extends HTML with following features:
Interpolations
Interpolations
Interpolation allows binding of javascript variables and expressions to DOM. The template syntax provides two ways of data binding.
Text
The "Mustache" like syntax allows putting any javascript expression as text.
The value of msg
property from data part of the component replaces the mustache tag, i.e., if msg
is "Say hello!", then the rendered DOM would have <span>Message: Say hello!</span>
.
The expressions in mustache tag can be any valid javascript expression. For example:
Vue processes the expression in the mustache tag in the data scope of the corresponding component. Hence, msg
property should be part of the data object of the corresponding component. It also sanitizes the evaluated value of the expression to prevent possible XXS vulnerabilities.
Moreover, the expressions are sandboxed and only have access to few whitelisted globals such as Math
and Date
.
The mustaches interpret data as plain text, but there are times when we want to interpolate some HTML string, Vue has special syntax for these situations; v-html
directive. We will discover more about it in the next section.
Attributes
The mustache syntax interpolation is not possible inside HTML attributes. We use a directive (v-bind
) for binding data to HTML attributes.
In above example, we are binding the someClassName
expression to class
attribute. Generically, we can write v-bind:<attribute>="<expression>"
is the syntax for binding HTML attributes.
The attribute binding behavior for boolean properties is slightly different. If the expression evaluates to a falsy value, then the attribute will not be included in the rendered DOM. null
, undefined
, and false
, all are falsy values.
Directives
The directives are specific attributes with v-
prefix. The directive syntax is as follows:
Examples:
A directive has a name, an optional argument, one or more optional modifiers and an optional expression. The directive name is unique kebab cased string. If we want to name our directive my-awesome-directive
, then the directive would be v-my-awesome-directive
is the attribute name to use the directive.
The expression is a javascript expression same as in text interpolation and attributes binding.
Argument
A directive can accept an argument, denoted by a colon after the directive name. For example, the v-bind
directive binds data to HTML attributes.
Here src
is the argument. v-bind
uses the argument to determine that src
attribute of <img>
tag should be the value of the expression url
.
Modifiers
The modifiers are boolean values which directives may use to enable or disable the provided features.
For example, when we use the v-on
directive with the .prevent
modifier, it calls event.preventDefault()
on the triggered event.
Built-in Directives
v-text
v-text
updates the element's textContent
. In behavior, it is same as the mustache syntax for text interpolation. It sanitizes the value of the expression before setting it as the textContent
.
Example:
v-html
v-html
updates the element's innerHTML
. It inserts the value of the expression as innerHTML
of the target element.
Example:
Dynamically rendering arbitrary HTML can be very dangerous as it may lead to XSS attacks. Use `v-html` only on trusted content and never on user-provided content.
v-show
v-show
toggles the element's visibility by setting display
CSS property. For a falsy value of the expression, it hides the element.
Example:
When the value of isInvalid
is false, it would add style display: none
to the <span>
element.
This directive triggers transitions when its expression value changes. We will discuss transitions in later chapters.
v-if
v-if
renders the element based on the truthy-ness of the expression value. The element and its child components and contained directives are destroyed and re-created during toggles.
Example:
When the value of isInvalid
is false, v-if
directive removes the element <span>
from the DOM and destroys it.
This directive triggers transitions when its expression value changes.
v-else
v-else
provides else block to v-if
and v-else-if
directives. The element with v-else
directive should appear immidiately after the element with v-if
or v-else-if
directive.
Example:
v-else-if
v-else-if
provides conditional chain. The element with v-else-if
directive should appear immediately after the element with v-if
directive.
Example:
We will explore v-if
, v-else
and v-else-if
directives in detail in conditional rendering section.
v-for
v-for
renders the element or template block multiple times based on the source data.
Example:
We will explore v-for
directive in detail in list rendering section.
v-on
v-on
attaches an event listener to the element.
Example:
The v-on
directive is used very often, so Vue provides a shorthand syntax for it. We can use @click
instead of v-on:click
.
We will explore v-on
directive in detail in event handling section.
v-bind
v-bind
dynamically binds one or more attributes or component props.
Example:
The v-bind
directive is used very often, so Vue provides a shorthand syntax for it. We can use :src
instead of v-bind:src
.
The v-bind
directive provides following modifiers:
.prop
- Bind as a DOM property instead of an attribute. If the element tag is a component, then it will set the DOM property on the component's$el
element..camel
- Transform kebab-case attribute name into camelCase..sync
- A syntax sugar that expands into av-on
handler to update the bound value. By convention, the update event isupdate:<property>
. For example:
v-model
v-model
is syntax sugar for binding value with v-bind
and v-on
handler to update the bound value. It creates a two-way binding on a form input element or a component.
Example:
We will explore v-model
directive in detail in form input handling section.
v-pre
v-pre
skips interpolation of the element and its children.
Example:
v-cloak
v-cloak
will remain on the element until the associated Vue instance finishes compilation. It can be used to hide un-compiled mustache binding until the Vue instance is ready when using in-DOM templates.
v-cloak
should be combined with CSS rules such as [v-cloak] { display: none; }
.
v-once
v-once
will render the element or component only once and on subsequent renders the element or component and its children are treated as static content. Using v-once
on large DOM trees can optimize the update performance.
Example:
Conditional Rendering
Programming languages have if statement for conditionally executing some part of the code. Vue has a similar construct for conditionally rendering some part of the template. The v-if
, v-else
, v-else-if
and v-show
directives instruct Vue to conditionally render elements.
The <h1>
element is rendered when the expression firstTimeUser
is true.
We can use v-else
directive to add else block.
The element with `v-else` directive should appear immediately after the element with `v-if` or `v-else-if` directive.
The v-else-if
directive allows multiple conditional blocks.
The element with `v-else-if` directive should appear immidately after the element with `v-if` or `v-else-if` directive.
Conditional Groups
A directive can be attached to a single element. However, when we need to toggle more than one element, we can use <template>
element. The <template>
element serves as a transparent wrapper, and the final result does not include it.
Controlling Reusable Elements
Whenever possible, Vue re-uses elements when rendering conditional blocks which makes Vue very fast. We can take advantage of these re-used elements, e.g. <input>
element preserves the entered text as the element is re-used.
As both templates use same elements, the elements are re-used and <input>
preserves its value. Only the placeholder
attribute is updated.
The re-use of the element is not always desirable though; we should add a key
attribute with unique values to tell Vue not to re-use the element.
In above example, if we do not use key
attribute on <img>
element then we would see a flash of the old image.
Conditionally Displaying Elements
We may use v-show
directive for optionally displaying an element.
The v-show
conditional rendering is different from v-if
. With v-show
, the element is always rendered. It only toggles the display
CSS property of the element.
The `v-show` directive does not support `` element.
Comparing v-show with v-if
v-if
is conditional rendering. For false condition, it does not render the element at all. The event listeners and child components inside the conditional block are destroyed and re-created during toggles. It also renders lazily, if the condition is false on initial render, it will skip the render and won't render until the condition becomes true.
v-show
does not affect the rendering behavior. Depending upon the expression value, it toggles display
CSS property to hide or show the element.
v-if
has higher toggle cost compared to v-show
. So prefer v-show
when the condition toggles very often.
List Rendering
List of messages in a chat application, list of products in an online store, list of articles in a blog. Rendering a list of elements is the most common task in real-world applications. The v-for
directive allows to iterate over lists and render HTML elements.
Example:
Results:
Batman Begins
The Dark Knight
The Dark Knight Rises
The v-for
directive requires a special syntax for expression in the form of movie in movies
, where movies
is the source array and movie
is an alias for the current array element.
The v-for
expression also supports an optional second argument for the index of the current array element.
Results:
1 - Batman Begins
2 - The Dark Knight
3 - The Dark Knight Rises
The v-for
directive also works with objects.
Result:
firstName = John
lastName = Doe
email = john@example.com
When iterating an object with `v-for` directive, the order is same as enumeration order of `Object.keys()` which is **not** guaranteed to be consistent across javascript engines.
The v-for
directive can take an integer as a source, in this case, it will repeat the element that many times. For example:
The v-for
directive can be attached to a <template>
element to render a list of multiple elements. For example:
The v-for
directive has higher priority than v-if
directive and when they exist on the same node, v-if
would execute on each iteration of the loop. The higher priority of v-for
can be useful when we want to render only some items. For example:
The above template renders only unwatched movies.
Computed properties should be preferred over `v-for` - `v-if` combo, whenever only some items from the list need to be rendered.
If the intent is to skip execution of the loop then we can place v-if
on a wrapper element (or <template>
). For example:
Controlling Reusable Elements
Vue uses in-place patch as default strategy when v-for
list items are rerendered. If the order of items has changed, instead of rearranging DOM elements, Vue will patch each element in-place to match the order of the items.
In-place patch is efficient, but only suitable when the list render output does not rely on child component state or temporary DOM state (e.g., form input values). We should add a key
attribute with unique values to help Vue tracking identity of the rendered elements.
It is recommended to provide a key
with v-for
whenever possible unless the iterated DOM is simple.
Array Change Detection
Vue wraps on observed array's mutation methods so they will also trigger view updates. The wrapped methods are:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
Other methods which do not mutate the original array do not trigger any updates. Non-mutating methods always return a new array. When working with these methods, the old array should be replaced with new one.
When an array is replaced with another array, Vue uses heuristics to maximize DOM element reuse, and the replacement operation is very efficient when two arrays contain overlapping items.
Caveats
There are few cases when Vue cannot detect changes to an array:
When an item is set with the index, e.g.,
app.items[index] = newValue
We can use
splice()
method for this.
Alternatively, Vue offers a method to set array items with indices.
When the length of the array is modified, e.g.,
app.items.length = newLength
We can use
splice()
method for this.
Object Change Detection
Vue wraps an observed object with a proxy object using getters and setters, so it triggers view updates if any property changes.
app.a
is now reactive. Updating app.a
would trigger view update.
Caveats
There are few cases when Vue cannot detect changes to an object:
When a new property is added to the object:
app.b
is not reactive and Vue does not allow adding new root-level properties to an already created instance. However, it is possible to add new reactive properties to a nested object using the Vue.set(object, key, value)
method. For example:
When some new properties are added to the object:
Using
Vue.set()
for a couple of new properties can be verbose, we may want to useObject.assign()
or_.extend()
. Do not extend or assign observed object in-place.
In such cases, it is recommended to create a fresh object with properties from both the objects.
Event Handling
User interactions on a webpage trigger DOM events. These events let us know if some element is clicked or the input field is focused, or the form is submitted.
We can use the v-on
directive to listen to DOM event. For example:
In above example, v-on
binds the inline expression with DOM click event and whenever the button is clicked, the counter
property is incremented by 1.
In practice, the logic for event handlers is more complicated and it is not possible to keep that much code in the v-on
expression. We should put the event handler logic in a method and use method name as v-on
expression. For example:
The inline v-on
expression has access to the original DOM event. The DOM event can be accessed using $event
variable. For example:
There is a shorthand syntax for v-for
, instead of v-on:click
, we may use @click
. For example:
Event Modifiers
The v-on
directive provides some useful modifiers. These modifiers can perform common tasks, and our event handler would be purely about data logic rather than dealing with DOM event quirks.
Following modifiers are available for v-on
directive:
.stop
- callevent.stopPropagation()
..prevent
- callevent.preventDefault()
..once
- trigger event listner at most once..self
- trigger event listner only when target element is the element itself..capture
- add event listner in capture mode..passive
- add event listner in passive mode.
The order of modifiers is important as the relevant code is generated in same order. For example, `@click.prevent.self` will prevent all clicks while `@click.self.prevent` will only prevent the clicks on the element.
Key Modifiers
When listening to keyboard event, we often look for specific keys are pressed or not. The v-on
provides modifiers to bind event listeners to particular keys.
We may use keyCode
as v-on
modifier.
The built-in key modifiers are as follows:
.delete
(captures both "Delete" and "Backspace" keys).enter
.esc
.space
.tab
.up
.down
.left
.right
Moreover, we may define aliases for other keys using global config.keyCodes
object.
In modern browsers, v-on
directive offers automatic key modifiers. We may use any valid key name exposed via KeyboardEvent.key
as modifiers by converting them to kebab-case.
System Key Modifiers
These modifiers can be used with keyboard or mouse events. They trigger the listener only when the corresponding modifier key is pressed.
Following are system key modifiers corresponding to the system keys:
.ctrl
.alt
.shift
.meta
Example:
v-on
has the .exact
modifier which ensures the exact combination of the system modifiers to trigger the event listener. For example:
Mouse Button Modifiers
These modifiers can be used to restrict mouse events to a specific mouse button.
Following are mouse button modifiers:
.left
.right
.middle
Form Input Handling
We use the v-model
directive to create two-way data bindings on form elements. It automatically pics the correct way to update the element based on the input type. For example:
The v-model
directive may seem magical, but in reality, it is syntax sugar for updating the bound value on user input events, though it handles some edge cases too. Above example can be written as follows:
Input Types
Let's open jsfiddle.net and try out following examples.
Text
Multiline Text
Checkbox
A single checkbox bound to a boolean value:
Multiple checkboxes bound to the same Array:
Radio
Select
Single select:
Multiple select:
Single select:
Dynamic options rendered with v-for
:
If the initial value of the `v-model` expression does not match with any of the options, the `` element will render it an "unselected" state. It is recommended to provide a disabled option with an empty value, as demonstrated in the above examples.
Value Binding
We can bind custom value on a radio input, a checkbox, or a select option.
Checkbox
When checked, the value of confirm
property would be 'yes'
, and for the unchecked state it would be 'no'
.
Radio
When checked, app.pick
is equal to app.a
.
Select
When selected, app.choose
is equal to { number: 123 }
.
Modifiers
v-model
provides following modifiers:
.lazy
- By defaultv-model
syncs the input with data after eachinput
event, when.lazy
modifier is used, it syncs afterchange
event..number
- Typecast value as a number. This modifier is useful with inputtype="number"
as the HTML input element always returns a string..trim
- It trims trailing and leading spaces of the value.
Input Components
v-model
directive can be used with components too. The component should accept value
prop and emit input
event to support v-model
. We will explore input components in detail in next section.
Components
Components are custom elements that encapsulate reusable code and extend HTML elements. They are also Vue instances, and so accept the same options object and provide the same lifecycle hooks.
Registration
We can use Vue.component(tag, options)
method to register components. Components registered using this method are available globally.
Example:
Above app would render:
We may use components
instance option to register the component in the scope of the instance/component.
When using the DOM as the template (e.g., using `el` option to mount an element with existing content), there are some restrictions as Vue can only retrieve template after the browser had parsed and normalized the HTML contents of the page. The most prominent restrictions are constraints on what elements can appear in ``, ``, `` and `` elements. As a workaround, Vue uses `is` attribute to tell the actual component to be rendered for the element. For example: ```html ``` **These limitations do not apply when using string templates from one of the following sources:** - `` - JavaScript inline template strings - Single file components (`.vue` file)</p>
Composition
Components are meant to be in similar fashion to HTML elements. However, there is an inevitable need for communication between components. However, it very important to keep components decoupled so the component's code can be written and reasoned in isolation.
In Vue, the parent and child components communicate using props and events. The parent component passes data down to child components via props, and the child component sends messages to the parent component via events.
API
A component is like a black box. It hides all its implementation details from other components. Components need to communicate with each other to compose an application. The component exposes following interfaces to facilitate inter-component communication:
Props
A prop is a custom attribute for receiving information from the parent component. Props allow the external environment to pass data to the component. The component needs to declare the props it expects explicitly. We use the props
option to do so.
For example:
When using the <child>
component, we pass the message
prop as following:
We can bind props using v-bind
directive or the shorthand form.
Props are read-only, so they cannot be mutated, and Vue would throw warnings in the console if we try to mutate them.
The component can specify prop requirements and validate them. We define props with validation requirements using object syntax. For example:
In above example, the prop
one
has a type check. It should be numeric. The prop type can beString
,Number
,Boolean
,Function
,Object
,Array
,Symbol
or any constructor with whichinstanceof
assertion can be made.two
accepts multiple types. It can be a string or a number.three
should get a string value. It is a necessary prop when missed Vue would throw an error.four
should be a number, and it has a default value of 1000. The default value is used if parent component does not provide value for propfour
.five
should be an object. It defines default value as factory function. For props of typeObject
,Array
,Function
and user-defined classes, a factory function is required for the default value.six
defines a custom validator. The incoming prop value should pass the custom validation.
All non-prop attributes passed by the parent component will be added to component's root element. For example:
The data-extra-attr
attribute would be added to the root element of <child>
component.
As HTML attributes are case-insensitive, so when using non-string templates, camelCased prop names should be used as their kebab-case equivalents. For example: ```js Vue.component('child', { props: ['myMessage'], template: `{{ myMessage }}` }) ``` ```html ```
Events
Component events are similar to native DOM events. Events allow the component to trigger side effects in the external environment.
The Vue events interface:
$on(eventName, listener)
for listening to an event.$emit(eventName, payload)
for triggering an event.
A parent component can use v-on
to listen to the events emitted from child components.
Example:
In this example, <my-counter>
component emits increment
events. The parent component listens to increment
events and updates the value total
accordingly.
Slots
Slots are holes in a component which receive content from the parent component. The process of interweaving the parent content and the component's template is called content distribution. Slots allow the external environment to compose the component with extra content.
Vue implements a content distribution API modeled after the current web components spec draft, using the <slot>
element to serve as distribution outlets.
Types of slots:
Default slot - The content (without slot attribute) from parent component replace the default slot. This slot serves as a catch-all outlet. For example, we have a component called
<my-component>
with the following template:
Following markup of the parent component that uses <my-component>
component:
Then the result will be:
Named slot - The content with from parent component with slot attribute same as the slot name replace the named slot. This slot act as an outlet for the content fragment that has corresponding
slot
attribute. For example, we have a component called<app>
with the following template:
Parent markup:
Then the result will be:
Scoped slot - This slot serves as a reusable template. It can be default or named. The child component passes data to the parent component. The parent component renders content with data from child component and passes it down for distribution.
For example, we have a component called
<my-component>
with the following template:
Parent markup:
Then the result will be:
The compilation scope of slots can be confusing. A simple rule for scope is: **Everything in the parent template is compiled in parent scope; everything in the child template is compiled in child scope.**
Types of Components
Component with template
A Vue component should have a template or a render function. The template can be added to a component in multiple ways. For example, following is component with string template.
In-DOM Template
The component in above example can also be written using an in-DOM template.
X-Template
X-Template is another way of the in-DOM template. However, x-template does not suffer from HTML parsing issues.
Inline Template
Component with render function
We may provide a render function instead of a template.
Following is the same component as above with plain javascript render function.
We may use JSx too.
Single File Component
SFC or Single File Component is the preferred way of writing Vue components in medium to large project. Each SFC is separate file with .vue
extension.
Functional Component
A functional component is a stateless and instance-less component.
Example:
When using SFC, we can create template-based functional components.
Async Component
Vue allows defining component as a factory function that asynchronously resolved the component definition. The factory function is called when the component is needed for rendering, and the result will be cached for future re-renders.
Async components can be paired with webpack's code-splitting feature.
The async component factory can return a Promise
too, so with webpack 2 + ES2015 syntax we can do:
The async component factory can return an object in the following format:
This component renders the <LoadingComponent>
while the async component is loading. If the async component fails to load within the defined timeout
period, <ErrorComponent>
is rendered. If the component is loaded, it is rendered after the defined delay
period.
Input Component
Recursive Component
A component can be used recursively if it is registered globally or if it provides name
option.
A recursive component can result in an infinite recursive invocation. Make sure the recursion is wrapped with v-if
that will eventually be false
.
Circular Component
While building something like a file directory, we may end up having a circular component dependency.
For example, we have Directory.vue
component with the following template:
The DirectoryContents.vue
component with the following template:
The module system sees that it needs Directory.vue
, however, first Directory.vue
needs DirectoryDetails.vue
, but DirectoryDetails.vue
needs Directory.vue
, however, Directory.vue
needs DirectoryDetails.vue
, etc., etc. It is stuck in a loop, not knowing how to resolve either component without first resolving the other fully. To fix this, we need to give the module system a point at which it can say, “Directory.vue
needs DirectoryDetails.vue
, however, there’s no need to resolve DirectoryDetails.vue
first.”
It can be achieved by making following change to DirectoryDetails.vue
:
Now Directory
in DirectoryDetails.vue
is an async component which would be resolved at runtime.
Custom Directives
Mixins
Filters
Last updated