Vue front end development specification

Sorting based on Vue official style guide

 

1, Coercion

1. The component name is multiple words

The component name should always be multiple words, except for the root component App.

Positive example:

export default {
  name: 'TodoItem',
  // ...
}
Copy code

Counterexample:

export default {
  name: 'Todo',
  // ...
}
Copy code

2. Component data

The data of the component must be a function.
When using the data attribute in a component (anywhere except new Vue), its value must be a function that returns an object.

Positive example:

// In a .vue file
export default {
  data () {
    return {
      foo: 'bar'
    }
  }
}
// It is possible to use objects directly on the root instance of a Vue,
// Because there is only one such instance.
new Vue({
  data: {
    foo: 'bar'
  }
})
Copy code

Counterexample:

export default {
  data: {
    foo: 'bar'
  }
}
Copy code

3. Prop definition

Prop definitions should be as detailed as possible.
In the code you submit, the definition of prop should be as detailed as possible, and at least its type needs to be specified.

Positive example:

props: {
  status: String
}
// Better practice!
props: {
  status: {
    type: String,
    required: true,
    validator: function (value) {
      return [
        'syncing',
        'synced',
        'version-conflict',
        'error'
      ].indexOf(value) !== -1
    }
  }
}
Copy code

Counterexample:

// This is acceptable only when developing a prototype system
props: ['status']
Copy code

4. Set the key value for v-for

Always use key with v-for.
On components_ Always_ v-for must be matched with key to maintain the status of internal components and their subtrees. Even maintaining predictable behavior on elements, such as object constancy in animation, is a good practice.

Positive example:

<ul>
  <li
    v-for="todo in todos"
    :key="todo.id"
  >
    {{ todo.text }}
  </li>
</ul>
Copy code

Counterexample:

<ul>
  <li v-for="todo in todos">
    {{ todo.text }}
  </li>
</ul>
Copy code

5. Avoid using v-if and v-for together

Never use v-if and v-for on the same element at the same time.
We tend to do this in two common situations:

  • To filter items in a list (such as v-for="user in users" v-if="user.isActive"). In this case, replace users with a calculated attribute (such as activeUsers) to return the filtered list.
  • To avoid rendering lists that should have been hidden (such as v-for="user in users" v-if="shouldShowUsers"). In this case, move the v-if to the container element (such as ul, ol).

Positive example:

<ul v-if="shouldShowUsers">
  <li
    v-for="user in users"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>
Copy code

Counterexample:

<ul>
  <li
    v-for="user in users"
    v-if="shouldShowUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>
Copy code

6. Set scope for component style

For applications, the styles in top-level App components and layout components can be global, but all other components should have scope.
This rule only relates to single file components. You don't have to use the scoped feature. You can also set the scope through CSS Modules, which is a class based BEM like strategy. Of course, you can also use other libraries or conventions.

In any case, for component libraries, we should prefer class based strategies to scoped features.

This makes it easier to override the internal style: it uses an understandable class name, does not have high selector priority, and is less likely to cause conflicts.

Positive example:

<template>
  <button class="c-Button c-Button--close">X</button>
</template>

<!-- use BEM appointment -->
<style>
.c-Button {
  border: none;
  border-radius: 2px;
}

.c-Button--close {
  background-color: red;
}
</style>
Copy code

Counterexample:

<template>
  <button class="btn btn-close">X</button>
</template>

<style>
.btn-close {
  background-color: red;
}
</style>

<template>
  <button class="button button-close">X</button>
</template>

<!-- use `scoped` characteristic -->
<style scoped>
.button {
  border: none;
  border-radius: 2px;
}

.button-close {
  background-color: red;
}
</style>
Copy code

2, Highly recommended (enhanced readability)

1. Component files

As long as there is a build system that can splice files, each component is divided into separate files.
When you need to edit a component or check the usage of a component, you can find it more quickly.

Positive example:

components/
|- TodoList.vue
|- TodoItem.vue
Copy code

Counterexample:

Vue.component('TodoList', {
  // ...
})

Vue.component('TodoItem', {
  // ...
})
Copy code

2. Case of single file component file

The file name of a single file component should either always start with uppercase (PascalCase)

Positive example:

components/
|- MyComponent.vue
Copy code

Counterexample:

components/
|- myComponent.vue
|- mycomponent.vue
Copy code

3. Basic component name

The basic components that apply specific styles and conventions (that is, the components that show classes, illogical or stateless) should all start with a specific prefix, such as Base, App or V.

Positive example:

components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue
Copy code

Counterexample:

components/
|- MyButton.vue
|- VueTable.vue
|- Icon.vue
Copy code

4. Single instance component name

Components that should only have a single active instance should be named with The prefix to show their uniqueness.
This does not mean that components can only be used on a single page, but only once per page. These components never accept any props because they are customized for your application, not their context in your application. If you find it necessary to add prop, it indicates that it is actually a reusable component, which is only used once in each page at present.

Positive example:

components/
|- TheHeading.vue
|- TheSidebar.vue
Copy code

Counterexample:

components/
|- Heading.vue
|- MySidebar.vue
Copy code

5. Tightly coupled component name

Child components closely coupled with the parent component should be named with the parent component name as a prefix.
If a component is meaningful only in the context of a parent component, this relationship should be reflected in its name. Because editors usually organize files alphabetically, this can put the associated files together.

Positive example:

components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
components/
|- SearchSidebar.vue
|- SearchSidebarNavigation.vue
Copy code

Counterexample:

components/
|- SearchSidebar.vue
|- NavigationForSearchSidebar.vue
Copy code

6. Word order in component name

Component names should start with high-level (usually general) words and end with descriptive modifiers.

Positive example:

components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputQuery.vue
|- SearchInputExcludeGlob.vue
|- SettingsCheckboxTerms.vue
|- SettingsCheckboxLaunchOnStartup.vue
Copy code

Counterexample:

components/
|- ClearSearchButton.vue
|- ExcludeFromSearchInput.vue
|- LaunchOnStartupCheckbox.vue
|- RunSearchButton.vue
|- SearchInput.vue
|- TermsCheckbox.vue
Copy code

7. Case of component name in template

Always PascalCase

Positive example:

<!-- In single file components and string templates -->
<MyComponent/>
Copy code

Counterexample:

<!-- In single file components and string templates -->
<mycomponent/>
<!-- In single file components and string templates -->
<myComponent/>
Copy code

8. Component name of complete word

Component names should tend to be complete words rather than abbreviations.

Positive example:

components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue
Copy code

Counterexample:

components/
|- SdSettings.vue
|- UProfOpts.vue
Copy code

9. Elements of multiple properties

Elements of multiple features should be written in multiple lines, one for each feature.

Positive example:

<img
  src="https://vuejs.org/images/logo.png"
  alt="Vue Logo"
>
<MyComponent
  foo="a"
  bar="b"
  baz="c"
/>
Copy code

Counterexample:

<img src="https://vuejs.org/images/logo.png" alt="Vue Logo">
<MyComponent foo="a" bar="b" baz="c"/>
Copy code

10. Simple expressions in the template

The component template should contain only simple expressions, and complex expressions should be refactored into calculated properties or methods.
Complex expressions can make your template less explicit. We should try to describe what should happen, not how to calculate that value. Moreover, computing properties and methods make the code reusable.

Positive example:

<!-- In template -->
{{ normalizedFullName }}
// Complex expression has been moved into a calculated property
computed: {
  normalizedFullName: function () {
    return this.fullName.split(' ').map(function (word) {
      return word[0].toUpperCase() + word.slice(1)
    }).join(' ')
  }
}
Copy code

Counterexample:

{{
  fullName.split(' ').map(function (word) {
    return word[0].toUpperCase() + word.slice(1)
  }).join(' ')
}}
Copy code

11. Simple calculation properties

Positive example:

computed: {
  basePrice: function () {
    return this.manufactureCost / (1 - this.profitMargin)
  },
  discount: function () {
    return this.basePrice * (this.discountPercent || 0)
  },
  finalPrice: function () {
    return this.basePrice - this.discount
  }
}
Copy code

Counterexample:

computed: {
  price: function () {
    var basePrice = this.manufactureCost / (1 - this.profitMargin)
    return (
      basePrice -
      basePrice * (this.discountPercent || 0)
    )
  }
}
Copy code

12. Quoted property values

Non empty HTML attribute values should always be quoted (single or double quotes, choose the one you don't use in JS).
In HTML, feature values without spaces can be without quotes, but doing so often leads to the avoidance of feature values with spaces, resulting in poor readability.

Positive example:

<AppSidebar :style="{ width: sidebarWidth + 'px' }">
Copy code

Counterexample:

<AppSidebar :style={width:sidebarWidth+'px'}>
Copy code

13. Abbreviations of directives

Both use instruction abbreviations (use: for v-bind: and @ for v-on:)

Positive example:

<input
  @input="onInput"
  @focus="onFocus"
>
Copy code

Counterexample:

<input
  v-bind:value="newTodoText"
  :placeholder="newTodoInstructions"
>
Copy code

3, Recommend

1. Order of top-level elements of single file components

Single file components should always keep the order of < script >, < template > and < style > tags consistent. And < style > should be placed last, because there must be at least one of the other two tags.

Positive example:

<!-- ComponentA.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>
Copy code

4, Use with caution (potentially dangerous mode)

1. key is not used in v-if/v-if-else/v-else

If the element types of a group of v-if + v-else are the same, it is best to use key (such as two < div > elements).

Positive example:

<div
  v-if="error"
  key="search-status"
>
  Error:{{ error }}
</div>
<div
  v-else
  key="search-results"
>
  {{ results }}
</div>
Copy code

Counterexample:

<div v-if="error">
  Error:{{ error }}
</div>
<div v-else>
  {{ results }}
</div>
Copy code

2. Element selector in scoped

Element selectors should be avoided in scoped.
In the scoped style, class selectors are better than element selectors because using element selectors heavily is slow.

Positive example:

<template>
  <button class="btn btn-close">X</button>
</template>

<style scoped>
.btn-close {
  background-color: red;
}
</style>
Copy code

Counterexample:

<template>
  <button>X</button>
</template>

<style scoped>
button {
  background-color: red;
}
</style>
Copy code

3. Implicit parent-child component communication

Communication between parent and child components through prop and events should be preferred, rather than this.$parent or changing prop.

Positive example:

Vue.component('TodoItem', {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },
  template: `
    <input
      :value="todo.text"
      @input="$emit('input', $event.target.value)"
    >
  `
})
Copy code

Counterexample:

Vue.component('TodoItem', {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },
  methods: {
    removeTodo () {
      var vm = this
      vm.$parent.todos = vm.$parent.todos.filter(function (todo) {
        return todo.id !== vm.todo.id
      })
    }
  },
  template: `
    <span>
      {{ todo.text }}
      <button @click="removeTodo">
        X
      </button>
    </span>
  `
})
Copy code

4. Non Flux global state management

Global state should be managed preferentially through Vuex, not through this.$root or a global event bus.

Positive example:

// store/modules/todos.js
export default {
  state: {
    list: []
  },
  mutations: {
    REMOVE_TODO (state, todoId) {
      state.list = state.list.filter(todo => todo.id !== todoId)
    }
  },
  actions: {
    removeTodo ({ commit, state }, todo) {
      commit('REMOVE_TODO', todo.id)
    }
  }
}
<!-- TodoItem.vue -->
<template>
  <span>
    {{ todo.text }}
    <button @click="removeTodo(todo)">
      X
    </button>
  </span>
</template>

<script>
import { mapActions } from 'vuex'

export default {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },
  methods: mapActions(['removeTodo'])
}
</script>
Copy code

Counterexample:

// main.js
new Vue({
  data: {
    todos: []
  },
  created: function () {
    this.$on('remove-todo', this.removeTodo)
  },
  methods: {
    removeTodo: function (todo) {
      var todoIdToRemove = todo.id
      this.todos = this.todos.filter(function (todo) {
        return todo.id !== todoIdToRemove
      })
    }
  }
})
Copy code

appendix

1. It is recommended to use vs code for front-end coding, and specify that the Tab size is 2 spaces

  1. vs code configuration
{
  "editor.tabSize": 2,
  "workbench.startupEditor": "newUntitledFile",
  "workbench.iconTheme": "vscode-icons",
  // The following is the stylus configuration
  "stylusSupremacy.insertColons": false, // Insert colon
  "stylusSupremacy.insertSemicolons": false, // Is it inserted
  "stylusSupremacy.insertBraces": false, // Insert braces
  "stylusSupremacy.insertNewLineAroundImports": false, // Wrap after import
  "stylusSupremacy.insertNewLineAroundBlocks": false, // Whether to wrap lines in two selectors
  "vetur.format.defaultFormatter.html": "js-beautify-html",
  "eslint.autoFixOnSave": true,
  "eslint.validate": [
    "javascript",
    {
      "language": "html",
      "autoFix": true
    },
    {
      "language": "vue",
      "autoFix": true
    },
    "javascriptreact",
    "html",
    "vue"
  ],
  "eslint.options": { "plugins": ["html"] },
  "prettier.singleQuote": true,
  "prettier.semi": false,
  "javascript.format.insertSpaceBeforeFunctionParenthesis": false,
  "vetur.format.js.InsertSpaceBeforeFunctionParenthesis": false,
  "vetur.format.defaultFormatter.js": "prettier",
  // "prettier.eslintIntegration": true
}
Copy code
  1. vs code plug-in
  • Auto Close Tag
  • Path Intellisense
  • Prettier
  • Vetur
  • vscode-icons

last

If you think this article is a little helpful to you, give it a compliment. Or you can join my development exchange group: 1025263163 learn from each other, and we will have professional technical Q & A to solve doubts

If you think this article is useful to you, please click star:   https://gitee.com/ZhongBangKeJi/CRMEB esteem it a favor  !

Keywords: Javascript Vue Vue.js gitee bind

Added by Xeoncross on Mon, 29 Nov 2021 06:23:37 +0200