Hey there DEV.to community!
So this is the second part of my previous Vue cheat sheet.
Some descriptions and code samples are from Vue.js official website. Visit Vue.js
There is a Japanese version of this article available at https://qiita.com/_masa_u/items/44db6af7dc0bc48bcc14 Thanks to
Enjoy!
Table of content
- Lifecycle hooks
- Events
- Components
Lifecycle hooks
Lifecycle hooks are simply some functions that run on a specific event/time during your Vue component.
Before create hook
Called synchronously immediately after the instance has been initialized, before data observation and event/watcher setup.
Sample:
let app = new Vue({
beforeCreate() {
console.log('I\'m not created yet');
}
});
Created hook
Called synchronously after the instance is created. At this stage, the instance has finished processing the options which means the following have been set up: data observation, computed properties, methods, watch/event callbacks. However, the mounting phase has not been started, and the $el property will not be available yet.
Sample:
let app = new Vue({
created() {
console.log('I\'m created');
}
});
Before mount hook
Called right before the mounting begins: the render function is about to be called for the first time.
Note: This hook is not called during server-side rendering.
Sample:
let app = new Vue({
beforeMount() {
console.log('Let\'s begin!');
}
});
Mounted hook
Called after the instance has been mounted, where el
is replaced by the newly created vm.$el
. If the root instance is mounted to an in-document element, vm.$el
will also be in-document when mounted is called.
Note: This hook is not called during server-side rendering.
Sample:
let app = new Vue({
mounted() {
console.log('I\'m ready!');
}
});
Before update hook
Called when data changes, before the DOM is patched. This is a good place to access the existing DOM before an update, e.g. to remove manually added event listeners.
Note: This hook is not called during server-side rendering, because only the initial render is performed server-side.
Sample:
let app = new Vue({
beforeUpdate() {
console.log('Your DOM is about to change. Be careful!');
}
});
Updated hook
Called after a data change causes the virtual DOM to be re-rendered and patched.
The component’s DOM will have been updated when this hook is called, so you can perform DOM-dependent operations here. However, in most cases you should avoid changing state inside the hook. To react to state changes, it’s usually better to use a computed property or watcher instead.
Note: This hook is not called during server-side rendering.
Sample:
let app = new Vue({
updated() {
console.log('Hello new DOM!');
}
});
Before destroy hook
Called right before a Vue instance is destroyed. At this stage the instance is still fully functional.
Note: This hook is not called during server-side rendering.
Sample:
let app = new Vue({
beforeDestroy() {
console.log('Well it\'s the time I think...');
}
});
Destroyed hook
Called after a Vue instance has been destroyed. When this hook is called, all directives of the Vue instance have been unbound, all event listeners have been removed, and all child Vue instances have also been destroyed.
Note: This hook is not called during server-side rendering.
Sample:
let app = new Vue({
destroyed() {
console.log('BOOOOM!');
}
});
Events
Events are called when a specific action is performed on an element.
In the previous Vue cheat sheet I described them really basically. Here I will describe more aspects of events.
Keep in mind that @
is a short hand of v-on:
.
Available events
By using v-on
you can access all JavaScript events. These are some samples:
<button @click="() => alert('Hello')">Do it</button>
<button @mouseover="() => alert('Hello')">Do it</button>
<button @mouseout="() => alert('Hello')">Do it</button>
<button @contextmenu="() => alert('Hello')">Do it</button>
You can also submit
event on forms:
<form @submit="() => alert('This form is submitted')">
<input type="text" />
</form>
Event modifiers
Event modifiers are used to alter some behaviour of the event or have a more control on it.
Modifiers are added following by a .
after the event.
So this is the structure v-on:event.modifier
or @event.modifier
.
Modifiers can also be chained to be performed at the respective order, like: @event.modifier-one.modifier-two
Stop modifier
<!-- the click event's propagation will be stopped -->
<a v-on:click.stop="doThis"></a>
Prevent modifier
<!-- the submit event will no longer reload the page -->
<form v-on:submit.prevent="onSubmit"></form>
Capture modifier
<!-- use capture mode when adding the event listener -->
<!-- i.e. an event targeting an inner element is handled here before being handled by that element -->
<div v-on:click.capture="doThis">...</div>
Once modifier
<!-- the click event will be triggered at most once -->
<a v-on:click.once="doThis"></a>
Self modifier
<!-- only trigger handler if event.target is the element itself -->
<!-- i.e. not from a child element -->
<div v-on:click.self="doThat">...</div>
Passive modifier
<!-- the scroll event's default behavior (scrolling) will happen -->
<!-- immediately, instead of waiting for `onScroll` to complete -->
<!-- in case it contains `event.preventDefault()` -->
<div v-on:scroll.passive="onScroll">...</div>
Key modifiers
Listening to keyboards event is easy but detecting which key is pressed would need the key code. Vue has some modifiers in order to listen to a specific key when using keyboard events.
These modifiers can be used with any key events such as keydown
or keyup
Enter key modifier
<input @keydown.enter="() => alert('Hey there!')"></input>
Tab key modifier
<input @keydown.tab="() => alert('Hey there!')"></input>
Delete key modifier
<input @keydown.delete="() => alert('Hey there!')"></input>
Esc key modifier
<input @keydown.esc="() => alert('Hey there!')"></input>
Space key modifier
<input @keydown.space="() => alert('Hey there!')"></input>
Up key modifier
<input @keydown.up="() => alert('Hey there!')"></input>
Down key modifier
<input @keydown.down="() => alert('Hey there!')"></input>
Right key modifier
<input @keydown.right="() => alert('Hey there!')"></input>
Left key modifier
<input @keydown.left="() => alert('Hey there!')"></input>
Home key modifier
<input @keydown.home="() => alert('Hey there!')"></input>
End down key modifier
<input @keydown.end="() => alert('Hey there!')"></input>
Ctrl down key modifier
<input @keydown.ctrl="() => alert('Hey there!')"></input>
Alt down key modifier
<input @keydown.alt="() => alert('Hey there!')"></input>
Shift down key modifier
<input @keydown.shift="() => alert('Hey there!')"></input>
Meta down key modifier
<input @keydown.meta="() => alert('Hey there!')"></input>
Custom key code
If Vue doesn't provide an alias for the key you want, you can use its key code as below:
<input @keydown.49="() => alert('Hey there!')"></input>
Key code 49 is for the number 1 on top of keyboard. (Not the number pad)
Key modifiers combination
You can chain key modifiers in order to create a combined structure, like this:
<input @keydown.ctrl.shift="() => alert('Hey there!')"></input>
Exact key modifier
Using exact
will allow you to capture the button you need and nothing else can be combined.
By using the code below if you hold shift and press ctrl it will respond normally:
<input @keydown.ctrl="() => alert('Hey there!')"></input>
But by using the code below the only key which should be pressed is ctrl:
<input @keydown.exact.ctrl="() => alert('Hey there!')"></input>
Components
Components are reusable Vue instances used to simplify your code and split your code in a better manner.
This is a Vue component:
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
As you can it has its template embedded in it as well as the data it uses and can be used in other Vue components like this:
<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
This will render three different buttons which has nothing to do with each other. Each of them will function separately and each has its own count
data.
Important: When defining a component the data
should be a function returning an object if not each instance won't have its own data and it will be shared.
Single file component
A single file component (or SFC) is a component which is in one file (holy crap! really?).
It has more clean syntax and it is as below:
<template>
<div>
</div>
</template>
<script>
export default {
};
</script>
<style scoped>
</style>
Registering components
By registering components you can use them inside your templates.
Global component registration
By doing this method your component will be available in every Vue instance (in case you have more than one):
import Vue from 'vue';
Vue.component('my-component', require('/path/to/your/component'));
Instance scoped registration
By doing this the component will only be available in the specified Vue instance:
import Vue from 'vue';
const myComponent = require('/path/to/your/component');
let app = new Vue({
components: {
myComponent
}
});
Lazy load component registration
This method is pretty cool since it will not bundle your component with your main entry file thus your website will be loaded faster and only the needed components will be required.
import Vue from 'vue';
const myComponent = () => import('./components/myComponent ');
let app = new Vue({
components: {
myComponent
}
});
Bonus Tip: This will extract your components named by numbers from 0 and so on. If you are using webpack you can use a magic comment in order to change your components' file names like below:
import Vue from 'vue';
const myComponent = () => import(/* webpackChunkName: "myComponent" */ './components/myComponent ');
let app = new Vue({
components: {
myComponent
}
});
Component props
Components can have props which act literally like HTML tags' attributes.
By having a component like this:
Vue.component('blog-post', {
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
You can use it like this:
<blog-post post-title="hello!"></blog-post>
Note: When defining props it is better to define it using camelCase but when using it, use it as kebab-case. Although it is possible to use kebab-case defined props as camelCase in Vue but IDEs might get confused about it.
Your single file components can also have props:
<template>
<div>
</div>
</template>
<script>
export default {
props: ['myProp'];
};
</script>
<style scoped>
</style>
Component slots
Slots are used to embed other elements or components inside a component.
Simple slot
A simple slot is an unnamed slot and is used like below in a template:
<a :href="url" class="strange-class"><slot></slot></a>
After defining the template above assuming that the component name is navigation-link
and url
is a prop, you can use it as below:
<navigation-link url="/my-profile">Your profile</navigation-link>
As you see we have a text inside of our components and that is going to be inserted instead of <slot></slot>
.
Named slots
Named slots are a little different than an unnamed one.
By defining a component called base-layout
like this:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
You can use it like this:
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
The templates with v-slot:slot-name
will be placed in their respective slots defined in the component and other ones will be placed in <slot></slot>
which is unnamed.
Note: An unnamed slot is actually accessible with the name default
like below:
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<template v-slot:default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
Scoped slots
A slot can have access to its parents prop in order to avoid such a thing (if needed) you can define a slot prop like below:
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
And when using:
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
This slot will use the user
available in the component and not the one available in the parent component.
Check out my free Node.js Essentials E-book here:
Top comments (0)