Vue 2 x specification

The component data must be a function

When using data in a component (anywhere but new Vue), its value must be a function that returns an object, to avoid some component reuse bugs

Is not recommended

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

recommended

export default {
    data () {
        return {
          	foo: 'bar'}}}Copy the code

Prop definitions are as detailed as possible

Prop definitions should be as detailed as possible, at least specifying its type, to avoid some potential type errors

Is not recommended

// Source: SRC \components\chart\embedexcel\ datafiltermodal.vue
props: ["position"."spread"]
Copy the code

recommended

props: {
    strProp: {
        type: String.default: ' '
    },
    arrProp: {
        type: Array.default: () = >[]},objProp: {
        type: Object.default: () = >({})}}Copy the code

V-for sets unique key values

When v-for is used, a unique key must be set so that Vue can minimize possible DOM changes during rendering

Is not recommended

<! -- Source: SRC \ Components \easy-more\ easyShowmoreTooltip.vue -->
<p v-for="(item,index) in arr">
  	{{item[keyVal]}}
</p>
Copy the code

recommended

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

Avoid using v-for and V-if together (1)

When filtering items in a list, never use v-for and V-if on the same element, instead use computed attributes

Is not recommended

<div
    v-for="user in users"
    v-if="user.isActive"
    :key="user.id"
>
  	{{ user.name }}
</div>
Copy the code

recommended

<div
  	v-for="user in activeUsers"
  	:key="user.id"
>
  	{{ user.name }}
</div>
Copy the code
computed: {
    activeUsers: function () {
      	return this.users.filter(() = > user.isActive)
    }
}
Copy the code

Avoid using v-for and V-if together (2)

When hiding a list that should be hidden, never use v-for and V-if on the same element. Instead, add a parent element and use V-if on the parent element

Is not recommended

<! - source: SRC \ components \ toolBarComponent \ liquidfill \ liquidfillNumericalSet vue - >
<div v-if=! "" numericalSet.configs.length" class="noInfo">
</div>
<div v-for="(field,indexs) in numericalSet.configs" :key="field.columnId" v-else>
</div>
Copy the code

recommended

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

Mixins use private property names

To avoid attribute conflicts when mixin, it is recommended to use the $_ prefix for plugins, mixins, and other custom private attributes that are not considered as public apis

Is not recommended

// Source: SRC \views\Pages\Dashboard\mixins\ embedexcelfuncs.js
export const embedexcelFuncs = {
    data () {
        return {
          	styleTemp: {}}}.methods: {
          handleSpaceList(){}}}Copy the code

recommended

export const myGreatMixin = {
    data () {
        return {
          	$_myGreatMixin_title: ' '}},methods: {
      	$_myGreatMixin_update: function () {}}}Copy the code

Component names should consist of multiple words

Component names should always be multiple words (except for root App and Vue built-in components) and named in a big hump style to avoid conflicts with existing or future HTML elements

Is not recommended

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

// Source: SRC \ Components \ Modal \confirm.vue
export default {
  	name: 'confirm'.// ...
}
Copy the code

recommended

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

export default {
  	name: 'BaseConfirm'.// ...
}
Copy the code

Sets the scope for the component’s style

Single-file components should have styles scoped so that the styles of the current component do not affect the styles of other components, except in special cases (such as when the DOM of part of an Element component is transferred under the body)

Is not recommended

<! -- source: SRC \ Components \chart\ slicerTabs \ relevancecharts.vue -->
<template>
  	<div class="common_bottom_20"></div>
</template>

<style>
.common_bottom_20 {
  	margin-bottom: 20px;
}
</style>
Copy the code

recommended

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

<style scoped>
.button {
    border: none;
    border-radius: 2px;
}
</style>
Copy the code

The file name of the single-file component

The file naming style of single-file components should be consistent, with a unified big hump

Is not recommended

components/
|- table-page.vue
|- dragRightIcon.vue
|- UserInfoModal.vue
Copy the code

recommended

components/
|- TablePage.vue
|- DragRightIcon.vue
|- UserInfoModal.vue
Copy the code

Component names in templates are case sensitive

Uniform kebab naming in Vue templates (not mandatory)

Is not recommended

<mycomponent/>
<myComponent/>
<MyComponent></MyComponent>
Copy the code

recommended

<my-component></my-component>
Copy the code

Self-closing assembly

In the Vue template, components are automatically closed

Is not recommended

<my-component></my-component>
Copy the code

recommended

<my-component/>
Copy the code

Full word component name

Component names should tend to be full words rather than abbreviations

Is not recommended

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

recommended

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

Prop name case

When declaring a prop, it should always be named with a small hump, and in Vue templates it should always be named with a kebab

Is not recommended

props: {
  	'greeting-text': String
}
Copy the code
<! -- source: SRC \views\Pages\Workbench\selfSupportTemplete\header.vue -->
<easy-select searchWidth="278px"></easy-select>
Copy the code

recommended

props: {
    greetingText: {
      	type: String.default: ' ',}}Copy the code
<welcome-message greeting-text="hi"/>
Copy the code

An element with multiple attributes

Elements with multiple attributes should be written in multiple lines, one for each attribute, because this is easier to read

Is not recommended

<Icon type="ios-search" @click="changeSearchStatus" v-if='! info.isSearch'></Icon>
Copy the code

recommended

<my-component
    foo="a"
    bar="b"
    baz="c"
></my-component>
Copy the code

Simple expressions in templates

Component templates should contain only simple expressions, and complex expressions should be refactored into computed properties or methods because computed properties and methods are intuitive and reusable

Is not recommended

<! SRC \views\Pages\Authority\basicSet\ ocAutoconfig. vue -->
{{item.split('-status:')[0].split('/')[0]}}
Copy the code

recommended

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

Compute the property SRP

Complex computational properties should be broken up into as many simpler properties as possible, with each property doing one thing (the single responsibility principle) so that they are easier to test, read, and embrace change better

Is not recommended

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

recommended

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 the code

Attribute value with quotation marks

Non-empty attribute values should always be quoted (double quotes are recommended) to improve readability

Is not recommended

<! -- Source: SRC \ Components \chart\ slicerTabs \ slicerTabs.
<el-date-picker
  	:type=timeFilterType[item.columnFilterType]
  	:format=timeFormat[item.columnFilterType]
>
</el-date-picker>
Copy the code

recommended

<input type="text">
<app-side-bar :style="{ width: sidebarWidth + 'px' }"></app-side-bar>
Copy the code

Unification of instruction abbreviations

Directive abbreviations (: for V-bind:, @ for V-on:, and # for v-slot:) should be used either or neither, and are recommended

recommended

<template #footer>
    <div @click="divClick">
      	<div :someProp="propData"></div>
    </div>
</template>
Copy the code

The component/instance options are in the same order

Component/instance options should have a uniform order

  1. Side effects (trigger effects outside the component)
    • el
  2. Global awareness (requires knowledge beyond components)
    • name
    • parent
  3. Component type (Changing the type of the component)
    • functional
  4. Template modifier (changes how templates are compiled)
    • delimiters
    • comments
  5. Template dependencies (resources used within templates)
    • components
    • directives
    • filters
  6. Combine (merge property into options)
    • extends
    • mixins
  7. Interface (component interface)
    • inheritAttrs
    • model
    • props/propsData
  8. Local state (local responsive property)
    • data
    • computed
  9. Events (callbacks triggered by reactive events)
    • watch
  10. Lifecycle hooks (in the order in which they are invoked)
    • beforeCreate
    • created
    • beforeMount
    • mounted
    • beforeUpdate
    • updated
    • activated
    • deactivated
    • beforeDestroy
    • destroyed
  11. Non-reactive Property (independent of the instance property of the responding system)
    • methods
  12. Render (declarative description of component output)
    • template/render
    • renderError

Examples of common component options

new Vue({
    el: ' '.name: ' '.components: {},
    directives: {},
    filters: {},
    mixins: [].props: {},
    data () {},
    computed: {},
    watch: {},
    beforeCreate () {},
    created () {},
    beforeMount () {},
    mounted () {},
    beforeDestroy () {},
    destroyed () {},
    methods: {},
    template: ` `,
    render () {}
})
Copy the code

The sequence of element attributes is unified

Elements (including components) should have a consistent order of attributes (not mandatory)

  1. Define (provide options for components)
    • is
  2. List rendering (creating multiple variations of the same element)
    • v-for
  3. Conditional rendering (whether the element is rendered/displayed)
    • v-if
    • v-else-if
    • v-else
    • v-show
    • v-cloak
  4. Render (Change how elements are rendered)
    • v-pre
    • v-once
  5. Global awareness (requires knowledge beyond components)
    • id
  6. Unique attribute (attribute that requires a unique value)
    • ref
    • key
  7. Bidirectional binding (combining bindings with events)
    • v-model
  8. Other attributes (all plain bound or unbound attributes)
  9. Events (Component event listeners)
    • v-on
  10. Content (overrides the content of the element)
    • v-html
    • v-text

Common Attribute Examples

<input
    v-for=""
    v-once
    id=""
    ref=""
    :key=""
    v-model=""
    class=""
    style=""
    v-on=""
    v-html=""
/>
Copy the code

The order of the top-level elements of a single-file component

Single-file components should always keep the order of the

Is not recommended

<style>/ *... * /</style>
<template>.</template>
<script>/ *... * /</script>
Copy the code

recommended

<template>.</template>
<script>/ *... * /</script>
<style>/ *... * /</style>
Copy the code

Use element selectors sparingly in scoped

Element selectors should be avoided in Scoped because class selectors are faster than element selectors in scoped style

Is not recommended

<style scoped>
/* Source: SRC \layouts\ sidermenu. vue
button span {
  	color: #447ee7;
}
</style>
Copy the code

recommended

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

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

Avoid implicit communication between parent and child components

Parent component communication should take precedence over this.$parent or changing prop via prop and events

Is not recommended

Vue.component('TodoItem', {
    props: {
        todo: {
            type: Object.required: true}},template: '<input v-model="todo.text">'
})
Copy the code
Vue.component('TodoItem', {
    props: {
        todo: {
            type: Object.required: true}},methods: {
        removeTodo () {
            var vm = this
            vm.$parent.todos = vm.$parent.todos.filter(function (todo) {
              	returntodo.id ! == vm.todo.id }) } },template: `  {{ todo.text }}   `
})
Copy the code

recommended

Vue.component('TodoItem', {
    props: {
        todo: {
            type: Object.required: true}},template: `  `
})
Copy the code
Vue.component('TodoItem', {
    props: {
        todo: {
            type: Object.required: true}},template: `  {{ todo.text }}   `
})
Copy the code

Change the status by committing

Explicitly modifying the state rather than assigning a value to it directly should be done with COMMIT, which allows you to track state changes more explicitly, and allows some debugging tools to log each state change (not mandatory).

Is not recommended

// source: SRC \views\Pages\Workbench\selfSupportTemplete\setMenu\ crosstable.vue
this.$store.state.selfOrderLimit = item.nodeData.selfOrderLimit
Copy the code

recommended

this.store.commit('changeSelfOrderLimit', item.nodeData.selfOrderLimit)
Copy the code

Good use of modifiers

For most events, Vue provides modifiers that can be used to improve development efficiency

Is not recommended

<! SRC \views\Pages\Workbench\electronicForm\ TableData.vue -->
<div @click="stopPropagation($event)">
Copy the code
stopPropagation($event) {
  	$event.stopPropagation();
}
Copy the code

recommended

<div @click.stop>
Copy the code

The request is written in CREATED

It is a best practice to handle requests in Created, except in special cases (such as dynamic components that use keep-alive)

Is not recommended

mounted () {
    api.getAuthTreeAjax()
      	.then(() = > {})
      	.catch(() = >{})}Copy the code

recommended

created () {
    api.getAuthTreeAjax()
      	.then(() = > {})
      	.catch(() = >{})}Copy the code

A README should be attached to a common component

Common components should be written with a README that details the props, slots, events, and instructions for exposed methods.

Common component README template

### Component descriptionHere is the component description### props| | | | type default values describe | | -- - | -- - | -- - | -- - | | disabled | Boolean | | | false if disable components# # # slot| | slot name slotProps description | | | -- - | -- - | -- - | | default |`{ userName: 'John', userAge: 24 }`The default slot | |# # #| event name | | return value is the return value type description | | | -- - | -- - | -- - | -- - | | on - select | | the currently selected item String option trigger the event | | is elected### Method of exposure| | | parameters method name type description | | | -- - | -- - | -- - | -- - | | resetForm | - | - | | reset formCopy the code