“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”
Writing in the front
More and more people are learning Vue, including some back end students. Since its release, Vue has successfully established itself in the front end. Vue is small and clean compared to the clunky Angular framework, and it’s easier to get started than React. The official definition is a set of progressive frameworks for building user interfaces.
My understanding of a progressive framework is very simple: use the features you want or can use, and don’t use the parts you don’t want. Vue doesn’t force you to accept and use all of its features at once.
It can be seen that Vue is indeed a framework that is easy to learn, but there are some advanced functions in Vue. The author summarizes some advanced features of Vue, aiming to help learners master these advanced skills of Vue and help readers stand out in interviews or jobs.
Vue advanced features:
-
The advanced features presented here are based on Vue2, and updates to Vue3 will be introduced in a later article
-
(1) Customize v-Model (2) $nextTick (3) slot
-
(4) Dynamic and asynchronous components (5) keep-alive (6) mixins
1. Customize the V-Model
That is, use the V-model command on the component. Usage scenarios: Use a color selector component, or encapsulate the Input of your own company’s project, requiring some project-specific number or text. Now you can’t use the simplest Input, you have to encapsulate a CustomInput yourself.
CustomVmodel component code:
<template>
<div>
<input type="text":value="text1"
@input="$emit('change1',$event.target.value)">
<! -- 1. The input above uses value instead of v-model 2. 3. Text1 attribute = text1 -->
</div>
</template>
<script>
export default {
model: {prop:'text1'.// This corresponds to the props attribute
event:'change1'
},
props: {text1:String.default(){
return ' '}}}</script>
Copy the code
Next, use this component:
<template>
<div>
<p>Advanced features</p>
<p>{{name}}</p>
<! -- custom v-model-->
<CunstomVmodel v-model="name"/>
</div>
</template>
<script>
import CunstomVmodel from './ComponentVmodel.vue'// Import components
export default {
components:{
CunstomVmodel// Register the component
},
data(){
return{
name:'Orange's front end amusement park'}}}</script>
<style>
body{
background-color: rgb(176.138.226);
}
p:nth-child(2) {color: lightgreen;
}
</style>
Copy the code
Code demo:
Bernays! So we have successfully used the V-Model directive on our custom component 😄.
2. $nextTick
First of all, let’s be clear that Vue is rendered asynchronously, as is React. Asynchronous rendering means that the DOM will not render immediately after the data changes. If we want to get the “correct DOM node” immediately after the data changes, we need to call $nextTick, which will be triggered after the DOM is rendered to get the latest DOM node.
With the following Demo you will have a clearer idea of $nextTick
NextTick Component code:
<template>
<div>
<ul ref="ul1">
<li v-for="(item,index) in fruits" :key="index">{{item}}</li>
</ul>
<button @click="addItem">add</button>
</div>
</template>
<script>
export default {
data(){
return{
fruits: ['orange'.'pomelo'.'pineapple']}},methods: {addItem(){
this.fruits.push(`The ${Date.now()}`)
this.fruits.push(`The ${Date.now()}`)
this.fruits.push(`The ${Date.now()}`)
const ulElem = this.$refs.ul1
console.log(ulElem.childNodes.length); }}}</script>
Copy the code
To explain this code: Click the Add button to get the ul node and print the length of the child nodes of ul (that is, the number of Li)
We found that after the first addition of data, the length of the print node should be 6, but the console printed the result as 3. This is why Vue rendered asynchronously, and DOM does not render immediately after the data was changed. If we want to get the “correct DOM” immediately after the data changes, we need to call $nextTick
<template>
<div>
<ul ref="ul1">
<li v-for="(item,index) in fruits" :key="index">{{item}}</li>
</ul>
<button @click="addItem">add</button>
</div>
</template>
<script>
export default {
data(){
return{
fruits: ['orange'.'pomelo'.'pineapple']}},methods: {addItem(){
this.fruits.push(`The ${Date.now()}`)
this.fruits.push(`The ${Date.now()}`)
this.fruits.push(`The ${Date.now()}`)
// 1. Render asynchronously, $nextTick will call back when the DOM is rendered
// 2. Data changes will be integrated during page rendering. Multiple data changes will only be rendered once
this.$nextTick(() = >{
const ulElem = this.$refs.ul1
console.log(ulElem.childNodes.length); })}}}</script>
Copy the code
Code demo:
Bernays! With $nextTick, we implemented the function of obtaining the DOM node immediately after changing the data 😋.
3. slot
There are many slot knowledge points, including basic usage (basic knowledge points), scope slots and named slots.
The basic use
Child component code:
<template>
<div>
<a :href="url">
<slot>Here's the default</slot>
</a>
</div>
</template>
<script>
export default {
props: ['url'].data(){
return{}}}</script>
Copy the code
{{webiste.title}} () {{webiste.title}} () {{webiste.title}} () {{webiste.title}} ();
Root component code:
<template>
<div>
<p>Advanced features</p>
<p>{{name}}</p>
<SlotDemo :url="webiste.url">
{{website.title}}
</SlotDemo>
</div>
</template>
<script>
import SlotDemo from './Slot.vue'
export default {
components:{
SlotDemo
},
data(){
return{
name:'Orange's front end amusement park'.website: {url:'www.baidu.com'.title:'Google it'}}}}</script>
<style>
body{
background-color: rgb(176.138.226);
}
p:nth-child(2) {color: lightgreen;
}
</style>
Copy the code
Look! We have successfully inserted the data 🙃 into the slot.
Scope slot
The primary purpose of scope slots is for children to throw values from data for the parent to get. The scope slots are a little confusing, so let’s go straight to the code.
ScopedSlot subcomponent code:
<template>
<div>
<a href="url">
<slot :slotData='website'>// The slotData is arbitrary and can be received by the parent component</slot>
</a>
</div>
</template>
<script>
export default {
props: ['url'].data(){
return{
website: {url:'https://www.jd.com/'.title:'JD Shopping'}}}}</script>
Copy the code
Root component code:
<template>
<div>
<p>Advanced features</p>
<p>{{name}}</p>
<ScopedSlot :url="website.url">
<! -- Here the template is mandatory, and slotprops is arbitrary -->
<template v-slot="slotprops">
{{slotprops.slotData.title}}
</template>
</ScopedSlot>
</div>
</template>
<script>
import ScopedSlot from './ScopedSlot.vue'
export default {
components:{
ScopedSlot
},
data(){
return{
name:'Orange's front end amusement park'.website: {url:'www.baidu.com'.title:'Google it'}}}}</script>
<style>
body{
background-color: rgb(176.138.226);
}
p:nth-child(2) {color: lightgreen;
}
</style>
Copy the code
Code demo:
Look! We get the data of the child component in the heel component and insert it into the slot of the child component. That’s what scope slots are for 😝!
A named slot
There are multiple Solts that give each slot a name, so let’s look at the code.
NamedSlot Component code:
<template>
<div>
<h1><slot name='slot1'></slot></h1>
<h2><slot></slot></h2>
<h3><slot name='slot2'></slot></h3>
</div>
</template>
<script>
export default{}</script>
Copy the code
Root component code:
<template>
<div>
<p>Advanced features</p>
<p>{{name}}</p>
<NamedSlot>
<template v-slot:slot1>I'm H1 and I'm going to insert into SloT1</template>
<template v-slot:slot2>I'm h2 and I'm going to plug in slot2</template>
<p>I am P and will be inserted into an unnamed slot</p>
</NamedSlot>
</div>
</template>
<script>
import NamedSlot from './NamedSlot.vue'
export default {
components:{
NamedSlot
},
data(){
return{}}}</script>
<style>
body{
background-color: rgb(176.138.226);
}
p:nth-child(2) {color: lightgreen;
}
</style>
Copy the code
Code demo:
See, we insert the data into the slot we want to insert, that’s what named slot is for 😊.
4. Dynamic and asynchronous components
:is = “component-name”; Scenarios that need to be rendered dynamically based on data, i.e. the component type is uncertain
Dynamic components
For example, if you want to develop a news detail page, you only know the data, not the order in which the components are rendered
Let’s implement this function now:
Root component code:
<template>
<div>
<div v-for="(val,key) in comname" :key='key'>
<component :is="val.type"></component>
</div>
</div>
</template>
<script>
import MyText from './Text.vue'
import MyImage from './Image.vue'
export default {
components:{
MyText,
MyImage
},
data(){
return{
comname: {1: {type:'MyText'
},
2: {type:'MyText'
},
3: {type:'MyImage'},}}}}</script>
Copy the code
Child component code:
<template>
<div>
<p>I'm the Text component</p>
</div>
</template>
<script>
export default {
data(){
return{}}}</script>
Copy the code
<template>
<div>
<p>I'm the Image component</p>
</div>
</template>
<script>
export default{}</script>
Copy the code
Code demo:
Asynchronous components
Asynchronous components exist to be loaded on demand. Large components, such as Echart ICONS or code editors, can have a significant impact on performance when loaded in the first place. Components are imported when they are registered using the import() function
Root component code:
<template>
<div>
<p>Advanced features</p>
<p>{{name}}</p>
<AsyncComp v-if="isShow"/>
<button @click="showComp">show AsyncComp</button>
</div>
</template>
<script>
export default {
components: {AsyncComp:() = >import('./AsynComponent.vue')},data(){
return{
name:'Orange's front end amusement park'.website: {url:'www.baidu.com'.title:'Google it'
},
isShow:false}},methods: {showComp(){
this.isShow=!this.isShow
}
}
}
</script>
<style>
body{
background-color: rgb(176.138.226);
}
p:nth-child(2) {color: lightgreen;
}
</style>
Copy the code
AsynComponent code
<template>
<div>
<p>Input box:</p>
<input type="text" v-model.trim="name">
<! -- <input type="text" v-model.lazy="name"> <input type="text" v-model.number="age"> -->
<p>Multiline text</p>
<textarea cols="30" rows="10" v-model="text"></textarea>
<p>Check box</p>
<input id="Orange" type="checkbox" v-model="checked1">
<label for="Orange">The oranges</label>
<input id="Grapefruit" type="checkbox" v-model="checked2">
<label for="Grapefruit">grapefruit</label>
<input id="Pineapple" type="checkbox" v-model="checked3">
<label for="Pineapple">pineapple</label>
<p>Radio buttons</p>
<input type="radio" id="male" value="male" v-model="gender">
<label for="male">male</label>
<input type="radio" id="female" value="female" v-model="gender">
<label for="female">female</label>
<p>Drop-down list selection (radio selection)</p>
<select name="" id="" v-model="selected">
<option disabled value="">Please select a</option>
<option value="">A</option>
<option value="">B</option>
<option value="">C</option>
<option value="">D</option>
</select>
<p>Drop-down list selection (multiple selection)</p>
<select name="" id="" v-model="selectedList" multiple>
<option disabled value="">Please select a</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
</div>
</template>
<script>
export default {
data(){
return {
name:'orange'.age:18.text:'1314520'.checked1:true.checked2:false.checked3:true.6
gender:'male'.selected:' '.selectedList: []}}}</script>
Copy the code
Code demo:
We will find that the component will be introduced and rendered only when the button is clicked to display it, greatly improving performance. This is where the asynchronous component comes in — load 👍 on demand.
5. keep-alive
Cache component; Suitable for frequently switching scenes that do not require repeated rendering, such as Tab bar switching. Let’s see how it works through a code demonstration.
Root component code:
<template>
<div>
<p>Advanced features</p>
<p>{{name}}</p>
<KeepAlive/>
</div>
</template>
<script>
import KeepAlive from './KeepAlive.vue'
export default {
components:{
KeepAlive
},
data(){
return{
name:'Orange's front end amusement park',}}}</script>
<style>
body{
background-color: rgb(176.138.226);
}
p:nth-child(2) {color: lightgreen;
}
</style>
Copy the code
KeepAlive component code:
<template>
<div>
<button @click="changeState('A')">A</button>
<button @click="changeState('B')">B</button>
<button @click="changeState('C')">C</button>
<KeepAliveA v-if="state==='A'"/>
<KeepAliveB v-if="state==='B'"/>
<KeepAliveC v-if="state==='C'"/>
</div>
</template>
<script>
import KeepAliveA from './KeepAliveStateA.vue'
import KeepAliveB from './KeepAliveStateB.vue'
import KeepAliveC from './KeepAliveStateC.vue'
export default {
components:{
KeepAliveA,
KeepAliveB,
KeepAliveC
},
data(){
return{
state:'A'}},methods: {changeState(state){
this.state=state
}
}
}
</script>
Copy the code
KeepAliveA (B, C) code:
<template>
<div>This is A component.</div>
</template>
<script>
export default {
mounted() {
console.log('A is mounted')},destroyed(){
console.log('A is destroyed')}}</script>
Copy the code
Code demo:
We found that when we switched components, the components were destroyed, which was very performance consuming, and we needed to cache the components.
We have keepalive wrapping up all these components, so let’s see what happens
Look! We have successfully cached the components with the Keepalive tag, which improves performance. 😀!
6. Mixin
Multiple components have the same logic, pulled out; Mixins are not perfect solutions there are solutions, and in Vue3.0, the proposed Composition API addresses these issues. Let’s take a look at the code to see what a Mixin is
Mixin component code:
<template>
<div>
<p>My name is {{name}}</p>
<p>{{age}}</p>
<p @click="showPicture">This is my picture</p>
</div>
</template>
<script>
import myMixin from './Mixin'
export default {
mixins:[myMixin],// You can add multiple
data(){
return{
name:'orange'}},mounted(){
console.log('Name is Mounted'); }}</script>
Copy the code
Code demo:
We have 18 extra pages and a few unfamiliar pieces of code on the console. Where did this come from? The answer is mixn. We defined the mixin.js file
export default {
data() {
return {
age: 18,}},methods: {
showPicture() {
console.log("picture is here")}},mounted() {
console.log("Mixin is mounted")}},Copy the code
Mixins take this common logic out and introduce it through mixns, avoiding duplication of definitions.
Some problems with Mixn:
- The source of variables is not clear, which is not conducive to reading
- Multiple mixins can cause naming conflicts.
- Mixins may have a many-to-many relationship with components, resulting in high complexity.
The last
This article summarizes the advanced features of Vue, although you can not use in your work, but is the so-called skill is no burden, master these skills may be work, we make clear the application scenario of various features, believe that by learning accumulation, readers will be able to play the Vue ~ if this article helpful to you, Please click on the GitHub blog at github.com/skyblue309. I have other columns, welcome to read ~ Vue from give up to easy to play with the beauty of CSS JavaScript