Vue.js Recipies

By Eoin on 13 September 2017.

This is a record of some gotchas I’ve come across with Vue.js v2. I love its simplicity.

Caveat: examples are taken from real code, but I have not tested them directly. If you see a problem, please contact me.

Contents of this post:

# AJAX Request

Include Axios:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

Make the request, noting the self trick to keep a reference to this:

Vue.component('my-vue-component', {
  ...
  data: { 
    widgets: null
  },
  methods: {
    
fetchData: function() {
      let self = this;
      axios.get("/api/widgets")
        .then(function (response) {
          self.widgets = response.data;
        })
        .catch(function (error) {
          console.log(error);
        });
    }
  }
  ...
});

# kebab-case for Props with HTML Components

Use camelCase in the JavaScript, and kebab-case in the HTML.

This is the HTML template for your component, note how the widgetName changes to widget-name:

<template id="widget-editor">
  <p>{{ widgetName }}</p>
</template>

<div id="my-app">
  <widget-editor :widget-name="Weather Widget"></widget-editor>
</div>

Javascript for the component:

Vue.component('widget-editor', {
  // camelCase in JavaScript
  props: ['widgetName'],
  template: '#widget-editor'
})

# Force Refresh of object

Problem: let’s say you have a component that displays a model, like a “todo list” which contains another component “todo item”. If you load new data for that todo list itme from the server, you might want the todo list item component to be recreated completely so that it goes through all its initialisation steps. If you don’t destroy the model, you component might have state from the older model. For example, you might forget to reset a boolean flag “show top priority item” when the item changes. Most of this is covered by how Vue.js watches for changes in its properties you set. This is more about overcoming programmer bugs. Maybe this really isn’t a problem, and I didn’t understand what the correct approach should have been.

Controversial approach: Vue.js documentation advises you to be “data-centric”. In other words, instead of destroying and re-creating an object, you should watch for changes in your component of that object. But I’ve found in one case it was cleaner to destroy (nullify) the object first, then assign a new object to the variable, so that no state is left over from the older object.

HTML:

<template id="todo-list">
  <p>
    My one thing to do:
    <todo-item :item-object="topPriorityItem" v-if="topPriorityItem"></todo-item>
</template>

JavaScript:

Vue.component('todo-list', {
  data: {
    todoItems: ['Get kebab', 'Go for a walk'],
    topPriorityItem: null
  },
  methods: {
    setTopPriority: function(itemIndex) {
      this.topPriorityItem = null;
      this.$nextTick(function() {
        // Trick: waits until next "tick" to ensure that item nullification destroys <todo-item>
        this.topPriorityItem = this.todoItems[itemIndex];
      });
    }
  }
}
Vue.component('todo-item', {
  props: [itemObject],
  mounted: function() {
    // Complicated state setting here that would be hard to track
    // if the item wasn't destroyed and recreated
  }
});

About and Contact · All posts