This article has participated in the review and gift drawing activity , Nuggets Badge *2, Comment on relevant content to participate in the lucky draw   Check the details

## Preface

Recently, I went into the pit Vue project , It feels like falling into the ancestral shit mountain , Poor readability , Not to mention maintainability . So I'd like to take this column to mention a few points about Vue Suggestions for code readability , If you think it's useful, give it a compliment , If you think the suggestion is unreasonable, comment and criticize , There are better suggestions. Welcome to comment and add .

## One 、 Make good use of components to make the code more organized

Never put the implementation code of a page in one .vue In file , Unless this page is very simple , Otherwise, this .vue The code in the file will be long and smelly .

Vue The purpose of providing components is not just to reuse , It can also be used to split code , Even making good use of components can optimize the rendering and updating speed of pages . This is because Vue When the page is rendered and updated, the components in the page will not be updated , Unless the component props perhaps slot The referenced data changes .

You can use the following steps to put a Vue The page is divided into components to make the code more organized

### 1.1、 extract UI Components

How to define UI What about the components ？ It is recommended to distinguish by whether the server data is processed or not UI Components and business components . For example, load pop-up window 、 The second confirmation pop-up window 、 Message prompt box and so on belong to UI Interactive components .

take UI After the component is extracted , You can put UI The interactive code is separated from the business interactive code . Remember not to UI Write business code in component , such UI Components will not be reusable .

Take a counterexample , Add the business code to be processed after secondary confirmation in the secondary confirmation pop-up window , Lead to UI Components will not be reusable . We can imitate ElementUI The secondary confirmation pop-up window is called to implement a secondary confirmation pop-up window component .

this.$confirm(message, title, options) .then(res =>{}) .catch(err =>{}) Copy code  In this way, the business code can be written in then In the callback function of , The core implementation code of the component is as follows : //confirm.vue <template> <div v-show="show"> //... <div @click="ok"></div> <div @click="cancel"></div> </div> </template> <script> export default { data(){ return { show: false, } }, methods:{ ok(){ this.show = false; this.resolve(); }, cancel(){ this.show = false; this.resolve(); }, } } </script> Copy code  //index.js import Vue from 'vue'; import options from './confirm.vue'; const Confirm = Vue.extend(options); let confirm = undefined; const ConfirmInit = (options = {}) => { return new Promise((resolve, reject) => { options.resolve = resolve; options.reject = reject; confirm = new Confirm({ el: document.createElement('div'), data: options }) document.body.appendChild(confirm.$el);
Vue.nextTick(() => {
if(confirm) confirm.show = true;
})
return confirm;
})
}
Vue.prototype.$confirm = ConfirmInit; Copy code  //main.js import 'components/confirm/index.js';// Global registration secondary confirmation pop-up window confirm Components Copy code  ### 1.2、 Extract business components by module A page can be divided into multiple areas , Like the head 、 Bottom 、 Sidebar 、 List of goods 、 Member list, etc , Each region can be used as a module to extract business components . ### 1.3、 Extract functional components by function Extract business components by module , At this time, the business component may still be very large , Therefore, the functional components should be further extracted according to the function . The functions are big and small , We should pay attention to several principles ： • Too simple functions are not extracted For example, a collection function , Just request an interface , Don't extract functions like this . Only the functions of logical operations with a certain complexity can be extracted . • Single function , A functional component handles only one business . For example, a file reader component , There is a need , It is required to automatically collect the file after it is opened , So where to write the collection logic code ？ Maybe you write the collection logic code in the method of listening for the successful opening of files in the component without thinking about it , After a while , The requirement should be added to the reading record first, and then click the collect button to collect , When you modify the code in the component, you find that another page also references this component , Therefore, an additional parameter should be added to the component to distinguish business scenarios , Business scenarios are superimposed as requirements change , Various judgment logic will be added to the code of the component , Over time, it becomes long and smelly , Obviously, this practice is not allowed to . The correct approach is to customize an event on the component label on-fileOpen-success, use handleFileOpenSuccess Function to listen for this event . <fileReader @on-fileOpen-success="handleFileOpenSuccess"></fileReader> Copy code  Execute in the method of listening for the successful opening of the file in the component this.$emit('on-fileOpen-success',data) Trigger this event , among data You can pass file information out , stay handleFileOpenSuccess Function to handle business interactions such as collecting or adding history records and then collecting . This approach makes the file reader component single .

• Functional components should contain as few as possible UI part ,UI Partly with slot Slot incoming , This makes the component more pure , More reusable .

For example, the upload icon of the upload component , It's impossible to follow UI When the design changes, add an upload icon to it , You can use slot The slot passes the upload icon into .

//upload.vue
<template>
<div>
<slot name="icon"></slot>
</div>
</template>
Copy code 
//index.vue
<template>
<div>
<template #icon>
</template>
</div>
</template>
Copy code 

## Two 、 utilize v-bind Make component properties more readable

If you want to treat all the attributes of an object as prop Incoming components componentA, You can use... Without parameters v-bind. for example , For a given object params

params: {
id: 1,
name: 'vue'
}
Copy code 

Before optimization

<componentA :id=params.id :name="params.name"></componentA>
Copy code 

After optimization

<componentA v-bind="params"></componentA>
Copy code 

## 3、 ... and 、 utilize $attrs And$listeners To encapsulate third-party components

### 1、$attrs In encapsulating third-party components , There is always a problem , How to use the properties and events of third-party components through encapsulated components . Like encapsulating a elementUi In the component Input Input box components myInput, When an error is entered, an error prompt is displayed below the input box . myInput The component code is as follows ： <template> <div> <el-input v-model="input"></el-input> <div>{{errorTip}}</div> </div> </template> <script> export default { props:{ value:{ type:String, default:'', }, errorTip:{ type:String, default:'', } }, data(){ return { } }, computed:{ input:{ get(){ return this.value }, set(val){ this.$emit('input',val)
}
}
}
}
</script>
Copy code 

This call myInput Components , among errorTip Enter an error prompt for the input box .

<myInput v-model="input" :errorTip="errorTip"></myInput>
Copy code 

If you want to in myInput Add a... To the component disabled Property to disable the input box , How to achieve it ？ Most students do this

<template>
<div>
<el-input v-model="input" :disabled="disabled"></el-input>
<div>{{errorTip}}</div>
</div>
</template>
<script>
export default {
props:{
//...
disabled:{
type:Boolean,
default:false
}
},
//...
}
</script>
Copy code 

After a period of time, I will be in myInput Add... To the component el-input Other properties of the component ,el-input The total number of components is 27 More than a , What should I do , One by one prop Pass in , This is not only poor readability, but also cumbersome , It can be used $attrs One step in place , Let's take a look first attrs The definition of . $attrs: Contains inaction in the parent scope prop Be identified ( And get ) Of attribute binding (class and style With the exception of ). When a component does not declare anything prop when , This will include all bindings for the parent scope (class and style With the exception of ), And through v-bind="$attrs" Incoming internal components <template> <div> <el-input v-model="input" v-bind="$attrs"></el-input>
<div>{{errorTip}}</div>
</div>
</template>
Copy code 

It is not enough , You have to inheritAttrs Option set to false, Why? , Take a look at inheritAttrs The definition of options is clear .

By default, the parent scope is not recognized as props Of attribute binding (attribute bindings) will “ Back off ” And as ordinary HTML attribute Apply to the root element of the subcomponent . When composing a component that wraps a target element or another component , This may not always be in line with expected behavior . By setting inheritAttrs by false, These default behaviors will be removed . And by $attrs You can make these attribute take effect , And through v-bind Explicitly bound to non root elements . Be careful ： This option does not affect class and style binding . Simply speaking , hold inheritAttrs Set to false,v-bind="$attrs" To take effect .

<template>
<div>
<el-input v-model="input" v-bind="$attrs"></el-input> <div>{{errorTip}}</div> </div> </template> <script> export default { inheritAttrs: false, props:{ value:{ type:String, default:'', }, errorTip:{ type:String, default:'', } }, data(){ return { } }, computed:{ input:{ get(){ return this.value }, set(val){ this.$emit('input',val)
}
}
}
}
</script>
Copy code 

So you can clearly el-input The properties and properties of the component myinput The properties of components are distinguished , Component's props The readability of options is greatly improved .

### 2、$listeners So how to achieve in myIpput Use... On components el-input What about the custom events on the component , Maybe your first reaction was this.$emit.

<template>
<div>
<el-input
v-model="input"
v-bind="$attrs" @blur="blur" > </el-input> <div>{{errorTip}}</div> </div> </template> <script> export default { //... methods:{ blur(){ this.$emit('blur')
}
}
}
</script>
Copy code 
<myInput v-model="input" :errorTip="errorTip" @blur="handleBlur"></myInput>
Copy code 

el-input The components are 4 A custom event , Not much , If you encounter custom events, more third-party components , do , Can you add them one by one , Not only will it add a bunch of unnecessary methods, And the readability is poor, it is easy to communicate with myInput Self methods Mixed in with . You can actually use $listeners One step in place , Let's take a look first $listeners The definition of .

$listeners： Contains... In the parent scope ( Not included .native Decorator's ) v-on Event listener . It can go through v-on="$listeners" Incoming internal components .

<template>
<div>
<el-input
v-model="input"
v-bind="$attrs" v-on="$listeners"
>
</el-input>
<div>{{errorTip}}</div>
</div>
</template>
<script>
export default {
//...
}
</script>
Copy code 
<myInput v-model="input" :errorTip="errorTip" @blur="handleBlur"></myInput>
Copy code 

stay myInput In the component, as long as el-input Add... To the component v-on="\$listeners", You can go to myInput Use... On components el-input Component custom events .

## The way of drawing prizes

Premise ：

• By the end of 9 month 10 Japan , If the comment area exceeds 10 Human interaction （ Not including the author himself ）, The author can draw in his own name to give out the Nuggets badge 2 gold （ Nuggets officials bear ）

• Commentators can't be trumpets , such as LV0, No historical developments , Or just like an author's number ;

• Comments cannot appear 「 Trample 」「 Support 」「 Welcome back 」 Etc. or similar comments ;

The way of drawing prizes ：

All qualified commentators , Random sampling 2 name .

Lottery tools ：

choujiang.wiicha.com/

Opening time ：

2021 year 9 month 9 Japan 21 spot

https://qdmana.com/2021/09/20210909111329225x.html