A few lessons working with VueJS

I have been building a personal capstone project for the last couple of weeks and I have learnt some new things about VueJS. I would like to highlight them in this post: They are:

  1. Don’t use a global events bus
  2. Always initialize data properly
  3. How to use refs
  4. Slots are for your benefits

1. Don’t use a global events bus

Flux libraries are like glasses: you’ll know when you need them.
- Dan Abramov

In most cases, using a global events bus would suggest the need to have a centralized state. Frankly, a global events bus seems like a quick and easy way out but in the long run, maintenance can suffer. A solution would be to use Vuex.

For me, the main problem a centralized state management system helped to solve was server communication. I really wanted to have all my server communication in one place so that if I needed to change anything, it would be as easy as opening just one file. With a global events bus, I had to speak to the server from different components within my app and I didn’t like that. I integrated Vuex and problem solved.

You can learn more about Vuex by reading the docs and checking out this post I found helpful. (I recommend the docs though)

2. Always initialize your data properly

Since Vue performs the getter/setter conversion process during instance initialization, a property must be present in the data object in order for Vue to convert it and make it reactive.

The Vue.$data object needs to know all its dependents otherwise an error like this is thrown [Vue warn]: Property or method “x" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. The solution: Initialize your data even if you have to have empty fields.

For example, I had a modal that housed a form component with a reactive prop object. At first, I didn’t realise that the Vue was trying to bind the prop object so I kept running into the above error. After I realized, I first initialized the prop with null but that didn’t work. Then I initialized with empty fields and everything worked fine. An example is shown below.

<modal>
<reactive-form :prop="propObject"></reactive-form>
</modal>
...
export default {
data(){
return {
propObject : {
keyA : '',
keyB : ''
...
}
}
}
}

3. How to use refs

ref is used to register a reference to an element or a child component. The reference will be registered under the parent component’s $refs object. If used on a plain DOM element, the reference will be that element; if used on a child component, the reference will be component instance

Generic element components can exist through various parts of an application and it is important to have a way to access their methods A solution is to use ref and then access them using this.$refs.

For example, I had a generic modal component with anopen and aclose method. To access these I needed a reference. Hence, I did something like:

<modal ref="myModal">
//modal content
</modal>
<button @click="openModal">Open Modal</modal>
...
methods : {
openModal(){
this.$refs["myModal"].open();
}
}

They are some things to note though.

  1. refs are not reactive so don’t use them in templates for data binding.
  2. They are created by the render function and cannot be access on initial render.
  3. If you really need to put reactive content in them then make sure to initialize data and manage state properly.
  4. Always make sure you are accessing them from their parents because they are not available elsewhere.

You can read more about refs here.

4. Slots are for your benefit

The content distribution API is a very useful mechanism when designing components that are meant to be composed together.

If you need to compose your components like one builds a Lego house then slots are the way to go.

In my case, I had a table component and I needed to make use of another row component without scattering my data all over the place. So here’s what I did:

<template>
<table>
<tr>
<th>Name</th>
<th>Company</th>
<th>Date</th>
</tr>
  <slot name="table-row"></slot>
</div>
</template>

Then in the main page component, I had this:

<table-component>
<div slot="table-row">
<table-row v-for="obj in objects" :key="obj.id" :prop="obj">
</table-row>
</div>
</table-component>

I had the component for the table-row defined elsewhere and using slots allowed me to composed them. Hence, the following was rendered.

<table>
<tr>
<th>Name</th>
<th>Company</th>
<th>Date</th>
</tr>
<tbody>
...
</tbody>
</table

There are numerous benefits with slots and I suggest you check out this, this and this link for more information.

Conclusion

I have learnt quite a few things and I know I have a long way to go. I haven’t finished the project for which this post was written but as soon as it is done, I’d put a post up about my experience.

~

This is my first post and it meant to be a sort of online journal for me to review my journey as a JavaScripter. Please do not hesitate to point out errors and give advice. Cheers.