Skip to content

Instantly share code, notes, and snippets.

@rutcreate
Created February 22, 2019 08:57
Show Gist options
  • Save rutcreate/f26e2e51b89519bdd43be7d7a15f9270 to your computer and use it in GitHub Desktop.
Save rutcreate/f26e2e51b89519bdd43be7d7a15f9270 to your computer and use it in GitHub Desktop.
JavaScript and VueJS Coding Style

JavaScript Coding Style

Naming Convention

  • Use camelCase for variable name.
// Bad
const number_of_people = 20
const NumberOfPeople = 20
const person = {
    id: 1,
    first_name: 'John',
    last_name: 'Doe'
}

// Good
const numberOfPeople = 20
const person = {
    id: 1,
    firstName: 'John',
    lastName: 'Doe'
}
  • Exception case for JSON object some server may requires snake_case.
// Good
const person = {
    id: 1,
    first_name: 'John',
    last_name: 'Doe'
}
  • Use camelCase for method or function name.
// Bad
function get_user_id () {}
const get_user_id = () => {}

// Good
function getUserId () {}
const getUserId = () => {}
  • Use PascalCase for class name.
// Bad
class listItem {}
class list_item {}

// Good
class ListItem {}
  • Use UPPERCASE with underscore (_) for constants. It could apply to class's members or JSON object's key.
// Bad
const statusDraft = 0
const status_approved = 1
const StatusPublished = 2
// or
const postStatus = {
    statusDraft: 0,
    status_approved: 1,
    StatusPublished: 2
}

// Good
const STATUS_DRAFT = 0
const STATUS_APPROVED = 1
const STATUS_PUBLISHED = 2
// or
const POST_STATUS = {
    DRAFT: 0,
    APPROVED: 1,
    PUBLISHED: 2
}

Spaces

  • All operator signs must be surrounded by space except !.
// Bad
const pass = mathScore>=50&&physicsScore>30||!male
const result=x+5*y/20-8

// Good
const pass = mathScore >= 50 && physicsScore > 30 || !male
const result = x + 5 * y / 20 - 8
  • No space between open and close parentheses.
// Bad
const pass = ( mathScore >= 50 && physicsScore > 30 ) || !male
const result=( x + 5 ) * y / ( 20 - 8 )
function createPerson ( firstName, lastName ) {}
Math.floor( 3.14159 )

// Good
const pass = (mathScore >= 50 && physicsScore > 30) || !male
const result = (x + 5) * y / (20 - 8)
function createPerson (firstName, lastName) {}
Math.floor(3.14159)
  • Always space before open and after parentheses when define function.
// Bad
function createPerson(firstName, lastName){}
const personUtil = {
    create(){},
    save(person){}
}

// Good
function createPerson (firstName, lastName) {}
const personUtil = {
    create () {},
    save (person) {}
}
  • Always space after comma and no space between square brackets in Array.
// Bad
const numbers = [1,2,3,4,5,6]
const numbers = [ 1,2,3,4,5,6 ]

// Good
const numbers = [1, 2, 3, 4, 5, 6]
  • No space after key and always space before value in JSON Object.
// Bad
const data = {
    name :'John Doe'
}

// Good
const data = {
    name: 'John Doe'
}
  • Always space after open and before close curly braces in single line JSON Object.
// Bad
const data = {name: 'John Doe'}

// Good
const data = { name: 'John Doe' }
  • Always space after comma in single line JSON Object.
// Bad
const data = { name: 'John Doe',country: 'Thailand',gender: 'male' }

// Good
const data = { name: 'John Doe', country: 'Thailand', gender: 'male' }
  • Every empty lines must not contain any space.
// Bad
export default {
    name: 'TodoList',
    
    methods: {}
}

// Good
export default {
    name: 'TodoList',

    methods: {}
}
  • Last line of code must be 1 empty line.
// Bad
console.log('bad')
// Good
console.log('bad')

If, else and if-else

  • Always put curly braces surround if statement even it is single line statement.
// Bad
if (true)
    console.log('true')

// Good
if (true) {
    console.log('true')
}
  • Open curly brace must be the same line of if and close curly brace must be next line of last statement.
// Bad
if (true)
{
    console.log('true')
}

// Bad
if (true) {
    console.log('true') }

// Bad
if (true) { console.log('true') }

// Good
if (true) {
    console.log('true')
}
  • else and else if must be the same line of close curly brace and open curly brace.
// Bad
if (true) {
    console.log('true')
}
else if (false) {
    console.log('false')
}
else {
    console.log('else')
}

// Good
if (true) {
    console.log('true')
} else if (false) {
    console.log('false')
} else {
    console.log('else')
}
  • Always space after if, surrounds else and else if, and before open curly brace.
// Bad
if(true){
    console.log('true')
}else if(false){
    console.log('false')
}else{
    console.log('else')
}

// Good
if (true) {
    console.log('true')
} else if (false) {
    console.log('false')
} else {
    console.log('else')
}

Indentation

  • Use 4 spaces for indentation.
// Bad
const data = {
  firstName: 'John',
  lastName: 'Doe'
}

// Good
const data = {
    firstName: 'John',
    lastName: 'Doe'
}
  • JSON Object in Array must be start next line and add 1 indent.
// Bad
const todoItems = [{
    title: 'Go to shopping',
    done: false
}, {
    title: 'Do homework',
    done: true
}]

// Good
const todoItems = [
    { title: 'Go to shopping', done: false },
    { title: 'Do homework', done: true }
]
const todoItems = [
    {
        title: 'Go to shopping',
        done: false
    },
    {
        title: 'Do homework',
        done: true
    }
]
  • JSON Object as parameter must be start at the same line of function or method name and add 1 indent.
// Bad
createPerson(
    {
        firstName: 'John',
        lastName: 'Doe'
    }
)
createPerson({ firstName: 'John',
               lastName: 'Doe' })

// Good
createPerson({
    firstName: 'John',
    lastName: 'Doe'
})

createPerson({ firstName: 'John', lastName: 'Doe' })
  • JSON Object as parameter can start next line if there are more than 1 parameter and first parameter start next line.
// Good
createPerson(
    {
        firstName: 'John',
        lastName: 'Doe'
    },
    new Date()
)

// Better
const person = {
    firstName: 'John',
    lastName: 'Doe'
}
const registerDate = newDate()
createPerson(person, registerDate)

Trailing space and comma

  • Every single line of code must has no trailing space.
// Bad
const name = 'John Doe' 

// Good
const name = 'John Doe'
  • Array value must has no trailing comma.
// Bad
const numbers = [1, 2, 3, 4, 5,]

// Good
const numbers = [1, 2, 3, 4, 5]
  • JSON Object value must has no trailing comma.
// Bad
const person = {
    firstName: 'John',
    lastName: 'Doe',
}
const person = { firstName: 'John', lastName: 'Doe', }

// Good
const person = {
    firstName: 'John',
    lastName: 'Doe'
}
const person = { firstName: 'John', lastName: 'Doe' }

String

  • Use template literal instead of concat string.
// Bad
const message = `Hello John Doe`

// Still good
const name = 'John Doe'
const message = 'Hello' + name

// Better
const name = 'John Doe'
const message = `Hello ${name}`

VueJS

  • Component's filename must be in PascalCase.
// Bad
todo-list.vue
todoList.vue

// Good
TodoList.vue
  • Element order should be <template>, <script>, <style>.
<!-- Bad -->
<script>
export default {
    ...
}
</script>

<template>
    <div>{{ message }}</div>
</template>

<style>
</style>

<!-- Good -->
<template>
    <div>{{ message }}</div>
</template>

<script>
export default {
    ...
}
</script>

<style>
</style>

VueJS <script>

  • Every components must be defined a name.
// Bad
export default {
    // Missing name here
    data () {
        return {
            title: ''
        }
    }
}

// Good
export default {
    name: 'TodoItem',

    data () {
        return {
            title: ''
        }
    }
}
  • Component's properties must be ordered as listed below:
    • name
    • components
    • props
    • data
    • computed
    • watch
    • beforeCreate
    • created
    • beforeMount
    • mounted
    • beforeUpdate
    • updated
    • activated
    • deactivated
    • beforeDestroy
    • destroyed
    • methods
// Bad
export default {
    name: 'TodoList',

    mounted () {
        this.todoItems = this.$store.todoItems
    },

    data () {
        return {
            todoItems: []
        }
    }
}

// Good
export default {
    name: 'TodoList',

    data () {
        return {
            todoItems: []
        }
    },

    mounted () {
        this.todoItems = this.$store.todoItems
    }
}
  • Component's properties must be separated by empty line.
// Bad
export default {
    name: 'TodoList',
    data () {
        return {
            todoItems: []
        }
    },
    mounted () {
        this.todoItems = this.$store.todoItems
    }
}

// Good
export default {
    name: 'TodoList',

    data () {
        return {
            todoItems: []
        }
    },

    mounted () {
        this.todoItems = this.$store.todoItems
    }
}
  • import must be sorted alphabetically.
// Bad
import Dog from '@/components/Dog'
import Banana from '@/components/Banana'
import Apple from '@/components/Apple'
import Cat from '@/components/Cat'

// Good
import Apple from '@/components/Apple'
import Banana from '@/components/Banana'
import Cat from '@/components/Cat'
import Dog from '@/components/Dog'
  • Separate import, require and export by empty line.
// Bad
import Apple from '@/components/Apple'
import Banana from '@/components/Banana'
const Util = require('@/util')
const jQuery = require('jquery')
export default {
    ...
}

// Good
import Apple from '@/compnents/Apple'
import Banana from '@/components/Banana'

const Util = require('@/util')
const jQuery = require('jquery')

export default {
    ...
}
  • Always use @ when import or require
// Bad
import Hello from '../../../Hello'

// Good
import Hello from '@/components/Hello'
  • components's items must be sorted alphabetically.
// Bad
export default {
    ...

    components: {
        Dog,
        Banana,
        Apple,
        Cat
    }
}

// Good
export default {
    ...

    components: {
        Apple,
        Banana,
        Cat,
        Dog
    }
}
  • computed, methods, watch's properties should separated by empty line.
// It's ok
export default {
    ...

    computed: {
        allTodos () {
            return this.todoItems
        },
        activeTodoItems () {
            return this.allTodos.filter(todo => todo.active)
        },
        todoCount () {
            return this.todoItems.length
        }
    },

    methods: {
        method1 () {
            console.log('method1')
        },
        method2 () {
            console.log('method2')
        }
    },

    watch: {
        var1 (newValue, oldValue) {
            console.log('var1 changed')
        },
        var2 (newValue, oldValue) {
            console.log('var2 changed')
        }
    }
}

// Better
export default {
    ...

    computed: {
        allTodos () {
            return this.todoItems
        },

        activeTodoItems () {
            return this.allTodos.filter(todo => todo.active)
        },

        todoCount () {
            return this.todoItems.length
        }
    },

    methods: {
        method1 () {
            console.log('method1')
        },

        method2 () {
            console.log('method2')
        }
    },

    watch: {
        var1 (newValue, oldValue) {
            console.log('var1 changed')
        },

        var2 (newValue, oldValue) {
            console.log('var2 changed')
        }
    }
}
  • Props must define type.
// Bad
export default {
    props: ['value']
}

// Good
export default {
    props: {
        value: {
            type: String
        },

        active: {
            type: Boolean
        }
    }
}

VueJS <template>

  • Use 4 spaces for 1 indent.
<!-- Bad -->
<template>
  <div>{{ message }}</div>
</template>

<!-- Good -->
<template>
    <div>{{ message }}</div>
</template>
  • Use kebab-case for component name in template.
// Bad
<template>
    <CustomSelect />
    <customSelect />
    <customselect />
</template>

// Good
<template>
    <custom-select />
</template>
  • Use self-closing on no slot component.
<!-- Bad -->
<template>
    <custom-select></custom-select>
</template>

<!-- Good -->
<template>
    <custom-select />
</template>
  • Use kebab-case to bind property.
<script>
export default {
    name: 'TodoList',

    props: {
        todoItems: {
            type: Array
        }
    }
}
</script>

// Bad
<template>
    <todo-list :todoItems="todoItems" />
</template>

// Good
<template>
    <todo-list :todo-items="todoItems" />
</template>
  • Always use @ instead of v-on.
<!-- Bad -->
<template>
    <custom-select v-on:click="click" />
</template>

<!-- Good -->
<template>
    <custom-select @click="click" />
</template>
  • Always use : instead of v-bind.
<!-- Bad -->
<template>
    <custom-select v-bind:key="key" />
</template>

<!-- Good -->
<template>
    <custom-select :key="key" />
</template>
  • Always start next line when there is more than 1 attribute.
<!-- Bad -->
<template>
    <custom-select v-if="value" :key="key" />
</template>

<!-- Good -->
<template>
    <custom-select
        v-if="value"
        :key="key"
    />
</template>
  • Attributes must be ordered by attribute's name as listed below.
    • is
    • v-for
    • v-if
    • v-else-if
    • v-else
    • v-show
    • v-cloak
    • id
    • ref
    • key
    • slot
    • v-model
    • Other attributes
    • v-on
    • v-html, v-text
<!-- Bad -->
<template>
    <custom-select
        @click="click"
        id="custom-select1"
        @update="update"
        class="custom-select"
        :visible="true"
        :label="form.name"
        ref="customSelect"
        v-model="select"
    />
</template>

<!-- Good -->
<template>
    <custom-select
        id="custom-select1"
        ref="customSelect"
        v-model="select"
        class="custom-select"
        :label="form.name"
        :visible="true"
        @click="click"
        @update="update"
    />
</template>

VueJS <style>

  • Open curly brace must be the same line of selector, body must be next line, and close curly brace must next line.
// Bad
.card
{
    border: 1px solid #ccc;
}
.card { border: 1px solid #ccc; }

// Good
.card {
    border: 1px solid #ccc;
}
  • Separate selector block by empty line.
// Bad
.card {
    border: 1px solid #ccc;
    .card-title {
        font-weight: bold;
    }
}
.button {
    font-weight: bold;
}

// Good
.card {
    border: 1px solid #ccc;

    .card-title {
        font-weight: bold;
    }
}

.button {
    font-weight: bold;
}
  • Use 3 character hex where possisble.
// Bad
.card {
    color: #aabbcc;
}

// Good
.card {
    color: #abc;
}
  • Separate words in ID and class names by hyphen.
// Bad
.cardtitle {
    border: 1px solid #ccc;
}

// Good
.card-title {
    border: 1px solid #ccc;
}
  • Order rules by alphabetically.
// Bad
.card {
    text-align: center;
    color: #222;
    border: 1px solid #ccc;
    background: #f7f7f7;
}

// Good
.card {
    background: #f7f7f7;
    border: 1px solid #ccc;
    color: #222;
    text-align: center;
}
  • Separate multiple selectors by new line.
// Bad
h1, h2, h3 {
    font-weight: bold;
}

// Good
h1,
h2,
h3 {
    font-weight: bold;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment