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
- 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
- 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 !