Reference Guide: Vue.js Single File Components

Oct 29, 2019

Create file Hello.vue

<template>  <div>    <div class="greet">Hello {{ item.name }} ({{ nameUpper }})</div>    <div>      <input v-model="nickName" placeholder="Nick name">      Hi {{ nickName }}    </div>    <div>      <button @click="increment">{{ count }}</button>      <a href="#" @click.prevent="increment">{{ count }}</a>    </div>    <div>    <a :href="url">Google</a> -    <a :href="url + '?q=' + q">Query</a> -    <a :href="buildUrl()">Build Query</a>    </div>  </div></template><script>export default {  name: 'hello',    // optional  props: ['item'],  data() {    return {      nickName: '',      count: 0,      url: 'https://www.google.com/search',      q: 'hello'    }  },  computed: {    nameUpper() {      return this.item.name.toUpperCase()    }  },  methods: {    increment() {      this.count += 1    },    buildUrl() {      return `${this.url}?q=${this.q}`    }  }}</script><style scoped lang="scss">.greet {  font-size: 2rem;  font-weight: bold;}</style>

Single Root Elemnt

<template>  <div>    ...  </div></template>

Styles

<template>  <div class="greet">Hello {{ item.name }}</div></template><style scoped lang="scss">.greet {  font-size: 2rem;  font-weight: bold;}</style>

NOTE: Use scoped: CSS will apply to elements of the current component only.

NOTE: lang="scss" to use Scss instead of CSS.

Passing Data via Props / Use Component

Pass in data from Parent

<template>  <div>    <hello :item="{name: 'Desmond', age: 40}" />  </div></template><script>// @ is an alias to /srcimport Hello from '@/components/Hello.vue'export default {  name: 'home',  components: {    Hello  }}</script>

NOTE: In template, you can refer to the component via kebab-case (component-name) or PascalCase (ComponentName).

Receiving data in Child

<template>  <div>    Hello {{ item.name }}  </div></template><script>export default {  props: ['item']}</script>

Click event / Methods

<template>  <div>    <button @click="increment">{{ count }}</button>    <a href="#" @click.prevent="increment">{{ count }}</a>  </div></template><script>export default {  data() {    return {      count: 0    }  },  methods: {    increment() {      this.count += 1    }  }}</script>

NOTE: @ is shorthand fpr v-on:

NOTE: .prevent modifier tells the v-on directive to call event.preventDefault() on the triggered event

Bind attributes

<template>  <div>    <a :href="url">Google</a>    <a :href="url + '?q=' + q">Query</a>    <a :href="buildUrl()">Build Query</a>  </div></template><script>export default {  props: ['item'],  data() {    return {      url: 'https://www.google.com/search',      q: 'hello'    }  },  methods: {    buildUrl() {      return `${this.url}?q=${this.q}`    }  }}</script>

NOTE: : is shorhand for v-bind:

v-model for input

<template>  <div>    <input v-model="nickName" placeholder="Nick name">    Hi {{ nickName }}  </div></template><script>export default {  data() {    return {      nickName: ''    }  },}</script>

Computed

<template>  <div>    Hello {{ item.name }} ({{ nameUpper }})  </div></template><script>export default {  props: ['item'],  computed: {    nameUpper() {      return this.item.name.toUpperCase()    }  }}</script>

NOTE: Computed properties are cached based on their reactive dependencies. You could achieve the same via methods without the benefit of caching.

NOTE: Computed vs Watched Property

NOTE: Computed Setter

NOTE: Watchers

Communication

Parent call Child method

Child notify Parent

Others

References:

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.