More Best Practices for Vue.js

John Au-Yeung
May 7 · 4 min read
Image for post
Image for post
Photo by Jeffrey F Lin on Unsplash

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at how to write Vue apps in an easily maintainable way by following a few best practices.

Use Computed Properties Instead of Methods

For instance, this:

<template>
<div id="app">
<div v-for="todo in todoTasks" :key="todo.id">{{todo.description}}</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
tasks: [
{ id: 1, description: "eat", done: false },
{ id: 2, description: "drink", done: true },
{ id: 3, description: "sleep", done: true },
{ id: 4, description: "walk", done: false },
{ id: 5, description: "read", done: false }
]
};
},
computed: {
todoTasks() {
return this.tasks.filter(t => !t.done);
}
}
};
</script>

is better than:

<template>
<div id="app">
<div v-for="todo in getTodoTasks(tasks)" :key="todo.id">{{todo.description}}</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
tasks: [
{ id: 1, description: "eat", done: false },
{ id: 2, description: "drink", done: true },
{ id: 3, description: "sleep", done: true },
{ id: 4, description: "walk", done: false },
{ id: 5, description: "read", done: false }
]
};
},
methods: {
getTodoTasks(tasks) {
return tasks.filter(t => !t.done);
}
}
};
</script>

Since the second example runs getTodoTasks every time any data is changed as the templates are being re-rendered. On the other hand, computed properties only change when the dependencies inside the function change. So todoTasks function only runs when this.tasks changes.

Use of the Same v-if Condition on Multiple Consecutive Elements

Also, we’re repeating code, which is almost never good.

Therefore, there’s no advantage to doing this. So instead of writing:

<template>
<div id="app">
<button @click="toggle = !toggle">Toggle</button>
<p v-if="toggle">foo</p>
<p v-if="toggle">bar</p>
<p v-if="toggle">baz</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
toggle: false
};
}
};
</script>

We should either wrap an element around the p elements and use v-if on the wrapper:

<template>
<div id="app">
<button @click="toggle = !toggle">Toggle</button>
<div v-if="toggle">
<p>foo</p>
<p>bar</p>
<p>baz</p>
</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
toggle: false
};
}
};
</script>

Or we can use the template component as follows if we don’t want a wrapper:

<template>
<div id="app">
<button @click="toggle = !toggle">Toggle</button>
<template v-if="toggle">
<p>foo</p>
<p>bar</p>
<p>baz</p>
</template>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
toggle: false
};
}
};
</script>
Image for post
Image for post
Photo by NeONBRAND on Unsplash

Use Key Property to Differentiate Between Reusable Elements or Components

For instance, we can write:

<template>
<div id="app">
<button @click="username = !username">Toggle Login Type</button>
<form v-if="username">
<div>
<label>Email</label>
<input type="text" key="email">
</div>
<div>
<label>Password</label>
<input type="text" key="password">
</div>
</form>
<form v-else>
<div>
<label>Username</label>
<input type="text" key="username">
</div>
<div>
<label>Password</label>
<input type="text" key="password">
</div>
</form>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
username: false
};
}
};
</script>

In the code above, we have the key attribute set to password in both password inputs. Therefore, when we click Toggle Login Type, we’ll see the entered password being kept while the button toggles between the 2 forms.

Detection Of Changes Within An Array

<template>
<div id="app">
<button @click="draw">Draw</button>
<p v-for="n in nums" :key="n">{{n}}</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
nums: [1, 2, 3, 4, 5]
};
},
methods: {
draw() {
const index = Math.floor(Math.random() * this.nums.length);
this.$set(this.nums, index, Math.random() * 200);
}
}
};
</script>

The draw method in the code above changes a random entry of the nums array to a random value. We need to call this.$set to make Vue re-render the array after the value of entry has changed.

The following code:

<template>
<div id="app">
<button @click="draw">Draw</button>
<p v-for="n in nums" :key="n">{{n}}</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
nums: [1, 2, 3, 4, 5]
};
},
methods: {
draw() {
const index = Math.floor(Math.random() * this.nums.length);
this.nums[index] = Math.random() * 200;
}
}
};
</script>

doesn’t work since Vue doesn’t re-render since it’s not aware that it needs to render the component when an entry in the array changed.

Conclusion

We shouldn’t use v-if with the same condition to check for multiple consecutive components. Instead, we should wrap it around an element or template and the use v-if there.

The key attribute is useful for inputs since it lets us keeps inputted values if 2 inputs have the same key value conditionally displayed by 2 different v-if conditions.

this.$set is useful for triggering re-render after array or object entries are set.

The Startup

Medium's largest active publication, followed by +730K people. Follow to join our community.

John Au-Yeung

Written by

Web developer. Subscribe to my email list now at http://jauyeung.net/subscribe/. Email me at hohanga@gmail.com

The Startup

Medium's largest active publication, followed by +730K people. Follow to join our community.

John Au-Yeung

Written by

Web developer. Subscribe to my email list now at http://jauyeung.net/subscribe/. Email me at hohanga@gmail.com

The Startup

Medium's largest active publication, followed by +730K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store