The final chapter of the book discusses best practices and style norms for vue.js development projects,

Set the property Key for the list rendering

The special attribute key is mainly used in vue. js virtual DOM algorithm to identify virtual nodes when comparing old and new virtual nodes.

Use key in v-if/ V-if-else/V-else

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

Elements)

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

The route switching component does not change

When the page switches to an address with the same route but different parameters, the component’s lifecycle hook does not re-render

const routes = [
  {
    path:'/detail/:id',
    name:'detail',
    component:Detail
  }
]
Copy the code

When we switch from route /detial/1 to detail/2, nothing happens to the component. This is because vue-Router recognizes that the two routes use the same component for reuse and does not recreate the component, so the component’s lifecycle hook does not fire.

Route navigation guard beforeRouterUpdate

Vue-router provides a navigation guard, beforeRouterUpdate, which is called when the current route changes and the component is being reused, so you can define a routing navigation guard within the component to solve this problem

Observe the changes to the $route object

The watch can monitor the changes of routing objects and respond to routing changes

const User = { template:'... ', watch:{'$route'(to,from){// Respond to route changes}}}Copy the code

This approach also solves the above problem, but at the expense of adding a watch to the component, which incurs memory overhead that relies on tracing

This should allow more accurate monitoring of parameter changes

const User = { template:'... 'watch: {$route. Query. Id' () {/ / request personal description information '$route. Query. Page' () {/ / request listCopy the code

Add a property key to the router-view component

It’s very clever, very violent, but very effective.

<router-view :key="$router.fullPath"></router-view>
Copy the code

This way the routing component is enchanted and recreated each time it switches

Add query for all routes

If it were a uniform query, we would have trouble adding arguments each time.

Configure a basic Query globally

Use global guard beforeEach

In fact, the global guard beforeEach does not have the ability to modify Query, but you can use the next method to interrupt the current navigation and switch to a new navigation, adding some new Query methods that will loop indefinitely because they will always be intercepted by the global guard beforeEach

const query = { referer:'hao360cm'} router.beforeEach((to,from,next)=>{ to.query.referer? next():next({... to,query:{... to.query,... query}})Copy the code

Using function hijacking

This way, the principle is: by intercepting the router. History. TransitionTo method, within the vue – the router before switching routing parameters are added to the query

const query = {referer:'hoa360cn'} const transitiosnTo = router.history.transitionTo router.history.transitionTo = function(location,onComplete,onAbort){ location = typeof location === 'object'? {... location,query:{... location.query,... query}}:{path:location,query} transitionTo.call(router.history,location,onComplete,onAbort) }Copy the code

However, modifying the vue-router internal method to achieve the purpose is also a dangerous operation

Distinguish the use boundaries of Vuex and props

When a component gets state from the Vuex Store, and when it uses props to receive state passed in by the parent component. A generic component defines a detailed prop and can be as detailed as possible, at least by specifying its type.

  • The API of the component is stated, so it is easy to understand the usage of the component.
  • In a development environment, if an ill-formed prop is supplied to a component, vue.js will issue a warning on the console to help us catch potential sources of error

Avoid using v-if with V-for

Vue. Js officially strongly advises against using both v-if and v-for on the same element

<ul> <li v-for="user in users" v-if="user.isActive" :key="user.id"> {{ user.name }} </li> </ul> <! (function(user){return this.users.filter(function(user){return user.isActive }) } } </script> <! - change the template - > < ul > < li v - for = "user in activeUsers" : : key = ". The user id "> {{user. The name}} < / li > < / ul > <! - for the second case - > < ul > < li v - for = "user in the users" v - if = "shouldShowUsers" > {{user. The name}} < / li > < / ul > <! - update - - > < ul v - if = "shouldShowUsers" > < li v - for = "user in the users" > {{user. The name}} < / li > < / ul >Copy the code

Set the scope for the component style

CSS rules are global, and style rules for any one component apply to the entire page.

In vue.js, you can set the component style scope via the Scoped feature or CSS Modules(a class-based BEM like strategy)

<template> <button class=" BTN btn-close">X</button> </template> // use scoped <style scoped>. border-radius: 2px; } </style> <template> <button :class="[$style.button,$style.buttonclose]">X</ style> </template module> .button{ border:none } .buttonClose{ background-color: red; } </style>Copy the code

Avoid element selectors in scoped

In the Scoded style, class selectors are better than element selectors because heavy use of element selectors is slow

To set the style scope, vue.js adds a unique feature to the element, such as data-v-f3f3eg9. If you use an element selector like (Button [data-v-f3f3eg9])

Avoid implicit parent-child component communication

Instead of using this.$parent or changing prop, we should communicate between parent components via prop and events.

An ideal vue.js application is “prop pass down, event pass up”

Changes to prop or this.$parent can make it easy to connect deeply coupled components, but not very good

How are single-file components named

The case of the file name of a single-file component

Always capitalize words (PascalCase) or always connect them horizontally (kebab-case)

// Bad myComponent.vue myComponent.vue // good myComponent.vue my-component.vueCopy the code

Base component name

Basic components that apply a specific style and convention (that is, non-logical or stateless components that present classes) should all start with a specific prefix, such as Base,App, or V. These components provide the basic style and behavior for your application

Vue basetable.vue baseicon.vue appbutton.vue apptable.vue  AppIcon.vue VButton.vue VTable.vue VIcon.vueCopy the code
  • Easy to sort, the basic components of the application are all listed together
  • The same prefix can be easily imported by working with webapck to import the corresponding component
var requireComponent = ruquire.context("./src",true,/^Base[A-Z])
requireComponent.keys().forEach(funciton()fileName){
  var baseComponentConfig = requireComponent(fileName)
  baseComponentConfig = baseComponentConfig.default || baseComponentConfig
  var baseComponentName = baseComponentConfig.name || (fileName.replace(/^.+\//,'').replace(/\.\w+$/,''))
  Vue.component(baseComponentName,baseComponentConfig)
}
Copy the code

Singleton component name

These components will never accept prop

TheHeadeing.vue
TheSidebar.vue
Copy the code

Tightly coupled component name

Child components that are tightly coupled to the component should be named prefixed by the parent component

Typically, we can solve this problem by nesting child components in a directory named after the parent component

Components/TodoList/ Item/ index.vue button.vue index. Vue  component/ TodoList/ Item/ Button.vue Item.vue TodoList.vueCopy the code
  • This results in many files with the same name,
  • Multi-layer nesting also increases the subdirectory structure and the time spent searching

So here we can do that

components/ TodoList.vue TodeListItem.vue TodeListItemButton.vue components/ SearchSidebar.vue SearchSidebarNavigation. Very bad example vue components/TodoList vue TodoItem. Vue TodoGutton. Vue components/SearchSidebar vue NavigationForSearchSidebar.vueCopy the code

Full word component name

SdSettings. Vue UProfOpts. Examples of vue recommend StudentDashbordSettings. Vue UserProfileOptions. VueCopy the code

Component names are multiple words

Component names should always consist of multiple words, except for the root component App. This avoids conflicts with present and future HTML elements because all HTML element names are single words

Vue.component('todo',{}) export default{name:' todo'}  Vue.component('todo-item',{}) export default{ name:'TodoItem' }Copy the code

Component names in templates are case sensitive

Component names should always be capitalized in single-file components and string templates, but always delimited in DOM templates

// In single-file component and string templates <MyComponent/> // in DOM templates < my-Component ></my-component> or: // on all enemies < my-Component ></my-component>Copy the code

Case of prop name

Props :{'greeting-text':String} <welcome-message gereetingText = "hi"/> <welcome-message gereeting-text = "hi"/>Copy the code

Order of component/instance options

  • name
  • components directives filters
  • extends mixins
  • props/propsData
  • data computed
  • Watch Lifecycle hooks
  • methods