Common Vue Problems — State Updates, Vuex, and Event Handlers

John Au-Yeung - Jan 26 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

Vue.js makes developing front end apps easy. However, there are still chances that we’ll run into problems.

In this article, we’ll look at some common issues and see how to solve them.

Passing event and argument to v-on in Vue.js

We can pass arguments to the method we call in the v-on directive in Vue.

For instance, we can write:

<input type="number" v-on:input="addToCart($event, item.id)" min="0" placeholder="0">
Enter fullscreen mode Exit fullscreen mode

in our template.

Then in our component, we can write:

methods: {
  addToCart(event, id){
    console.log(id)
  }
}
Enter fullscreen mode Exit fullscreen mode

$event has the object emitted from the input event.

id has the item.id that we passed in the template code.

The Purpose of nextTick

nextTick lets us do something after we changed the data.

It’s like setTimeout in plain JavaScript.

nextTick detects changes from data changes, so it’ll always run after a piece of data has been updated.

setTimeout isn’t aware of that.

For instance, if we have:

<template>
  <div>
    {{ val }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      val: 1
    }
  },
  mounted() {
    this.val = 2;

    this.$nextTick(() => {
      this.val = 3;
    });
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

The initial value of this.val is 1.

Then the mounted hook is called and updates this.val is 2.

Once that update is done, then Vue updates this.val to 3.

Difference Between $mount() and $el

$mount lets us explicitly mount the Vue instance when we need to.

With it, we can delay the Vue instance until a particular element exists.

This is useful for adding Vue to legacy apps where the elements are added by manipulating the DOM.

el mounts the Vue instance straight into the DOM without checking whether it exists first.

Therefore, it’s useful for mounting the instance to a static element or something that we know always loads before the Vue instance.

[Vue warn]: Cannot find element

This error means that Vue can’t the element with the given select to mount the component on.

For instance, if we have:

const main = new Vue({
  el: '#main',
  data: {
    hello: 'home'
  }
});
Enter fullscreen mode Exit fullscreen mode

Then the element with ID main isn’t found.

To fix that, we should make sure that the element is loaded before we create the Vue instance.

For example, we can write:

window.onload = () => {
  const main = new Vue({
    el: '#main',
    data: {
      hello: 'home'
    }
  });
}
Enter fullscreen mode Exit fullscreen mode

or we can write:

window.addEventListener('load', () => {
  // add the same Vue instance as the previous example
})
Enter fullscreen mode Exit fullscreen mode

They both let us mount the Vue instance after the given element is present in the DOM.

Load All Server-Side Data on Initial Vue.js Load

We can load the data into the Vuex store before creating the Vue instance by writing our own function to load it.

For example, we can write:

const store = (data) => {
  return new Vuex.Store({
    state: {
      exams: data,
    },
    actions,
    getters,
    mutations,
  });
}

fetch('/some/url')
  .then(response => response.json())
  .then((data) => {
    new Vue({
      el: '#app',
      router,
      store: store(data),
      template: '<App/>',
      components: { App },
    });
  });
Enter fullscreen mode Exit fullscreen mode

We have a function to create the store with thestore .

Then we call the store function in our object that we passed into the Vue constructor.

The data we passed into the store is from the fetch function call.

This way, the data will be populated in the store before it goes to the store.

Import SASS or SCSS with a Vue CLI Project

We can import SASS or SCSS with a Vue app created with Vue CLI by adding the node-sass and sass-loaer packages.

Then we can load the SCSS files in our code.

To install the packages, we run:

npm install -D node-sass sass-loader
Enter fullscreen mode Exit fullscreen mode

Then we can write:

import './styles/my-styles.scss'
Enter fullscreen mode Exit fullscreen mode

to import the styles globally in main.js .

If we want to import a SASS or SCSS file in the file, then we write:

<style lang="scss">
  ...
</style>
Enter fullscreen mode Exit fullscreen mode

to add make Vue aware of SCSS code.

Conclusion

To let us use SASS or SCSS code in an existing project, we can use the SASS loader package.

If we want to load data to a Vuex store before loading our Vue app, we can load the data, then create the Vuex store with the data.

Then we can create our Vue instance with the store.

We can pass anything to event handlers.

nextTick is handy for updating our state after some other update.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .