Is a sunny, sunny weekend, someone to accompany the goddess to go shopping, someone to accompany the goddess to see a movie, xiaobian but quietly took out the computer. Ha ha ha, not xiaobian diaosi, goddess is sitting next to playing with her phone.
In the past two days, I have reread the vue2.0 style guide and compiled the nine key rules.
V-for sets the key value
When it comes to v-for needing to set a key, many people’s first reaction is to talk about the reason from the perspective of the diff algorithm. I prefer to give an example to illustrate the reason
Suppose you have a page whose list of pages is obtained by iterating through a set of numbers, as shown in the figure below
Sample code is as follows
<! -- Template section -->
<div id="app">
<div v-for="item in arr">
{{item}}
<input/>
</div>
<button @click="deleteData">Delete the second element</button>
</div>
Copy the code
/ / js parts
new Vue({
el: '#app',
data() {
return {
arr: [1.2.3]}},methods:{
deleteData() {
this.arr.splice(1.1)}}})Copy the code
Now you need to remove the second element. Below, we will use index as key and unique value ID as key in the render list, respectively, to see the effect of removing the second element in three scenarios
v-for
Do not usekey
Click to see a code demo
I was the third
v-for
Use indexes askey
Click to see a code demo
As you can see, use the index as
key
After the second element is removed, the number before the input field is correct, but the number after the number 3 is wrong and should be displayedI was the thirdv-for
Use the unique value ID askey
Click to see a code demo
Using id as key, the display is correct
There is a simple reason why V-for requires a key. Comparing the array [1,2,3] with [1,3], it’s easy to see that 2 has been deleted, but computers don’t do that
- The computer compares the old and new arrays and finds that 1===1 remains the same
- And then we compare 2, and we see that 2 becomes 3, so we can change 2 to 3, and we can reuse everything in the second row, just change the number
- The index deletes the element in the third row
So why not use an index as a key? When the 2 in [1,2,3] is deleted, the array length is changed from 3 to 2, and the index of number 3 becomes the index of number 2.
- The computer compares the values with key 0 and finds that they are all 1 and remain the same
- The computer compares the value of key 1 and finds that the value is changed from 2 to 3. The element is reused and the text above the element is modified
- The computer compares the value of key 2 and finds that it has been deleted, so it deletes the third element
With id as the key, each item has a unique identifier. When deleting the second item in [{id:’1′,value: 1},{id: ‘2’,value: 2}, {id:’ 3′, value:3}], the whole process is as follows
- The computer takes out the ID of the first item of the new data, then looks for it in the original data, and finds that there is data with the same ID, and the data has not changed, so it remains unchanged
- The computer continues to get the id of the second item and finds 3. Then it also finds 3 from the original data, so 3 is retained
- At this point, there is data with ID 2 in the old data, but there is no data in the new data, so delete it.
No problem !!!!
Complex logic in templates is replaced by computed properties
Vue’s ability to use expressions in templates is very convenient, but expressions are designed for simple logic processing. If you use too much or too complex logic in a template, the readability and maintainability of the template will become poor, and the entire template will appear bloated.
<! --v-if uses a series of conditional judgments, which are not readable -->
<button
v-if=" user.roles && user.roles.includes('Workflowbeheer') && data.userId === user.id && data.status === 1 "
>delete</button>
Copy the code
<template>
<button v-if="deletable">delete</button>
</template>
<script>
export default {
computed: {
// Check whether it can be deleted
deletable() {
const { data, user } = this
// Cannot edit if the current user is not a process administrator
if (user.roles && user.roles.includes('Workflowbeheer')) {
// If the current user is the process initiator and the status is not started, the user can be deleted
return data.userId === user.id && data.status === 1
}
return false}}}</script>
Copy the code
Avoid mixing V-for with V-if
When developing a VUE project, you might come across code like this
<ul>
<li v-for="item in list" v-if="item.visible" :key="item.id">
{{ item.name }}
</li>
</ul>
Copy the code
If esLint is enabled in your project, you might see an exception like the following (esLint vue/no-use-v-if-with-v-for rule needs to be enabled)
The 'list' variable inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if'.
Copy the code
When processing instructions in vue, V-for has a higher priority than V-if, so the above code can be simulated with JS as
list.map(item= > {
if(item.visible) {
return item.name
}
})
Copy the code
As you can see from the above code, even if visible is false for most of the data, the entire list is traversed once. If you need to walk through the entire array each time, it will affect speed, especially if you need to render a small part of it.
The above problem can be handled using computed properties
<ul>
<li v-for="item in getList" :key="item.id">
{{ item.name }}
</li>
</ul>
computed: {
getList() {
return this.list.filter(item => {
return item.visible
})
}
}
Copy the code
With the above code, we can gain the following benefits
- The filtered list is recalculated only when the list array changes, making filtering more efficient.
- After using v-for=”item in list”, we only iterate over the data that needs to be displayed during rendering, rendering is more efficient.
- Decoupled render layer logic, maintainability is relatively high.
Use private properties/methods whenever possible
When developing a VUE component, we can call the methods provided by the component through the ref of the component. However, some methods inside a component are private and should not be called externally. However, there are no private methods in JS as there are in other languages (such as Java’s private), so the convention in JS is to use properties or methods that begin with _ to indicate private methods.
Public selectRows(rows) {}, private external selectRows(rows) {}, private external selectRows(rows) {}, private external selectRows(rows) {}Copy the code
Defining private properties/methods in VUE differs from the usual JS conventions. Inside the Vue, private properties/methods on the Vue prototype have been defined with the prefix _. Continuing to define private properties/methods on the component may overwrite properties/methods on the instance, as in the following case:
methods: {
// Initialize the component's data method
_init() {
fetch().then(data= >{})}}Copy the code
The above code looks fine, but it actually runs because the _init method overrides the Vue. Prototype method of the same name. The first is _init
In the Vue2.0 style guide, it is recommended to use $_ to define private methods to ensure that they do not conflict with Vue itself. In the preceding example, to
methods: {
// Initialize the component's data method
$_init() {
fetch().then(data= >{})}}Copy the code
The component data must be a function and return an object
Before we talk about why a component’s data must return a function, let’s look at basic and reference types in JS.
- Basic types of
After the release of bigInt in ES2020, there are seven basic types in JS
- String character type
- Number Number type
- Boolean Indicates the Boolean type
- undefined
- null
- Symbol
- Bigint
The characteristics of basic types include
- Values of primitive types are stored in stack memory
- A comparison of primitive types is a comparison of their values
- Values of primitive types are immutable, and changes to values open up new space in stack memory
- New properties cannot be mounted on base types
let a = 2
let b = a
// Change the value of a to create a new space in stack memory, so it does not affect the value of b
a = 3
// Output 3, 2
console.log(a,b)
// New attributes cannot be mounted to base types
a.testProp = 'Mounted Properties'
/ / output is undefined
console.log(a.testProp)
Copy the code
- Reference types In JS, all but eight basic types are reference types, such as
Object
.Array
.Function
.RegExp
.Date
, etc.
The characteristics of reference types include
- The value of the reference type is stored in heap memory, while the reference is stored in stack memory
- Values of reference types are accessed by reference
- The value of the reference type is mutable (directly modified in heap memory)
- New properties can be mounted on reference types
let obj1 = {a: 1.b: 2}
let obj2 = obj1
Obj1 and obj2 refer to the same heap space, so the value of obj1 is stored in the heap
// Modify, which directly affects the value of obj2
obj1.a = 3
3 / / output
console.log(obj2.a)
// Mount new properties
obj1.testProp = 'New property value mounted'
// Print "new property value mounted"
console.log(obj1.testProp)
Copy the code
From the above comparison, I think it is clear why vUE data must return a function.
Suppose we now develop a component whose data is a common object. When we instantiate multiple components, all instances will share references to the same data object, and any changes made to the data by one instance will affect the other instances. By defining the data on a component as a function, object references are avoided when multiple components are instantiated and each instance returns a new copy of the original data by calling the data function.
Set the scope for the component style
Today, the front-end development is changing with each passing day, everything is in the rapid development of the front-end project scale is getting bigger and bigger, and CSS as a global scope only language, style conflict will bring a lot of trouble. JS language modules have been standardized, CSS is still exploring, and this is also an urgent problem to solve. A number of solutions have been proposed to add scope to CSS, such as BEM style specifications, such as CSS Modules.
In Vue, CSS is scoped by adding scoped attributes to elements
<template>
<button class="button">button</button>
</template>
<! Add the scoped attribute to the style tag.
<style scoped>
.button {
width: 50px;
height: 40px;
}
</style>
Copy the code
The result after compilation is as follows
<! Data-v-039c5b43 = data-v-039C5B43 = data-v-039C5B43 = data-v-039C5B43 = data-v-039C5B43 = data-v-039C5B43 = data-v-039C5B43 = data-v-039C5B43
<button data-v-039c5b43="" class="button">button</button>
Copy the code
/* Limit the scope of the style by adding a property selector for the style */
.button[data-v-039c5b43] {
width: 50px;
height: 40px;
}
Copy the code
Although we recommend adding scope for component styles, it is not necessary to use what VUE providesattribute scoped
For component libraries such as may need to override styles externally if usedattribute scoped
Because the attribute name is uncertain and the style weight is high, style overwriting is difficult.
It is recommended to use a naming convention like BEM for constraints, which makes it easier to override internal styles, uses a class name that people can understand without too high a selector priority, and is less likely to cause conflicts. For example, Both Element UI and Vant use BEM
Split complex pages into multiple component files
Have you ever seen a Vue file with a bunch of template code loaded with v-if, V-for, V-show instructions? I don’t know how you feel about that. It’s hell, all logic coupled together. For a complex page, we recommend breaking the page down into modules/functions and writing it into small, single components that can be referenced in the main entry file. For example, for a complex page, we can break it down
header.vue
main.vue
footer.vue
Three files, then complete the logic within the three files, and finally assemble the page by introducing all three components into the main entry file. The benefits of this include
- The complex logic is decoupled, the code structure is clearer, the logic is simpler, and the readability is stronger
- Componentized abstraction of functions makes component reuse easier
- It is easy for multiple people to collaborate, and different people can develop a complex page at the same time
Prop should be as detailed as possible
Compare the following two pieces of code
/ / the first paragraph
export default {
props: ['status'.'data']}/ / the second paragraph
export default {
props: {status: {
type: Boolean.default: true
},
data: {type: Array.required: true}}}Copy the code
By comparing the above two pieces of code, we can clearly know what attributes are required by the component, what the type of attributes is, what the default value is, and whether it is required. The benefits of this include:
- Properties are defined in detail, so it is easy to understand the use of components;
- In a development environment, Vue will be alerted if an ill-formed prop is supplied to a component, allowing potential problems to be discovered more quickly.
Component names should consist of multiple words
I thought about the need for component names to consist of more than one word, and I saw a piece of code once
<header class="header">
<! - section - >
<ul>
<li>Home page</li>
<li>about</li>
</ul>
</header>
Copy the code
I look at this code and I feel fine, I feel fine, and I look at the interface and I’m like, hey, why is there a logo on the left side of the header? I smiled and said, this must be the style inside the added, and then looked at the style, WTF, what ghost, style inside did not add ah, this is how to do, good magic. Then I saw a piece of code that looked like this
import Header from '@/components/header'
export default {
components: {
Header
}
}
Copy the code
How about my forty meter long machete !!!!!!
Why component names should be multiple words to avoid conflicts with existing and future HTML elements. What’s more, you won’t get hit doing it, but you can do it, too. Good luck.
This paper mainly refers to:
Cn.vuejs.org/v2/style-gu…
Juejin. Cn/post / 684490…
Thank the author, such as infringement immediately removed. If you find this article helpful to you, I hope you can give a thumbs-up to xiaobian, thank you very much. Small hands praise, love affair, hahaha hahaha