Everything You Need To Know About Vue.js Cheat Sheet

Table of content

  • Interpolations
    • Simple interpolation
    • Interpolation with expression
      • Simple expression interpolation
      • Ternary operator expression interpolation
    • Raw HTML interpolation
  • Binding
    • Simple binding
    • Binding with concat
    • Conditional binding
  • Two-way data binding
  • Events
  • Dynamic arguments
    • Dynamic arguments by object
  • Computed properties
  • Watchers
  • Conditional render
    • Toggle display conditional rendering
  • List rendering
    • Array rendering
    • Object rendering
    • Iterate in range
  • Lifecycle hooks
    • Before create hook
    • Created hook
    • Before mount hook
    • Mounted hook
    • Before update hook
    • Updated hook
    • Before destroy hook
    • Destroyed hook
  • Events
    • Available events
    • Event modifiers
      • Stop modifier
      • Prevent modifier
      • Capture modifier
      • Once modifier
      • Self modifier
      • Passive modifier
    • Key modifiers
      • Enter key modifier
      • Tab key modifier
      • Delete key modifier
      • Esc key modifier
      • Space key modifier
      • Up key modifier
      • Down key modifier
      • Right key modifier
      • Left key modifier
      • Home key modifier
      • End key modifier
      • Ctrl key modifier
      • Alt key modifier
      • Shift key modifier
      • Meta key modifier
      • Custom key modifier
    • Key modifiers combination
    • Exact key modifier
  • Components
    • Single file component
    • Registering components
      • Global component registration
      • Instance scoped component registration
      • Lazy load component registration
    • Component props
    • Component slots
      • Simple slot
      • Named slots
      • Scoped slots
  • Mixins
    • Mixin option merging
    • Global mixins
  • Custom directives
    • Custom global directives
  • Filters
    • Global filters
  • Router
    • Getting started with router
      • Router installation
      • Defining routes
    • Router links
    • Advanced routing
      • Dynamic routes
        • Reacting to dynamic routes param changes
      • 404 route
      • Asterisk routes
    • Named routes
      • Named routes with params
    • Programmatic navigation
      • Programmatic named navigation
      • Programmatic navigation with params
    • Route redirection
      • Route named redirection
      • Dynamic route redirection
      • Route redirection with params
    • Route alias
  • Force re-rendering
  • Watching nested data
  • Custom components with v-model support
  • Functional component

Interpolations

Interpolation means putting or rendering your data which is possible very easily using Vue’s double-mustache syntax.

Simple interpolation

By using double-mustache syntax you can render your data:

<span>My name is: {{ myName }}</span>

Interpolation with expression

Interpolations can contain simple expressions in Vue.

Simple expression interpolation

You can also use JavaScript expressions inside double-mustaches:

<span>I'm {{ myAge + 5 }} years old!</span>

You can also use methods to manipulate your data and return an string or integer to be rendered:

<span>My pets' names are {{ myPets.join(", ") }}</span>

Ternary operator expression interpolation

You can also use ternary operator to have a simple conditional rendering:

<span>I'm a {{ myAge > 50 ? 'kinda old' : 'young' }}!</span>

Note:

  • You can only use one expression inside double-mustaches
  • An expression is different than a statement. For example the code below won’t work because it is not and expression, but a statement:
<!--THIS IS WRONG-->
{{ let msg = 'Hello World!'; }}

  • Flow control is not supported in double-mustaches:
<!--THIS IS WRONG-->
{{ if(true) { return 'Yes!' } }}

Raw HTML interpolation

If you don’t want to escape your data and render it as real HTML use the v-html directive:

<span v-html="myHTMLData"></span>

Warning: Rendering HTML can be risky since it can cause into XSS attacks on your website.

Binding

Binding means using your data inside your tag’s attributes.

Simple binding

Something wrong that new Vue developers try to do is putting a data into a attribute like this:

<span class="{{ myClass }}"></span>

But this is wrong and you actually have to bind it:

<span v-bind:class="myClass"></span>

There is a shorter way of binding which is by omitting v-bind directive, like below:

<span :class="myClass"></span>

Binding with concat

So what if you want to combine some string with your data when binding? Well use put your string inside of quotes and concat it as usual:

<span :class="myClass + 'test'"></span>

This can really be useful by using it inside hyperlinks:

<a :href="baseURL + '/post/' + postId">Read more</a>

The example above is a good example of a link to the post including the base URL and the post suffix and then the post id.

Conditional binding

You can use bindings to conditionally do something.

For the attributes which don’t have a value like disabled or required if your bound data return true the attribute will be added and if returns false the attribute won’t be added to the element.

<button :disabled="true"></button>

You can also use expressions which return boolean:

<button :disabled="password.length < 6"></button>

You can use an object inside the class attribute in order to bind the specified class if the condition is met:

<div :class="{green: true, red: false}"></div>

In the example above green class will be added to our div but not red.
You can use comparison and logical operators as well:

<div :class="{green: 5 > 1, red: false && 9 < 16}"></div>

Two-way data binding

By using the v-model directive you can create a two-way data binding. Which means the user can change the data using an input and see the result simultaneously if needed.

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

let app = new Vue({
    el: '#app',
    data: {
        message: ''
    }
});

The v-model directive can work on almost every input type.

Events

Events are called when a specific action is performed on an element.
Events are declared with v-on directive.

<div id="app">
    <button v-on:click="callMyfunction"></button>
</div>

let app = new Vue({
    el: '#app',
    methods: {
        callMyfunction() {
            alert('This is it!');
        }
    }
});

When a click is performed on this button it will call the callMyFunction method.

You can use anonymous functions as well:

<button v-on:click="() => alert('Hello my friend')"></button>

There is shorthand for events as well:

<button @click="() => alert('Hello my friend')"></button>

Dynamic arguments

Imagine when you want to have an attributes name evaluated. Well this is possible by doing like below:

<div v-bind:[myAttribute]="myData"></div>

You can also have an events name dynamically attached:

<div v-on:[myEvent]="doSomething"></div>

Dynamic arguments by object

There is also a way of binding dynamic arguments by using an object and JavaScript’s native dynamic key syntax, like below:

<button v-on="{[myAttr]: true}">Click on me if you can</button>

let app = new Vue({
    el: '#app',
    data: {
        myAttr: 'disabled'
    }
});

This can be used on events as well:

<button v-on="{[myEvent]: function() { alert("Hello world!") }}">Hi</button>

let app = new Vue({
    el: '#app',
    data: {
        myEvent: 'click'
    }
});

Computed properties

Computed properties are a way of cleaning your code and use them instead of expressions inside of your double-mustaches or other places.

Imagine you have the code below:

<p>
The best programming languages are: {{ programmingLanguages }}<br>
But the worst are: {{ programmingLanguages.split(', ').reverse().join(', ') }}
</p>

Instead you can define a computed property like below and use it instead of worst programming languages:

<p>
The best programming languages are: {{ programmingLanguages }}<br>
But the worst are: {{ worstProgrammingLanguages }}
</p>

let app = new Vue({
    el: '#app',
    data: {
        programmingLangauges: 'JavaScript, C#, PHP, Python, LALALA, HOHOHO'
    }
    computed: {
        worstProgrammingLanguages() {
            return this.programmingLangauges.split(', ').reverse().join(', ');
        }
    }
});

The order is not real and I’m not judging any programming language. It is just for demonstration.

Computed properties are getters which means they only return something and have no role in setting the data.

You can change this behaviour and set both set and get methods for a data, like below:

let app = new Vue({
    el: '#app',
    data: {
        myFirstName: 'Adnan',
        myLastName: 'Babakan'
    }
    computed: {
        myFullName: {
            get(): {
                return this.myFirstName + ' ' + this.myLastName;
            },
            set(v): {
                let parts = v.split(' ');
                this.myFirstName = parts[0];
                this.myLastName = parts[1];
            }
        }
    }
});

The code above will split the string by space and set the first part as first name and the second part as the last name when you are trying to set a data to myFullName but when getting the data it will concat first name and last name.

Watchers

A more generic way of knowing when a data changes is by using watchers.

let app = new Vue({
    el: '#app',
    data: {
        myAge: 19
    }
    watch: {
        myAge(v) {
            console.log('I\'m now ' + v);
        }
    }
});

Note: Watchers don’t manipulate data unless you want.

Conditional rendering

A conditional rendering is used when you want to display parts of your UI according to some condition(s).

<span v-if="isUserLoggedIn">Hello user</span>
<span v-else>Hi guest!</span>

Your conditions can have an ‘else-if’ as well:

<span v-if="favoriteColor === 'red'">Red like apple</span>
<span v-if="favoriteColor === 'blue'>Blue like sky</span>
<span v-else>Hmmm....</span>

Vue is smart and will only replace the parts that are different.
For example if you have a an input for logging in by email or username switching between two parts by condition won’t erase and re-render that input and user’s inputted value won’t be deleted:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address">
</template>

Though, by using key you can tell Vue that these fields are completely different and you should re-render them:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>

Toggle display conditional rendering

By using v-show you render the element but hide it (setting the display property to none) like this:

<span v-show="true">Hello there!</span>

Note: v-show doesn’t support the <template> element, nor does it work with v-else.

Note: v-if is lazy which means the block with false condition at the beginning won’t be rendered, on the other hand v-show actually renders but hides the block.

List rendering

Rendering a list of data is almost like looping in other programming languages.

Array rendering

Often it happens you want to iterate around an array and render them.
This is possible by using v-for directive:

<ul id="example-1">
  <li v-for="item in items">
    {{ item.message }}
  </li>
</ul>

var example1 = new Vue({
  el: '#example-1',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
});

You can also pass a second argument to access the index of current item:

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ index }} - {{ item.message }}
  </li>
</ul>

var example2 = new Vue({
  el: '#example-2',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
});

Object rendering

Object rendering is no harder than array rendering:

<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>

new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
});

You can also have access to the name of the property using the second argument:

<ul id="v-for-object" class="demo">
  <div v-for="(value, name) in object">
    {{ name }}: {{ value }}
  </div>
</ul>

new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
});

Accessing to the index is also available when iterating around an object:

<ul id="v-for-object" class="demo">
  <div v-for="(value, name, index) in object">
    {{ index }}. {{ name }}: {{ value }}
  </div>
</ul>

new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
});

Iterate in range

Iterating in a range of numbers is also pretty easy:

<div>
  <span v-for="n in 10">{{ n }} </span>
</div>

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.

Mixins

To be simple, mixins are just parts of your component stored in a separate file son it can be used again in other components.

A mixin can look like this:

// define a mixin object
export const myMixin = {
  created: function () {
    this.hello()
  },
  methods: {
    hello: function () {
      console.log('Hello from mixin!')
    }
  }
}

As you see this has a created hook and a method called hello so now this mixing can be used in a component, like below:

<script>
    import { myMixin } from './myMixin.js';
    export default {
        mixins: [myMixin]
    }
</script>

So this will function as if you wrote those hooks and methods in this component.

Mixin option merging

Well in case of any conflicts between a components self-assigned properties or methods and the mixin’s, the component it self will be in priority, see this:

let mixin = {
  data: function () {
    return {
      message: 'hello',
      foo: 'abc'
    }
  }
}

new Vue({
  mixins: [mixin],
  data: function () {
    return {
      message: 'goodbye',
      bar: 'def'
    }
  },
  created: function () {
    console.log(this.$data)
    // => { message: "goodbye", foo: "abc", bar: "def" }
  }
})

The way Vue handles overwriting can be changed but we will cover that in the other cheat sheet.

Global mixins

A global mixin is no different than a normal mixin rather than its affection scope which will include all Vue instances created.

import Vue from 'vue';

Vue.mixin({
    methods: {
        sayHi() {
            alert('Salam!');
        }
    }
});

const app = new Vue({
    el: '#app'
});

The method sayHi will be available for every component and Vue instance in the code above.

Custom directives

As you know directives are the way Vue handles DOM. For instance v-model or v-show are directives.

In order to define a directive you can do as below:

<script>
    export default {
        directives: {
            focus: {
                inserted: function (el) {
                    el.focus()
                }
            }
        }
    }
</script>

The focus directive will be available as v-focus and can be used like this:

<input v-focus />

So the input will be focused as soon as the component renders.

Custom global directives

In order for your custom directives to be available throughout your Vue instance and globally you can define it like below:

Vue.directive('focus', {
  inserted: function (el) {
    el.focus()
  }
})

Filters

Filters are simply used to alter a value and return it.
They can be used in both mustaches and v-bind directive.

To define a filter in a component you can de as below:

<script>
    export default {
        filters: {
            capitalize: function(value) {
                if (!value) return '';
                value = value.toString();
                return value.charAt(0).toUpperCase() + value.slice(1);
            }
        }
    };
</script>

Then the capitalize filter can be used as below:

<span>{{ msg | capitalize }}</span>

Or in a v-bind as below:

<a v-bind:href="url | capitalize">My capitalized link!</a>

Global filters

Global filters are no different than normal filters but they will be defined once and can be used in every Vue instance or component.

import Vue from 'vue';

Vue.filter('focus', {
    capitalize: function(value) {
        if (!value) return '';
        value = value.toString();
        return value.charAt(0).toUpperCase() + value.slice(1);
    }
});

Router

Vue router is used to design a routing system on the client-side using Vue.

Getting started with router

In order to start using the router you need to install it. These are steps:

Router installation

It is recommended to install it using npm:

npm i vue-router --save

It can be installed by including the file as well:

<script src="/path/to/vue.js"></script>
<script src="/path/to/vue-router.js"></script>

After installing it, it is time to tell Vue to use the router. To do so you can do as below:

import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

Your components which are bound to routes should be rendered somewhere in your page. This be declared as below:

<div id="app">
    <div>
        Hello World!
    </div>
    <router-view></router-view>
</div>

Defining routes

Each route will have its own unique component bound. You can define your routes as below:

const routes = [
  { path: '/foo', component: require('./path/to/foo/component') },
  { path: '/bar', component: require('./path/to/bar/component') }
];

const router = new VueRouter({
  routes // short for `routes: routes`
});

If you want yo push the routes to history of user’s browser you should activate the history mode as below:

const router = new VueRouter({
  mode: 'history',
  routes // short for `routes: routes`
});

And then attach your routes to your view instance:

const app = new Vue({
  router
}).$mount('#app');

Note: If you are using the history mode, in order to redirect all your requests to your index.html file so Vue can take care of rest of it you should configure your web server. Unless, by refreshing the browser on a page, it will return 404 since that page actually doesn’t exist on the server.

Router links

Router links are special since they don’t refresh the page but only getting the component that is needed (and push the URL to the history in history mode) so it seems like a new page.

Instead of a hyper-link (a tag) you should use router-link as below:

<router-link to="/foo">Go to foo</router-link>

Advanced routing

Vue router is beyond just few simple routes and it provides some great ways of handling routes.

Dynamic routes

Dynamic routes are used to match a series of routes with some params to be acquired.

A dynamic route is defined just like a normal route but with a colon at the beginning of the dynamic segment(s):

const routes = [
  { path: '/user/:username', component: require('./path/to/user/component') },
];

Now by the route above all of links such as /user/adnanbabakan, /user/dev/ or /user/vue is valid.

The username can be accessed in the route component as below:

<div>This is {{ $route.params.username }}'s profile!</a>

Reacting to dynamic routes’ param changes

Considering the example above. If the user moves from /user/adnanbabakan to /user/dev Vue won’t destroy the previous instance since it is already going to be the same component rendered again, thus the lifecycle hooks won’t be called in order to react to any params changes you can watch the $route object like
this:

<script>
  export default {
    watch: {
      $route(to, from) {

      }
    }
  };
</script>

404 route

Every website needs a great 404 route. In a Vue Router we can define an asterisk * route at the end so it catches everything that is not defined.

Warning: The asterisk route should be defined at the end and after any other route. Unless it will match everything else and ruin your routing system.

In order to do so look at the code below:

const routes = [
    // ... Any other routes ...
    { path: '*', component: require('./path/to/404/component') },
];

Asterisk routes

Asterisks can be used to match another kind of dynamic routes. A dynamic route can only match the dynamic segments between two slashes / but asterisk can do beyond that.

Look at the route below:

const routes = [
    { path: '/user-*', component: require('./path/to/user/component') },
];

So by the route above routes such as /user-adnan and /user-dev can be rendered.

By using the route below the $route.params will have a property called pathMatch which will include the part that matched the asterisk.
For example $route.params.pathMatch in the page /user-adnan will return adnan.

Named routes

Named routes are used to access long route pattern with their shorter name.

Imagine you have a pattern like this:

const routes = [
  {
    path: '/user/profile/setting/',
    component: require('./path/to/user/component')
  }
];

You can define a name for it like this:

const routes = [
  {
    path: '/user/profile/setting/',
    component: require('./path/to/user/component'),
    name: 'settings'
  }
];

Now your links can be like this:

<router-link :to='{name: "settings"}'>
    Profile settings
</router-link>

Instead of this:

<router-link to="/user/profile/setting/">
    Profile settings
</router-link>

Note: When passing an object to to attribute you should bind it.

Named routes with params

Some routes might have params as we had some examples above. You can define a name for them as well.

For example for the route below:

const routes = [
  {
    path: '/posts/from/:username',
    component: require('./path/to/posts/component'),
  }
];

You can have this:

const routes = [
  {
    path: '/posts/from/:username',
    component: require('./path/to/posts/component'),
    name: 'posts'
  }
];

And in order to create a link for this you can have the code below:

<router-link :to='{name: "posts", params: {username: "adnanbabakan"}}'>
    Profile settings
</router-link>

Programmatic navigation

As you read before in this cheat sheet you can create a router link using <router-link></router-link> but what if you needed to redirect user programmatically? Well you can do that by this code:

router.push('/foo');

This code will redirect your user to /foo. This is especially used in a condition or other situations like redirection after login.

Programmatic named navigation

You can also use router.push() for named routes like this:

router.push({name: 'myRoute'});

Programmatic navigation with params

As well, router.push() can be used for redirecting with params, like this:

router.push({name: 'myRoute', params: {paramOne: 'Hello', paramTwo: 'Salam'}});

Route redirection

Routes can be defined to be redirected to each other. Like this:

const routes = [
  {
    path: '/foo',
    redirect: '/bar'
  }
];

Route named redirection

A route can also be redirected to a named route, like this:

const routes = [
  {
    path: '/foo',
    redirect: { name: 'myRoute' }
  }
];

Dynamic route redirection

A route can be redirected using a function to evaluate the destination, like this:

const routes = [
  {
    path: '/foo',
    redirect: to => {
      // the function receives the target route as the argument
      // return redirect path/location here.
    }
  }
];

Route redirection with params

If the target route has a param it can be passed to the destination as well:

const routes = [
  {
    path: '/profile/:username',
    redirect: '/user/:username'
  }
];

Route alias

A route alias means a route can have multiple addressed to be accessed from.

For example:

const routes = [
  {
    path: '/foo',
    alias: '/bar'
  }
];

Now the route /foo can be accessed as /bar/ as well.

A route can have multiple aliases as well:

const routes = [
  {
    path: '/foo',
    alias: ['/bar', '/baz']
  }
];

Force re-rendering

In some cases, it is necessary to force Vue in order to re-render your component since it won’t track some changes.

There are some ways of doing so, such as using the v-if hack, but the correct way is by using forceUpdate method:

  export default {
    methods: {
      forceUpdateMyComponent() {
        this.$forceUpdate()
      },
    },
  }

Keep that in mind that $ is necessary to use this method in your Vue instance.
And you better be notified that this won’t update any computed property but only force the view of your component to be re-rendered.

Watching nested data

Sometimes you might need to watch some nested data you can do this using dot notation:

  export default {
    data() {
      return {
        myInfo: {
          firstName: 'Adnan'
        }
      }
    },
    watch: {
      'myInfo.firstName'() {
        console.log('Here');
      }
    }
  }

The code above is when you know which property inside your object to watch!
But what if you want to watch your whole object and also its values?

  export default {
    data() {
      return {
        myFruits: {apple: 'red', banana: 'yellow'},
      }
    },
    methods: {
      changeIt() {
        this.myFruits.apple = 'green'
      },
    },
    watch: {
      myFruits: {
        deep: true,
        handler() {
          console.log('Fruits updated!')
        },
      },
    },
  }

You can define your watch not as a function immediately but as an object, then by using the deep key and the value true watch your object and put what you want to be fired when the data got changed inside a function called handler.

Custom components with v-model support

As you know v-model is used to make a two-way binding with an input element/component and a data property.

If you are making a custom component and want it to support v-model you can emit the input keyword and in order to receive what is passed to your component initially with the v-model you simply need to get a prop called value.

For an easier comprehension check the code below:

<template>
    <div>
        <label>My custom test input: <input :value="inputValue" @input="emitTheData" /></label>
    </div>
</template>

<script>
  export default {
    props: ['value'],
    data() {
      return {
        inputValue: value
      }
    },
    methods: {
      emitTheData() {
        this.$emit('input', this.inputValue)
      }
    }
  }
</script>

This simple component will bind the data passed to it in two directions.

Note: As you can see, I assigned the prop called value to a data called inputValue and used it in my input, you might think that I could pass the prop directly to my input but as Vue suggests it is better not to alter props directly.

Functional component

Imagine having a component with no watch or computed property and no methods! You would only use it to render some other components as one with some props. If it is so then why waste Vue’s time when there are no lifecycle methods?

A functional component can be defined as below:

<template functional>
  <div>{{ props.foo }}</div>
</template>

Note: Keep in mind that there is no this context in these components since it is a functional component!

#vuejs #javascript #webdev

Everything You Need To Know About Vue.js Cheat Sheet
50.40 GEEK