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