Close read Vue official documentation series 🎉


The necessary

Data must be a function

To prevent component reuse when multiple component instances share a single data source, the component’s data option should be a function that returns a separate object each time it is instantiated.

Since new Vue({}) is only instantiated once, you can use object style on the root instance.

new Vue({
    data: {bar:'foo'
    },
    el:'#app'
});
Copy the code

Prop definitions are as detailed as possible

Include at least a “type” declaration. Detailed Prop has the following benefits:

  • Specification component documentation.
  • Type detection and hints to reduce potential errors.

Always set the key for V-for

This helps Vue better maintain state within child components and reuse DOM element objects.

Avoid using V-for with V-if

Because v-for has a higher priority than V-IF, a condition judgment is performed on each pass. A better way:

  1. Is it possible tov-ifExtract out of the container? Use it as av-forThe preconditions of.
  2. The data is filtered before the loop.

Set scope for the style

  • Styles in top-level App components and layout components should be global to the application.
  • For a UI component library, the styles of its components should be based onclassStrategies, such as selectionBEMSo that users of the component library can override styles in a normal way, without the mental burden of CSS scoping, selector priorities, etc.
  • For regular Vue single-file components, always turn them onscopedAttribute Implements the CSS Module.

【 参 考 答 案 】

CSS, the style language, has always been globally scoped since it was designed. With the rapid development of Web applications, the problem of style naming conflicts is more and more frequent. Every time a selector name is defined, it is necessary to consider whether the same name exists in other style files, which undoubtedly adds extra development costs and potential problems for developers. To do this, we want an ideal model where, for example, when writing styles, we can name them whatever we want, as long as the selector is semantic and readable, and we don’t have to worry about style naming conflicts.

Now, with this goal in mind, and having seen the modular approach of the JavaScript community come of age, the CSS community has come up with a similar concept – the CSS Module.

CSS Module CSS modular already, there is no a unified the official concept, it is much more from the perspective of the project, how to realize the isolation, the scope of the style to avoid multiple components between the style of the pollution, in a separate component in writing style, style conflict the developers don’t need to produce an additional burden in the heart.

At present, the CSS Module is mainly implemented in the following ways:

  • BEM
  • The Vuescoped
  • CSS Modules
  • CSS in js

BEM

Standardize the naming style by manual means. It makes it easier to extract the HTML hierarchy and structure relationships associated with CSS, while at the same time creating some scope-isolation (long, regular names to make selector names as unique as possible).

The Vuescoped

For components with scoped identifiers, Vue assigns a globally unique attribute selector to all elements within the component. For example, [data-V-5298C6bf], and then all CSS selectors in the component will be named with this property selector, so that the CSS within the component will only apply to elements in the current component, not to styles outside the component’s scope.

<template>
  <header class="header">header</header>
</template>

<style scoped>
.header {
  background-color: green;
}
</style>
Copy the code

The compiled:

<header class="header" data-v-5298c6bf>header</header>

<style>
.header[data-v-5298c6bf] {
  background-color: green;
}
</style>
Copy the code

CSS Modules

Module features provided by Webpack CSS-loader. Compile builds that map and replace the corresponding real CSS selector names with the generated hash, thus providing scoped isolation of CSS styles in the way they are named, ensuring that each CSS selector is unique.

//style.css
.title {
   color:red
}
Copy the code

The compiled

{
    "title":"title_DW78T"
}
Copy the code

For example, React imports style files in the same way as templates. You only need to name the imported style files in the style of xxx.module. CSS and use className={styles.title}.

Vue uses scoped by default. If you want to switch to CSS Modules, you can replace scoped with Module. In SFC, the style and HTML are written together. So Vue will automatically inject the generated CSS object into a calculated property of the component called $style. You can use dynamic class bindings in your modules:

<template>
  <p :class="$style.red">
    This should be red
  </p>
</template>
<style module>
.red {
  color: red;
}
.bold {
  font-weight: bold;
}
</style>
Copy the code

CSS in JS

In general, a CSS in JS library such as Styled- Components scoped CSS in the same way as CSS Modules, using a unique hash selector name. However, there is a different style of routing, such as Radium, the CSS in JS library, which completely inline CSS styles to labels so that each label is a separate scope.

Private property name

Private property names should have a namespace attached to avoid collisions with other authors.

var myGreatMixin = {
  // ...
  methods: {
    $_myGreatMixin_update: function () {
      // ...}}}Copy the code

It is highly recommended

Single file component file name

PascalCase naming is recommended.

Base component name

Underlying components that apply specific styles and conventions (that is, components that present classes without logic or stateless) should all start with a specific prefix, such as Base, App, or V.

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

components/
|- AppButton.vue
|- AppTable.vue
|- AppIcon.vue

components/
|- VButton.vue
|- VTable.vue
|- VIcon.vue
Copy the code

One problem to point out here is that there are many UI component libraries that do not use this specification when naming their component files, but all use this specification when naming component instances, such as AntV.

const Card = defineComponent({
  name: 'ACard'});Copy the code

Tightly coupled component name

Child components that are tightly coupled to the parent component should be named prefixed with the parent component name.

components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
Copy the code

The order of words in which component files are named

Component names should start with high-level (usually generically described) words and end with descriptive modifiers. Simply put, this means that your component name comes first and the function description of the component comes second, because the editor order makes it easier to navigate between component files.

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

Example:

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

Self-closing assembly

A self-merging component is actually a single tag within an HTML tag, which is referred to in the specification as an empty element.

Browsers only support single-tag writing of native tags, so for templates that are not processed by the Vue compiler, do not include single-tag writing of custom tags, as this does not comply with the HTML standard specification.

The main scenario is to use global components directly in an HTML file in a pure javascript-driven environment, for example:

<! ---index.html-->
<div id="app">
    <! -- This is not good 🙅♀️-- >
   <side-nav />
</div>
Copy the code

If it is a string template, X-template, or SFC, these will be converted by the compiler.

Component names in templates are case sensitive

Because HTML is case-insensitive, it is recommended to use custom components in templates in the kebab-case fashion for most common scenarios.

Component names in JS/JSX are case sensitive

The component name in JS/JSX should always be PascalCase.

js

Vue.component('MyComponent'{});Copy the code

jsx

<MyComponent/>
Copy the code

Full word component name

Autocompletion in editors has made writing long names very cheap, and the clarity it provides is invaluable. Infrequently used abbreviations should be avoided in particular.

Counterexample components / | - SdSettings. Vue | - UProfOpts. Good example vue components / | - StudentDashboardSettings. Vue | - UserProfileOptions.vueCopy the code

Case of Prop name

The props should always use camelCase in component logic, and kebab-case in templates and JSX. We simply follow the conventions of each language. More natural in JavaScript is camelCase. In HTML it is kebab-case.

js

Vue.component("MyComponent", {props: ["postTitle"]});
Copy the code

jsx

<MyComponent post-title='title' />
Copy the code

Multiple attribute a newline

Elements with multiple attributes should be written in multiple lines, one for each attribute.

Simple expressions in templates

Component templates should contain only simple expressions, and complex expressions should be refactored to evaluate properties or methods.

Simple calculation properties

Complex computed properties should be split into as many simpler computed properties as possible.

If multiple reactive values are used in a calculated attribute, and the results of each reactive value need to be calculated simply, the granularity of the calculated attribute should be continued.

The easiest way to do this is to look at the computed properties in your code. If there are more than 3 or 4 lines of code, consider splitting.

Attribute value of quotes

Non-empty HTML attribute values should always be quoted to improve code readability.

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

Instructions for

  • # -> v-slot
  • @ -> v-on
  • : -> v-bind

recommended

The order of element attributes

Based on our existing programming experience, we recommend that the Vue built-in attribute be written in front of the component tag and the user-defined attribute be written in the back. This helps us know the built-in behavior of Vue much earlier.

<component 
    :is="my-component" 
    v-if="isRead" 
    ref="target" 
    :content="post-content" 
/>
Copy the code

Use caution

Key is not used in v-if/ V-else -if/ V-else

If a set of V-if + V-else elements are of the same type, it is best to use key (such as two elements)

Elements).

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

By default, Vue updates the DOM as efficiently as possible. This means that when it switches between elements of the same type, it fixes existing elements, rather than removing the old one and adding a new one in the same place. If elements that are not identical are identified as identical, unexpected results can occur.

Element selector in scoped

Element selectors should be avoided in scoped.

In the Scoped style, class selectors are better than element selectors because element selectors are slow to use in large quantities.

To scope the style, Vue adds a unique attribute to the element, such as data-V-f3f3eg9. Then modify the selector so that only the attribute is valid for elements that match the selector (such as button[data-V-f3f3eg9]). The problem is that a large number of element-attribute selectors (such as Button [data-V-f3f3eg9]) can be slower than class-attribute selectors, so use class selectors whenever possible.

Implicit parent-child component pass values

Parent component communication should take precedence over this.$parent or directly changing the prop passed by the parent component in the child component. Data is passed down using Prop, and events are passed up using events to trigger changes in values.

Non-flux global state management

Global state should be managed through Vuex in preference to this.$root or a global event bus. The reason is simple: Vuex offers more features and solves a more comprehensive problem.

Managing state through this.$root and/or the global event bus is convenient for many simple cases, but not for most applications.

Vuex is the official Flux-like implementation of Vue, which provides not only a central area for managing state, but also a great tool for organizing, tracking, and debugging state changes. It is well integrated into the Vue ecosystem (including full Vue DevTools support).