Best Practices for Writing Vue Apps — Error Prevention

John Au-Yeung
May 6, 2020 · 4 min read
Photo by Markus Spiske 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 easy to maintain and performant fashion by looking at some best practices.

Component Style Scoping

This creates less styling conflicts between components.

For instance, we can write the following code given that App is the root component:

App.vue :

<template>
<div id="app">
<AppTodo/>
</div>
</template>
<script>
import AppTodo from "./components/AppTodo";
export default {
name: "App",
components: {
AppTodo
}
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
}
</style>

components/AppTodo.vue :

<template>
<p>{{todo}}</p>
</template>
<script>
export default {
name: "AppTodo",
data() {
return {
todo: "eat"
};
}
};
</script>
<style scoped>
p {
color: red;
}
</style>

In the code above, we have the style for p in AppTodo scoped to the component itself, so it won’t be available to anything outside.

On the other hand, the style in App isn’t scoped, so it’s applied everywhere.

Private Property Names

For example, we can write the following to indicate that a mixin method is a private method:

const mixin = {
methods: {
$_task() {
return "eat";
}
}
};
new Vue({
el: "#app",
mixins: [mixin]
});

In the code above $_task is a private method as indicated by the $_ prefix.

If we use modules, we can also write the following code to keep a function private:

mixin.js :

const eat = () => "eat";const mixin = {
methods: {
task() {
return eat();
}
}
};
export default mixin;

App.vue :

<template>
<div id="app">{{task()}}</div>
</template>
<script>
import mixin from "./mixin";
export default {
name: "App",
mixins: [mixin]
};
</script>

The code above has the eat private function in mixin.js . Then we just import the mixin while keeping eat private since we didn’t export it.

Whenever a build system is available to concatenate files, each component should be in its own file.

For instance, we write the following code to separate components into files:

app-bar.js :

Vue.component("app-bar", {
template: "<p>bar</p>"
});

app-foo.js :

Vue.component("app-foo", {
template: "<p>foo</p>"
});

index.html :

<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<app-foo></app-foo>
<app-bar></app-bar>
</div>
<script src="app-bar.js"></script>
<script src="app-foo.js"></script>
<script src="index.js"></script>
</body>
</html>

The code above includes one component definition in each file. Then we reference them in our template.

Single file components can only contain one component, so they’re always one component per file.

Photo by Honey Fangs on Unsplash

Filenames of single-file components should either be always PascalCase or always kebab-case.

Base components (a.k.a. presentational, dumb, or pure components) that apply app-specific styling and conventions should all begin with a specific prefix, such as Base, App, or V.

They only contain HTML elements, other base components, and 3rd party UI components. They never contain any global state.

This naming scheme groups all the base components together. It also prevents us from having to choose between arbitrary prefix for simple component wrappers.

Therefore, we should stick with one prefix for naming the components.

For example, a good naming scheme would be as follows:

components/ 
|- BaseButton.vue
|- BaseTable.vue
|- BaseInput.vue

Components that should only ever have a single active instance should begin with the The prefix, to denote that there can be only one.

They don’t accept any props. For instance, we may have the following file names for our components:

components/ 
|- TheHeader.vue
|- TheFooter.vue

Conclusion

Styles should be scoped in any component other than App so that we won’t have any issues with conflicting styles.

The Startup

Get smarter at building your thing. Join The Startup’s +789K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

John Au-Yeung

Written by

Web developer. Subscribe to my email list now at https://thewebdev.info/subscribe/. Email me at hohanga@gmail.com

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +789K followers.

John Au-Yeung

Written by

Web developer. Subscribe to my email list now at https://thewebdev.info/subscribe/. Email me at hohanga@gmail.com

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +789K followers.

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