current position:Home>Vue3.0 learning summary

Vue3.0 learning summary

2021-08-27 05:41:31 Beginner's self

One 、 Life cycle ( hook )

1. Life cycle functions during creation

Life cycle functions during creation :

  • beforeCreate: Instance just created in memory , here , Not initialized yet data and methods attribute .
  • created: The instance has been created in memory , here data and methods Created , Template compilation has not started yet , Reading in processing / When writing reaction data , Use created  This is a very useful method . for example , To carry out API Call and store the value , You can do this here . It's best to do this here , Not in mounted  Do this in , Because it happened in Vue During the synchronization initialization of , And we need to perform all the data reads / Write operation .
  • beforeMount: Now the template has been compiled , But it hasn't been attached to the page yet .
  • mounted: The compiled template has been , Mounted in the container specified by the page .

2. Life cycle functions during operation

Life cycle functions during operation :

  • beforeUpdate: Execute this function before status update , here data The status value in is up to date , But the data displayed on the interface is still old , Because re rendering has not started yet DOM node .
  • updated: This function is called after the instance is updated. , here data Status values in and data displayed on the interface , All of them have been updated , The interface has been re rendered .

3. Life cycle function during destruction

Life cycle function during destruction :

  • beforeUnmounted: Call before instance destruction . In this step , Instance is still fully available .
  • unmounted:Vue Call after instance destruction . After calling ,Vue Everything indicated by the instance is unbound , All event listeners will be removed , All child instances will also be destroyed .

Two 、 Instruction label

1.v-text

v-text: It is used to obtain data and render the data to the specified label in the form of text , Be similar to javascript in innerText.

<template>
  <div class="app">
    <span>{{message}}</span>
    <span v-text="message"></span>
  </div>
</template>
<script>
import { ref } from "vue";
export default {
  setup() {
    let message = ref("hello world");
    return { message };
  }
};
</script>
 Copy code 

Interpolation expression :

  • Can write js expression :{{Math.max(1,2,3)}}
  • You can also write directly :{{content}}

{{}}( Interpolation expression ) and v-text The difference in getting data is :

  • Use v-text The value will cover the original data in the label , Using the form of interpolation expression will not overwrite the original data of the label .
  • Use v-text It can avoid interpolation flicker in poor network environment .

2.v-html

<template>
  <div class="app">
    <span v-html='message'></span>
    <span v-text="message"></span>
  </div>
</template>
<script>
import { ref } from "vue";
export default {
  setup() {
    let message = ref("<a href='www.baidu.com'> use Baidu Search </a>");
    return { message };
  }
};
</script>
 Copy code 

v-html and v-text difference :

  • Common ground : Can be directly based on data Data name in , Render the data inside the label
  • Difference :
    • v-text: v-text Render the acquired data directly to the inside of the label in the form of text innerText
    • v-html: v-html The obtained data contains html After the label is parsed, it is rendered inside the corresponding label innerHtml

3. Event instruction —v-on

  • js Three elements of the event :
    • Event source : The event source is called the event source , It usually refers to html label
    • event : Take a specific action onclick single click dbclick double-click onkeyup ......
    • Monitor : Event handler function function(){}
  • vue event :v-on
    • Event instruction v-on:click=“handleClick” Abbreviation @click="handleClick"
<template>
  <div class="app">
    <!-- to button Button binds multiple events -->
    <button type="button" @click="click" v-on:mouseover="mouseOver" v-on:mouseout="mouseOut"> Am I </button>
  </div>
</template>
<script>
export default {
  setup() {
    const click = function () {
      alert("click");
    };
    const mouseOver = function () {
      alert("mouse over");
    };
    const mouseOut = function () {
      alert("mouse out");
    };
    return { click, mouseOver, mouseOut };
  }
};
</script>
 Copy code 

3.1 Stop the event from bubbling

<div @click="maopao">
    <button @click.stop="handleClick()"> adopt .stop Modifier to disable maopao Execution of events </button>
</div>
 Copy code 

3.2 Block default events

for example ,form When the form is submitted , Automatically refresh the page , The default event needs to be blocked , Execute only the corresponding method :

<template>
  <div class="app">
    <form @click.prevent='onSubmit'>
      <input type="submit" value=" Submit ">
    </form>
  </div>
</template>
<script>
export default {
  setup() {
    const onSubmit = function () {
      alert("click");
    };
    return { onSubmit };
  }
};
</script>
 Copy code 

3.3 Call it once

<input type="button" value=" Submit " @click.once="onSubmit"/>
 Copy code 

3.4 Key and mouse modifiers

// Key modifier  .enter key  .tab .delete esc up down left right
// Mouse modifier  left right middle
<template>
  <div class="app">
    <input @keydown="handleKeyDown" placeholder=" Click any keyboard to execute the event "/>
    <input @keydown.enter="enterDown" placeholder=" Click any keyboard + Enter execution event "/>
    <div @click.ctrl.exact="ctrlAndMouseDown">
       Hold down ctrl+ Click this with the mouse div To execute the event 
    </div>
  </div>
</template>
<script>
export default {
  setup() {
    const handleKeyDown = function () {
      alert("handleKeyDown");
    };
    const enterDown = function () {
      alert("enterDown");
    };
    const ctrlAndMouseDown = function () {
      alert("ctrlAndMouseDown");
    };
    return { handleKeyDown, enterDown, ctrlAndMouseDown };
  },
};
</script>
 Copy code 

3.5 Event parameter passing

Pay attention to two points :

  • Do not use parentheses ,event Is automatically passed in as an argument .
  • Use parentheses , Must be explicitly passed in event object , If you do not pass in, you may eventually find a global window.event.
<template>
  <div class="app">
    <button @click='handleBtnClick(2, $event)'> newly added </button>
     Counter :{{counter}}
  </div>
</template>
<script>
import { ref } from "vue";
export default {
  setup() {
    let counter = ref(0);
    const handleBtnClick = function(num, event){
      //event Native is available js event , Get some dom Property to operate on 
      console.log(event.target);
      counter.value += num;
    };
    return { handleBtnClick, counter };
  }
};
</script>
 Copy code 

4. Cyclic instruction ——v-for

<template>
  <div class="app">
    <h2>{{ msg }}</h2>
    <h1> Traversing objects </h1>
    <h2 v-for="(value, key, index) in user" :key="index">
      index: {{ index }} key:{{ key }} value:{{ value }}
    </h2>
    <h1> Traversal array </h1>
    <h2 v-for="(school, index) in schools" :key="index">
      index:{{ index }} schools:{{ school }}
    </h2>
    <h1> Traversal array contains objects </h1>
    <h2 v-for="(user, index) in users" :key="user.id">
      index: {{ index }} name:{{ user.name }} age:{{ user.age }} bir:{{
        user.bir
      }}
    </h2>
  </div>
</template>
<script>
import { reactive,ref } from "vue";
export default {
  setup() {
    let msg = ref("hello world");
    let user = reactive({ name: "zhangsan", age: 22, bir: "2009:12:22" });
    let schools = [" Beijing ", " Shanghai ", " Guangzhou "];
    let users = reactive([
      { id: "1", name: " Zhang San ", age: 23, bir: "2002-03-03" },
      { id: "2", name: " Li Si ", age: 34, bir: "2006-04-02" },
      { id: "3", name: " Wang Wu ", age: 12, bir: "2004-05-01" },
    ]);
    return { msg, user, schools, users };
  },
};
</script>
 Copy code 
  • 1. In the use of v-for You must pay attention to join in the :key To give vue Internally, the only way to reuse and sort key

5. v-show、v-if

  • v-show: Used to control whether a label element in a page is displayed , amount to :style="display:block/none".
  • v-if: Used to control whether page elements are displayed .
<template>
  <div class="app">
    <h1 v-if="isShow">{{msg}}--"v-if"</h1>
    <h1 v-show="isShow">{{msg}}---"v-show"</h1>
  </div>
</template>
<script>
import { ref } from "vue";
export default {
  setup() {
    let msg = ref("hello world");
    let isShow = ref(false);
    return { msg, isShow };
  },
};
</script>
 Copy code 

summary :

  • In the use of v-show It can be written directly boolean Value control element display , You can also control the display and hiding of tags through variables .
  • stay v-show Through boolean Expressions control the display and hiding of labels .
  • v-if、v-show : effect : Are used to control whether tags are displayed and hidden in the page Use : label :v-if="true|false",v-show="true|false"

difference :

  • v-show: The bottom layer controls whether page labels are displayed css Medium display Property to display and hide . Recommended :v-show When the amount of data is large and the control display state is switched frequently .
  • v-if : The bottom layer controls whether page labels are displayed directly dom Elements , Through to dom Elements are deleted and added to control the display and hiding of labels .

6. v-bind

v-bind: The property used to bind the label , Thus through vue Dynamic modification of label properties .

v-bind:value="inputValue" It can be abbreviated as :value="inputValue"
 Copy code 

6.1 binding html class

6.1.1 Object syntax

We can give v-bind:class An object , With dynamic switching class, Be careful :v-bind:class Instructions can be compared with normal class Characteristics coexist .

<template>
  <div class="app">
    <ul class='box' v-bind:class="{'textColor': isColor, 'textSize':isSize}">
      <li> Apple </li>
      <li> Banana </li>
    </ul>
  </div>
</template>
<script>
import { ref } from "vue";
export default {
  setup() {
    let isColor = ref(true);
    let isSize = ref(true);
    return { isColor, isSize };
  },
};
</script>
<style>
  .box {
    border: 1px dashed #f0f;
  }
  .textColor {
    color: #000;
    background-color: #eef;
  }
  .textSize {
    font-size: 30px;
    font-weight: bold;
  }
</style>
 Copy code 

You can also directly bind an object in the data :

<template>
  <div class="app">
    <ul class='box' v-bind:class="classObject">
      <li> Apple </li>
      <li> Banana </li>
    </ul>
  </div>
</template>
<script>
import { reactive } from "vue";
export default {
  setup() {
    let classObject = reactive({
      'textColor': true, 
      'textSize':false // No rendering 
    })
    return { classObject };
  },
};
</script>
 Copy code 

6.1.2 Array syntax

We can pass an array to v-bind:class, To apply a class list .

<template>
  <div class="app">
    <ul class='box' v-bind:class="[classA, classB]">
      <li> Apple </li>
      <li> Banana </li>
    </ul>
  </div>
</template>
<script>
import { ref } from "vue";
export default {
  setup() {
    const classA = ref('textColor');
    const classB = ref('textSize');
    return { classA, classB };
  },
};
</script>
<style>
  .box {
    border: 1px dashed #f0f;
  }
  .textColor {
    color: #000;
    background-color: #eef;
  }
  .textSize {
    font-size: 30px;
    font-weight: bold;
  }
</style>
 Copy code 

6.2 Binding inline styles

6.2.1 Object syntax

v-bind:style Object syntax of , Very much like CSS, It's actually a JavaScript object ,CSS Attribute names must use hump nomenclature .

<template>
  <div class="app">
    <ul class='box' v-bind:style="{color: activeColor, fontSize: size}">
      <li> Apple </li>
      <li> Banana </li>
    </ul>
  </div>
</template>
<script>
import { ref } from "vue";
export default {
  setup() {
    const activeColor = ref('#f00');
    const size = ref('30px');
    return { activeColor, size };
  },
};
</script>
 Copy code 

You can also bind directly to a style object , so much the better , Make the template clearer :

<template>
  <div class="app">
    <ul class='box' v-bind:style="styleObject">
      <li> Apple </li>
      <li> Banana </li>
    </ul>
  </div>
</template>
<script>
import { reactive } from "vue";
export default {
  setup() {
    const styleObject = reactive({color: '#f00', fontSize: '30px'});
    return { styleObject };
  },
};
</script>
 Copy code 

6.2.2 Array syntax

You can apply multiple styles to an element .

<template>
  <div class="app">
    <ul class='box' v-bind:style="[styleObjectA, styleObjectB]">
      <li> Apple </li>
      <li> Banana </li>
    </ul>
  </div>
</template>
<script>
import { reactive } from "vue";
export default {
  setup() {
    const styleObjectA = reactive({color: 'blue', fontSize: '36px'});
    const styleObjectB = reactive({textDecoration: 'underline'});
    return { styleObjectA, styleObjectB };
  },
};
</script>
 Copy code 

6.3 v-model

Data binding form . Generally used for form data binding Forms are often labeled :input、textarea、checkbox、radio、select

<template>
    <!-- A drop-down box -->
    <select v-model="selected">
      <option value="A Selected ">A</option>
      <option value="B Selected ">B</option>
      <option value="C Selected ">C</option>
    </select>
    <span>Selected: {{ selected }}</span>  
     <br>
    <!-- Radio button -->
    <input type="radio" id="small" value="small_value" v-model="picked">
    <label for="small">small</label>
    <br>
    <input type="radio" id="big" value="big_value" v-model="picked">
    <label for="big">big</label>
    <br>
    <span>Picked: {{ picked }}</span>
    <br>
    <!-- Check box -->
    <input type="checkbox" id="one" value="value_one" v-model.lazy="checkedNames">
    <label for="one"> Option one </label>
    <input type="checkbox" id="two" value="value_two" v-model.lazy="checkedNames">
    <label for="two"> Option 2 </label>
    <input type="checkbox" id="three" value="value_three" v-model.lazy="checkedNames">
    <label for="three"> Option 3 </label>
    <br>
    <span>Checked names: {{ checkedNames }}</span>
</template>
<script>
import { ref } from "vue";
export default {
  setup() {
    const selected = ref('');
    const picked = ref('');
    const checkedNames = ref([]);
    return {selected, picked, checkedNames}
  },
};
</script>
 Copy code 

v-model Can also be combined with .lazy、.trim and .number These modifiers are used together

  <!--  In every time  input  Synchronize the value of the input box with the data after the event is triggered , add to  lazy  Modifier ,
   So it can be used  change  Events are synchronized  -->
  <input v-model.lazy="msg" >
  <!-- Remove the space at the beginning and end of the string -->
  <input v-model.trim="msg">
  <!-- Convert data to value type -->
  <input v-model.number="age" type="number">
 Copy code 

7. Some other common instructions ——v-pre、v-once、v-block

7.1 v-pre

Skip the compilation of this element and its children . It can be used to show the original Mustache label . Skipping a large number of nodes without instructions will speed up compilation . in other words vue If this tag is encountered, it will not be compiled and rendered , Skip this label , Direct display of raw data .

<!-- v-pre -->
<span v-pre>{{ this will not be compiled }}</span>
<!--  Page direct display  -->
{{ this will not be compiled }}
 Copy code 

7.2 v-once

Render elements and components only once , Elements using this Directive / Component and all its child nodes , Will be treated as static content and skipped , This can be used to optimize performance . When modifying input Box , Used v-once The directive p The element does not change , And the second one. p Element can be changed accordingly .

<template>
  <p v-once>v-once:{{msg}}</p>
  <p>not v-once:{{msg}}</p>
  <input type="text" v-model="msg" />
</template>
<script>
import { ref } from "vue";
export default {
  setup() {
    const msg = ref('13');
    return {msg}
  },
};
</script>
 Copy code 

3、 ... and 、Composition API

vue2 Every time I put the whole vue Import , for example vue2 Of main.js Code in file :

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
render: h => h(App)
}).$mount('#app')
 Copy code 

Obviously, it can't be used in the project Vue be-all API, So many modules are actually useless , stay Vue3 in , It exposed a lot of API For developers , We can meet our needs , What will be needed API from Vue Import . for example main.js The code in :

import { createApp } from 'vue';
import App from './App.vue'

createApp(App).mount('#app')
 Copy code 

Take advantage of import and export Import and export syntax of , The function of on-demand packaging module is realized , The file volume after the project package is obviously much smaller , This is also what we need to do in this paper Vue3 API The reasons for this in detail .

1. setup

setup The function is also Compsition API The entry function of , Our variables 、 Methods are defined in this function , Take a look at how to use it :

<template>
    <div id="app">
        <p>{{ number }}</p>
        <button @click="add"> increase </button>
    </div>
</template>

<script>
// 1.  from  vue  Introduction in  ref  function 
import {ref} from 'vue'
export default {
    name: 'App',
    setup() {
        // 2.  use  ref  Function to wrap a responsive variable  number
        let number = ref(0)
        // 3.  Set a method 
        function add() {
            // number Be being ref Function wrapped , Its value is stored in .value in 
            number.value ++
        }
        // 4.  take  number  and  add  Back out , for template Use in 
        return {number, add}
    }
}
</script>
 Copy code 

The above code uses ref function , I'll explain it in detail , Here you just need to understand that its role is to wrap a responsive data , And you can put ref Function wrapped variables are treated as Vue2 data The variables in the , In this way, a simple click button number plus 1 The function of .

stay Vue2 in , We visit data or props The variables in the , It's all through things like this.number In this way we can get , But pay special attention to , stay setup in ,this Pointing to undefined, That is to say, you can't go back to Vue2 The same goes through this To get variables .

So how to get to props The data in ?

Actually setup The function also has two parameters , Namely props 、context, The former stores the parameter names and corresponding values that define the current component to be passed from the outside world ; The latter is a context object , You can access attr 、emit 、slots. among emit That's what we're familiar with Vue2 The method of communicating with the parent component in , It can be called directly .

1.1 setup The function of the first 1 Parameters props

setup(props,context){}
 Copy code 

The first parameter props:

  • props It's an object , Contains all the data passed from the parent component to the child component .
  • Used in child components props Receive .
  • An object that contains all the properties declared by the configuration and passed in . in other words : If you want to pass props Output the value passed by the parent component to the child component . You need to use props Make a receive configuration . namely props:{......}, If you don't pass props Make a receive configuration , Then the output value is undefined.
<template>
  <div class="box" @click="sonHander">
     I'm the data in the subcomponent 
  </div>
</template>
<script>

export default {
    // Not received 
    // props:{
    //     mytitle:{
    //         type: Object
    //     }
    // },
    setup(props, context) {
       const sonHander =  function(){
           context.emit('sonclick', ' The child component is passed to the parent component ');
       }
      console.log(props.mytitle);
      return {sonHander}
    }
};
</script>
 Copy code 
<template>
  <div class="box" @click="sonHander">
     I'm the data in the subcomponent 
  </div>
</template>
<script>

export default {
    // Not received 
    // props:{
    //     mytitle:{
    //         type: Object
    //     }
    // },
    setup(props, context) {
       const sonHander =  function(){
           context.emit('sonclick', ' The child component is passed to the parent component ');
       }
      console.log(props.mytitle);// The output value is  undefined
      return {sonHander}
    }
};
</script>
 Copy code 
 Why pass props.mytitle The output value is undefined Well ?
 Because we didn't use it props Make a receive configuration . namely 
props:{
    mytitle:{
        type:Object
    }
}
 If we add a receive configuration , The data passed from the parent component will be received 
 Copy code 

1.2 Parameters context Explanation

The first 2 Parameters :context, It's an object .

  • There are attrs( Get all the attributes on the current tag ), But the attribute is props All objects received are not declared in .
  • If you use props To get the value , meanwhile props You declare the value you want to get in , be :attrs The value obtained is undefined.
  • Be careful :attrs You don't need to get a value props Claim receipt in . The first 1 Parameters props Getting a value requires props The statement received in .
  • There are emit Event distribution ,( This event is required to pass to the parent component ).
  • There are slots slot .
<template>
  <div class="box" @click="sonHander"> I'm the data in the subcomponent </div>
</template>
<script>
export default {
  // Not received 
  props: {
    mytitle: {
      type: Object,
    },
  },
  setup(props, context) {
    // Output title: The value passed by the parent component 
    console.log(props.mytitle);
    // Output other people's titles : Use context Get value , No need to use props To receive 
    console.log(context.attrs.othertitle);
    // Output undefined, because context No need to use props To receive 
    console.log(context.attrs.mytitle);
    const sonHander = function () {
      context.emit("sonclick", " The child component is passed to the parent component ");
    };
    return { sonHander };
  },
};
</script>
 Copy code 

1.3 The child component dispatches events to the parent component

<template>
  <div class="box" @click="sonHander"> I'm the data in the subcomponent </div>
</template>
<script>
export default {
  setup(props, context) {
    const sonHander = function () {
      context.emit("sonclick", " The child component is passed to the parent component ");
    };
    return { sonHander };
  },
};
</script>
 Copy code 

1.4 Optimize event distribution

We know the 2 Parameters context It's an object , And there are three properties in the object attrs,slots,emit, At the time of the distribution of the incident , Use it directly emit Just ok 了 .

<template>
  <div class="box" @click="sonHander"> I'm the data in the subcomponent </div>
</template>
<script>
export default {
  setup(props, { emit }) {
    // Use it directly emit To distribute the incident 
    const sonHander = function () {
      emit("sonclick", " The child component is passed to the parent component ");
    };
    return { sonHander };
  },
};
</script>
<style>
</style>
 Copy code 

1.5 Get the value passed by the parent component

We will use props Parameter gets the value , And the use of attrs Get value .

<template>
  <div class="box" @click="sonHander"> I'm the data in the subcomponent </div>
  <h2> Use props To declare acceptance :{{props.mytitle}}</h2>
  <h2> Using parameter attrs obtain :{{attrs.othertitle}}</h2>
</template>
<script>
export default {
  // Not received 
  props: {
    mytitle: {
      type: Object,
    },
  },
  setup(props, {emit, attrs}) {
    const sonHander = function () {
      emit("sonclick", " The child component is passed to the parent component ");
    };
    return { sonHander, attrs, props };
  },
};
</script>
 Copy code 

2. Life cycle

Vue2 There is beforeCreatecreatedbeforeMountmountedbeforeUpdate Wait for the life cycle function , And in the Vue3 in , Some of these life cycles have changed , And the way it's called has changed , Here's a change chart to take a look at .

Vue2 Vue3
beforeCreate setup
created setup
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated   onUpdated
beforeDestory onBeforeUnmount
destoryed onUnmounted

2.1 Combine API Create hook for

For the use of Combine API Of Vue3 Lifecycle hook , Use setup() Methods to replace beforecate and created. It means , Any code put in these methods is now only in setup In the method .

//  Combine AP
import { ref } from 'vue'

export default {
   setup() {    
     const val = ref('hello') 
     console.log('Value of val is: ' + val.value)       
     return {         
       val
     }
   }
}
 Copy code 

2.2 beforeMount() and onBeforeMount()

In components DOM Invoke before rendering . In this step , The root element does not exist yet . In the options API in , have access to this.$els To visit . In combination API in , To do this , Must be used on the root element ref.

//  Combine  API
<template>
   <div ref='root'>
     Hello World
   </div>
</template> 

import { ref, onBeforeMount } from 'vue'

export default {
   setup() {
      const root = ref(null) 
      onBeforeMount(() => {   
         console.log(root.value) 
      }) 
      return { 
         root
      }
    }
 }
 Copy code 

because app.$el Not yet created , So the output will be undefined.

2.3 mounted() and onMounted()

After the first rendering of the component , The element is now available , Allow direct DOM visit . Again , stay Options API in , We can use this.$el To visit our DOM, In combination API in , We need to use ref To visit Vue In the life cycle hook DOM.

import { ref, onMounted } from 'vue'
export default {
  setup() {    /*  Combine  API */
    const root = ref(null)
    onMounted(() => {
      console.log(root.value)
    })
     return {
       root
     }
   }
} 
 Copy code 

2.4 beforeUpdate() and onBeforeUpdate()

Call... When data is updated , It happens in the virtual DOM Before patching . This is a good place to access existing DOM, For example, remove the added event listener manually .

beforeUpdate For tracking the number of times a component has been edited , Even track creation “ undo ” The operation of the function is very useful .

2.5 updated() and onUpdated()

DOM After the update ,updated Is called .

<template>
    <div>
      <p>{{val}} | edited {{ count }} times</p>
      <button @click='val = Math.random(0, 100)'>Click to Change</button>
    </div>
 </template>
<script>
import { onBeforeUpdate,onUpdated, ref} from 'vue'
export default {
   setup () {
     const count = ref(0)
     const val = ref(0)
 
     onBeforeUpdate(() => {
       count.value++;
       console.log("beforeUpdate");
     })
 
     onUpdated(() => {
       console.log("updated() val: " + val.value)
     })
     return {
       count, val
     }
   }
};
</script>
 Copy code 

These methods are very useful , But for more scenarios , What we need to use watch Method to detect these data changes . watch  It's easy to use , Because it gives the old and new values of the changed data .

Another option is to use calculated attributes to change state based on the element .

2.6 beforeUnmount() and onBeforeUnmounted()

It is called before unloading the component instance . At this stage , The instance is still completely normal .

stay Combine API in , An example of deleting an event listener is as follows .

import { onMounted, onBeforeUnmount } from 'vue' 
export default {
   setup () { 
     const someMethod = () => {
       // do smth
     } 
     onMounted(() => {
       console.log('mount')
       window.addEventListener('resize', someMethod);
     })
 
     onBeforeUnmount(() => {
       console.log('unmount')
       window.removeEventListener('resize', someMethod);
     })
   }
}
 Copy code 

The actual operation is Vite,vue-cli Or any development environment that supports hot overloading , When updating the code , Some components will be uninstalled and installed by themselves .

2.7 unmounted() and onUnmounted()

After uninstalling component instance, call . When this hook is called , All instructions of the component instance are unbound , All event listeners are removed , All subcomponent instances are unloaded .

import { onUnmounted } from 'vue'
export default {
  setup () { /*  Combine  API */
    onUnmounted(() => {
      console.log('unmounted')
    })
  }
}
 Copy code 

2.8 activated() and onActivated()

By  keep-alive  Called when the cached component is activated .

for example , If we use keep-alive Component to manage different tab views , Every time you switch between tabs , The current tab will run this  activated  hook .

Suppose we use keep-alive The wrapper performs the following dynamic components .

<template>
   <div>
     <span @click='tabName = "Tab1"'>Tab 1 </span>
     <span @click='tabName = "Tab2"'>Tab 2</span>
     <keep-alive>
       <component :is='tabName' class='tab-area'/>
     </keep-alive>
   </div>
</template>
<script>
import Tab1 from './Tab1.vue'
import Tab2 from './Tab2.vue'
import { ref } from 'vue'
export default {
  components: {
    Tab1,
    Tab2
  },
  setup () { /*  Combine  API */
    const tabName = ref('Tab1')
    return {
      tabName
    }
  }
}
</script>
 Copy code 

stay Tab1.vue Inside the component , We can visit like this activated hook .

<template>
 <div>
 <h2>Tab 1</h2>
 <input type='text' placeholder='this content will persist!'/>
 </div>
</template>
<script>
import { onActivated } from 'vue'
export default {
 setup() {
    onActivated(() => {
       console.log('Tab 1 Activated')
    })
 }
} 
</script>
 Copy code 

2.9 deactivated() and onDeactivated()

By  keep-alive  Called when the cached component is deactivated .

This hook is useful in some use cases , For example, when a particular view loses focus, save user data and trigger animation .

import { onActivated, onDeactivated } from 'vue'

export default {
  setup() {
    onActivated(() => {
       console.log('Tab 1 Activated')
    })
    onDeactivated(() => {
       console.log('Tab 1 Deactivated')
    })
  }
}
 Copy code 

3. reactive

reactive Method is used to create a responsive data object .

It's easy to use , Just pass in the data as a parameter , The code is as follows

<template>
    <div id="app">
    <!-- 4.  Access to the  count -->
    {{ state.count }}
    </div>
</template>
<script>
    // 1.  from  vue  Import  reactive 
    import {reactive} from 'vue'
    export default {
        name: 'App',
        setup() {
            // 2.  Create responsive data objects 
            const state = reactive({count: 3})
            // 3.  Will respond to the data object state return  get out , for template Use 
            return {state}
        }
    }
</script>    
 Copy code 

4. ref

Introducing setup Function time , We used ref Function encapsulates a responsive data object , On the surface, it looks like reactive It looks as like as two peas , It's almost , because ref It is through reactive Packaged an object , Then you pass the value to the object value attribute , This explains why we need to add .value

We can simply put ref(obj) It's like this reactive({value: obj})

Here we write a piece of code to take a specific look at

<script>
import { ref, reactive } from "vue";
export default {
  setup() {
    const obj = { count: 3 };
    const state1 = ref(obj);
    const state2 = reactive(obj);
    console.log(state1.value);
    console.log(state2);
  },
};
</script>
 Copy code 

Be careful : I mean .value Is in setup Function ref You need to add the object after packaging , stay template Access in templates is not required , Because at compile time , It will automatically identify whether it is ref Packed So how do we choose ref and reactive Well ?

Suggest :

  • Base type value (String 、Nmuber 、Boolean etc. ) Or a single value object ( Similar image {count: 3} So an object with only one attribute value ) Use ref.
  • Reference type value (Object 、Array) Use reactive.

5. toRef

toRef It is to convert a value in an object into responsive data , It receives two parameters , The first parameter is zero obj object ; The second parameter is the name of the attribute in the object

The code is as follows :

<script>
// 1.  Import  toRef
import { toRef } from "vue";
export default {
  setup() {
    const obj = { count: 3 };
    // 2.  take  obj  Properties in object count The value of is converted to responsive data 
    const state = toRef(obj, "count");
    // 3.  take toRef The wrapped data object is returned to template Use 
    return { state };
  },
};
</script>
 Copy code 

But on the surface it looks like toRef This API It seems very useless , Because this feature can also be used ref Realization , The code is as follows

<script>
    // 1.  Import  ref
    import {ref} from 'vue'
    export default {
        setup() {
        const obj = {count: 3}
        // 2.  take  obj  Properties in object count The value of is converted to responsive data 
        const state = ref(obj.count)

        // 3.  take ref The wrapped data object is returned to template Use 
        return {state}
    }
}
</script>
 Copy code 

At first glance, it seems to be , In fact, there is a difference between the two , We can compare it with a case study , The code is as follows

<template>
  <p>{{ state1 }}</p>
  <button @click="add1"> increase </button>

  <p>{{ state2 }}</p>
  <button @click="add2"> increase </button>
</template>

<script>
import { ref, toRef } from "vue";
export default {
  setup() {
    const obj = { count: 3 };
    const state1 = ref(obj.count);
    const state2 = toRef(obj, "count");

    function add1() {
      state1.value++;
      console.log(" Original value :", obj);
      console.log(" Responsive data objects :", state1);
    }

    function add2() {
      state2.value++;
      console.log(" Original value :", obj);
      console.log(" Responsive data objects :", state2);
    }

    return { state1, state2, add1, add2 };
  },
};
</script>    
 Copy code 

We use... Separately ref and toRef take obj Medium count To be responsive , It also states two methods to make count Increase in value , Print the original value after each increment obj And packaged responsive data objects , Also look at the changes in the view . ref:

  • You can see , In response to the value of the data +1 After the operation , The view has changed , The original value has not changed , The values of responsive data objects have also changed , This explanation ref Is a copy of the original data , It doesn't affect the original value , At the same time, when the value of responsive data object changes, the view will be updated synchronously .

toRef:

  • You can see , In response to the value of the data +1 After the operation , The view has not changed , The original value has changed , The values of responsive data objects have also changed , This explanation toRef Is a reference to the original data , Will affect the original value , But will the view be updated when the value of the responsive data object changes .

summary :

  • ref It's a copy of the incoming data ;toRef It's a reference to the incoming data
  • ref Changes in the value of update the view ;toRef Changing the value of does not update the view

6. toRefs

To understand the toRef after , It's easy to understand toRefs 了 , Its function is to convert the values of all attributes in the incoming object into responsive data objects , This function supports one parameter , namely obj object .

Let's take a look at its basic use

<script>
// 1.  Import  toRefs
import { toRefs } from "vue";
export default {
  setup() {
    const obj = {
      name: " Front end impression ",
      age: 22,
      gender: 0,
    }; // 2.  take  obj  Object to responsive data 
    const state = toRefs(obj); // 3.  Print it and check it out 
    console.log(state);
  },
};
</script>
 Copy code 

The results are as follows :

It returns an object , Object contains every wrapped responsive data object .

7. toRaw

toRaw Method is used to obtain ref or reactive Object's original data .

Let's start with a piece of code

<template>
  <p>{{ state.name }}</p>
  <p>{{ state.age }}</p>
  <button @click="change"> change </button>
</template>

<script>
import { reactive } from "vue";
export default {
  setup() {
    const obj = {
      name: " Front end impression ",
      age: 22,
    };

    const state = reactive(obj);

    function change() {
      state.age = 90;
      console.log(obj); //  Print raw data obj
      console.log(state); //  Print  reactive object 
    }

    return { state, change };
  },
};
</script>
 Copy code 

We have changed reactive Data in object , So you see the raw data obj And quilt reactive The values of the wrapped objects have changed , From this we can see , The two are a reference relationship .

Now we think , If you change the original data directly obj Value , What will happen ? The answer is : reactive The value of will change as well , But the view doesn't update .

thus it can be seen , When we want to modify the data , But when you don't want the view to be updated , You can choose to modify the values directly on the original data , So we need to get the raw data first , We can use Vue3 Provided toRaw Method

toRaw Receive a parameter , namely ref Object or reactive object

<script>
import { reactive, toRaw } from "vue";
export default {
  setup() {
    const obj = {
      name: " Front end impression ",
      age: 22,
    };

    const state = reactive(obj);
    const raw = toRaw(state);

    console.log(obj === raw); // true
  },
};
</script>
 Copy code 

The above code proves that toRaw Methods from reactive Object is the raw data , Therefore, we can easily do some performance optimization by modifying the value of the original data without updating the view . Be careful : Add a sentence , When toRaw The parameter received by method is ref Object time , Need to add .value To get the original data object .

8. provide && inject

And Vue2 Medium provide and inject The same effect , But in Vue3 It needs to be manually removed from vue Import .

Here is a brief description of the functions of these two methods :

  • provide : Passing data to subcomponents and descendant components . Receive two parameters , The first parameter is key, The name of the data ; The second parameter is value, The value of the data
  • inject : Receive data from parent or ancestor components . Receive a parameter key, The name of the data passed by the parent or ancestor component

Suppose there are three components , Namely A.vue 、B.vue 、C.vue, among B.vue yes A.vue The child components ,C.vue yes B.vue The child components

// A.vue
<script>
import { provide } from "vue";
export default {
  setup() {
    const obj = {
      name: " Front end impression ",
      age: 22,
    }; //  Pass the name to the child component and its descendants info The data of 
    provide("info", obj);
  },
};
</script>

// B.vue
<script>
import { inject } from "vue";
export default {
  setup() {
    //  receive A.vue Data passed in 
    inject("info"); // {name: ' Front end impression ', age: 22}
  },
};
</script>

// C.vue
<script>
import { inject } from "vue";
export default {
  setup() {
    //  receive A.vue Data passed in 
    inject("info"); // {name: ' Front end impression ', age: 22}
  },
};
</script>
 Copy code 

9. watch && watchEffect

watch and watchEffect They are used to monitor a data change to perform a specified operation , But there are still differences in usage . watch:watch(source, cb, [options] )
Parameter description :

  • source: It can be an expression or a function , Dependency object used to specify listening
  • cb: The callback function executed after the dependent object changes
  • options: Optional parameters , The properties that can be configured are immediate( Immediately trigger the callback function )、deep( Deep monitoring )

When listening ref Type :

<script>
import { ref, watch } from "vue";
export default {
  setup() {
    const state = ref(0);

    watch(state, (newValue, oldValue) => {
      console.log(` The original value is ${oldValue}`);
      console.log(` The new value is ${newValue}`); /* 1 Print the result in seconds :
     The original value is 0
     The new value is 1
  */
    });

    // 1 Seconds later state value +1
    setTimeout(() => {
      state.value++;
    }, 1000);
  },
};
</script>
 Copy code 

When listening reactive Type :

<script>
import { reactive, watch } from "vue";
export default {
  setup() {
    const state = reactive({ count: 0 });
    watch(
      () => state.count,
      (newValue, oldValue) => {
        console.log(` The original value is ${oldValue}`);
        console.log(` The new value is ${newValue}`); /* 1 Print the result in seconds :
       The original value is 0
       The new value is 1
    */
      }
    ); // 1 Seconds later state.count Value +1
    setTimeout(() => {
      state.count++;
    }, 1000);
  },
};
</script>
 Copy code 

When listening to multiple values at the same time :

<script>
import { reactive, watch } from "vue";
export default {
  setup() {
    const state = reactive({ count: 0, name: "zs" });
    watch(
      [() => state.count, () => state.name],
      ([newCount, newName], [oldvCount, oldvName]) => {
        console.log(oldvCount); //  old  count  value 
        console.log(newCount); //  new  count  value 
        console.log(oldName); //  old  name  value 
        console.log(newvName); //  new  name  value 
      }
    );
    setTimeout(() => {
      state.count++;
      state.name = "ls";
    }, 1000);
  },
};
</script>
 Copy code 

because watch The first parameter of the method we have specified the object to listen to , So when the component is initialized , The callback function in the second parameter will not be executed , If we want to initialize it, we will execute it first , You can set... In the third parameter object immediate: true

watch By default, the method listens to the specified data gradually , For example, if the monitored data has multiple layers of nesting , Deep data changes do not trigger a listener callback , If we want it to monitor deep data as well , You can set... In the third parameter object deep: true

Add : watch Method returns a stop Method , If you want to stop listening , You can directly execute the stop function

Let's talk about it again watchEffect, It is associated with watch The main differences are as follows :

  • There is no need to pass in dependencies manually
  • The callback function is executed once every initialization to get the dependency automatically
  • Unable to get the original value , You can only get the changed value

Look at how this method works :

<script>
import { reactive, watchEffect } from "vue";
export default {
  setup() {
    const state = reactive({ count: 0, name: "zs" });
    watchEffect(() => {
      console.log(state.count);
      console.log(state.name); /*  Print on initialization :
    0
    zs
    1 Print in seconds :
    1
    ls
  */
    });
    setTimeout(() => {
      state.count++;
      state.name = "ls";
    }, 1000);
  },
};
</script>
 Copy code 

As you can see from the above code , We are not like watch The same method is used to pass in a dependency , Instead, it directly specifies a callback function .
When the component is initialized , Execute the callback function once , The data to be detected automatically is state.count and state.name. According to the above characteristics , We can choose which monitor to use .

10. computed

computed( Compute properties ) Pass in a getter function , The default cannot be changed manually ref object , Use and vue 2.0 Not much difference .

computed Default usage

<template>
  <div class="home">
    <p>
       Age :
      <button type="button" @click="changeAge(-1)">-</button>
      {{ age }}
      <button type="button" @click="changeAge(1)">+</button>
    </p>
    <p> Year of birth :{{ year }}</p>
  </div>
</template>

<script>
import { computed, ref } from "vue";
export default {
  name: "Home",
  setup() {
    const age = ref(19);
    function changeAge(value) {
      age.value += value;
    }
    const year = computed(() => {
      return 2020 - age.value;
    });

    return {
      year,
      age,
      changeAge,
    };
  },
};
</script>
 Copy code 

computed getter and setter

<template>
  <div class="home">
    <p>
       Age :
      <button type="button" @click="changeAge(-1)">-</button>
      {{ age }}
      <button type="button" @click="changeAge(1)">+</button>
    </p>
    <p>
       Year of birth :
      <button type="button" @click="changeYear(-1)">-</button>
      {{ year }}
      <button type="button" @click="changeYear(1)">+</button>
    </p>
  </div>
</template>

<script>
import { computed, ref } from "vue";
export default {
  name: "Home",
  components: {},
  setup() {
    const age = ref(19);
    function changeAge(value) {
      age.value += value;
    }
    const year = computed({
      get() {
        return 2020 - age.value;
      },
      set(val) {
        age.value = 2020 - val;
      },
    });

    function changeYear(value) {
      year.value = year.value + value;
    }

    return {
      year,
      age,
      changeYear,
      changeAge,
    };
  },
};
</script>
 Copy code 

Four 、 Components

1. Recognize components

In the previous case , We just created a component App; If we put all the logic in one component in an application , Then this component will become very bloated and difficult to maintain ; Therefore, the core idea of componentization should be to split components , Split into small components ; Then these components are combined and nested together , Finally form our application .

Let's analyze the nesting logic of the following code , Suppose we put all the code logic into one App.vue In the component : 

<template>
  <div id="app">
    <div class="header"><h2> Here is header, Ha ha ha </h2></div>
    <div class="main">
      <ul>
        <li> I am a Banner, Xi xi xi 1</li>
        <li> I am a Banner, Xi xi xi 2</li>
        <li> I am a Banner, Xi xi xi 3</li>
      </ul>
      <ul>
        <li> I am a ProductList, Xi xi xi 1</li>
        <li> I am a ProductList, Xi xi xi 2</li>
        <li> I am a ProductList, Xi xi xi 3</li>
      </ul>
    </div>
    <div class="footer"><h2> Here is footer, Hey, hey, hey </h2></div>
  </div>
</template>
 Copy code 

We will find that , Put all the code logic into one component , The code is very bloated and difficult to maintain .

And in real development , We will have more content and code logic , It is very poor for scalability and maintainability .

therefore , In real development , We will split the components , Small components divided into functions .

2. Component splitting

We can split it in the following way : image.png After splitting according to the above method , We only need to write corresponding components to develop corresponding logic . Each component does its own function , Of course, internal components can be split into multiple components .

3. Global components

Direct mount definition . Global components are reusable , They don't influence each other . Component definitions are available everywhere throughout the instance , But it will affect the performance .

    // Global components are reusable , They don't influence each other . Component defines everywhere available , But it will affect the performance 
    <div id="root">
    </div>
    <script src="https://unpkg.com/[email protected]"></script>
    <script>
        const app = Vue.createApp({
            template: `
            <div><counter-parent/></div>
            <div><counter/></div>
            <div><counter/></div>`
        });
        // Registering global components 
        app.component('counter', {
            data() {
                return {
                    count: 0
                }
            },
            template: `<button @click="count += 1">{{count}}</button>`
        });
        app.component('counter-parent', {
            template: `<counter/>`
        });
        app.mount("#root");
    </script>
 Copy code 

4. Local components

Local components commonly used in work , Different from the global component is the mapping object of the name . Be careful : Locally registered components are not available in their subcomponents .

    <div id="root">
    </div>
    <script src="https://unpkg.com/[email protected]"></script>
    <script>
        const Counter = {
            data() {
                return {
                    count: 0
                }
            },
            template: `<button @click="count += 1">{{count}}</button>`
        };
        const HelloWorld = {
            template: `<div>hello</div>`
        };
        const app = Vue.createApp({
            components: { 'counter': Counter, 'hello-world': HelloWorld },
            // mount   Local components , Up and down order is important . It can be abbreviated as Counter
            //components: {Counter, HelloWorld}
            template: `
                <div> <counter /></div>
                <div><hello-world /></div>`
        });
        app.mount("#root");
    </script>
 Copy code 

stay ES2015+ in , Put a similar in the object  ComponentA  The variable name of is actually  ComponentA: ComponentA  Abbreviation , That is, the variable name is also :

  • The name of the custom element used in the template
  • Contains the variable name of this component option

5. Component name

There are two ways to define component names :

5.1 Use kebab-case

Vue.component('my-component-name', { /* ... */ })
 Copy code 

When using kebab-case ( Short horizontal lines separate the names ) When defining a component , Must be used when referencing this custom element kebab-case.

5.2 Use PascalCase

Vue.component('MyComponentName', { /* ... */ })
 Copy code 

When using PascalCase ( Initial in capital ) When defining a component , When referring to this custom element, both nomenclature can be used . however , Directly in DOM ( Non engineering ) When used in, only kebab-case It works .

6. Component's data The option must be a function

  • Mainly to isolate the data , Create a new object without creating a new component , Instead of sharing an object .
  • The result of sharing an object is that the data inside each component will be modified by other components , Multiple components should point to the same memory heap control .

7. Communication between components

The nesting logic above is as follows , They have the following relationship :

  • App Components are Header、Main、Footer Parent component of component
  • Main Components are Banner、ProductList Parent component of component

In the development process , We often encounter needs Components communicate with each other

such as App Multiple may be used Header, Everywhere Header The content displayed is different , Then we need to pass it to the user Header Some of the data , Let it show ;

Another example is that we are in Main One time request in Banner Data and ProductList data , Then you need to pass it on to them for display ; It is also possible that an event has occurred in a subcomponent , Some operations need to be done by the parent component , That requires the child component to pass events to the parent component .

All in all , In a Vue In the project , Communication between components is a very important link , So let's take a look at how data is transferred between components .

Do not directly modify the status data of the parent component in the child component (). The first mock exam function should be in the same module. .

7.1 Pass parent component to child component

Communication between parent and child components is very common in development , For example, the parent component has some data , Subcomponents are required for presentation : At this time we can go through props To complete the communication between components

props Enables you to register some custom properties on the component ; The parent component assigns values to these properties , The sub component obtains the corresponding value through the name of the attribute .

props There are two common uses :

  • Mode one : Array of strings , The string in the array is the name of the property
  • Mode two : object type , Object type we can specify the attribute name at the same time , Specify the type it needs to pass 、 Is it necessary 、 Default value and so on

1)props Array usage of image.png 2)props Object usage of In array usage, we can only describe the name of the passed in attribute , It cannot be restricted in any form , Next, let's look at how the writing of objects makes us props Become more perfect .

When using object syntax , We can limit the incoming content more :

  • Specifies the type of property passed in
  • Specifies whether the passed in property is required
  • Specifies when there is no incoming , Default value of property
props: {
    // Specify the type , The default value is 
    title: { type: String, default: " The default value is title" }, // Specify the type 、 Whether it is necessary to transmit 
    message: { type: String, required: true },
}
 Copy code 

7.2 The child component is passed to the parent component

In what cases does a child component need to pass content to the parent component ? 

When some events occur in the subcomponent , For example, a click occurs in a component , Parent component needs to switch content ; When a child component has something to pass to the parent component .

How do we complete the above operation ?

  • 1) First , We need to be in The name of the event to be triggered in some cases is defined in the sub component ;
  • 2) secondly , stay In parent component v-on Pass in the event name to listen , And bound to the corresponding method ;
  • 3) Last , When an event occurs in a subcomponent , Trigger the corresponding event according to the event name ;

We encapsulate a component of the counter button , Internal monitoring of two button clicks , Click to pass emit Send events by .

<template>
  <div>
    <button @click="increment">+</button> <button @click="decrement">-</button>
    <h2></h2>
    <input type="text" v-model.number="num" /> <button @click="addN">+n</button>
  </div>
</template>

<script>
import {ref} from 'vue';
export default {
  name: "User",
  setup(props, {emit}) {
    let num = ref(0)
    function increment(){ 
      emit('add');
    }
    function decrement(){ 
      emit('sub')
    }
    function addN(){        
      console.log(num.value)        
      emit('addN',num.value)  
    }
    return {num, increment, decrement, addN}
  }
}
</script>
 Copy code 

When introducing the above components , Monitor events

<template>
  <div>
    {{ counter }}
    <counter-com @add="increment" @sub="decrement" @addN="addN"> </counter-com>
  </div>
</template>
<script>
import CounterCom from "./views/User.vue";
import {ref} from 'vue';
export default {
  components: { CounterCom },
  setup(){
    let counter = ref(0);
    function increment() {
      counter.value++;
    }
    function decrement() {
      counter.value--;
    }
    function addN(num) {
      counter.value += num;
    }
    return {
      counter,
      increment,
      decrement,
      addN
    }
  }
};
</script>
 Copy code 

When customizing events , We can also pass some parameters to the parent component :

emit('addN',num.value)
 Copy code 

7.3 Parent and child components access each other – Parent access child $refs

Main steps :

  • Bind a... To the subcomponent ref Information .
  • Pass event on parent component , In the callback function through refs Access to this ref Information .
    <div id="app">
        <!--   Bind a... To the subcomponent ref-->
        <subcom ref="info"></subcom>
        <button @click="getChildrenCom"> Get subcomponents </button>
    </div>
    <template id="sub">
        <h3> This is a subcomponent </h3>
        <button @click="clickSub"> Click the button of the sub component </button>
    </template>
    <script>
        //1、 Create a subcomponent 
        const sub = {
            data() {
                return {
                    msg: ' Information about subcomponents '
                }
            },
            methods: {
                printinfo() {
                    console.log(' Methods from subcomponents ')
                },
                clickSub() {
                    alert(' Click the button of the sub component ')
                }
            },
            template: '#sub'
        }
        // Here is the parent component 
        const app = Vue.createApp({
            data() {
                return {
                    msg: ' Default message '
                }
            },
            methods: {
                getChildrenCom() {
                    //this.$refs Get data from subcomponents 
                    console.log(this.$refs.info.msg)
                    this.$refs.info.printinfo()
                }
            },
            components: {
                'subcom': sub
            }

        })
        app.mount('#app')
    </script>
 Copy code 

7.4 Parent and child components access each other – The child component accesses the parent component $parent

It is generally not recommended that child components access parent components , It will destroy the reusability of the parent component .

    <div id="app">
        <sub-Box></sub-Box>
    </div>
    <!-- Label the template -->
    <template id="subbutton">
        <h3> This is the first one subbutton Child components </h3>
        <button @click="subtbclickTime"> Click the button {{count}} Time </button>
    </template>
    <!-- Label the template -->
    <template id="subBox">
        <p> This is a subBox Components </p>
        <subbuttoncom></subbuttoncom>
    </template>
    <script>
        //1、 Create a subcomponent 
        const subbutton = {
            data() {
                return {
                    count: 0
                }
            },
            methods: {
                subtbclickTime() {
                    this.count++
                    // The child component accesses the parent component 
                    // console.log(this.$parent.parentInfo)
                    // console.log(this.$parent.$parent)

                    // Sub component access root operator 
                    // console.log(this.$root)
                    console.log(this.$root.msg)
                }
            },
            template: '#subbutton'

        }

        //2、 Create another sub component 
        const subBox = {
            data() {
                return {
                    parentInfo: ' Default information for parent component '
                }
            },
            components: {
                'subbuttoncom': subbutton
            },
            template: '#subBox',
        }
        // Here is the root component 
        const app = Vue.createApp({
            data() {
                return {
                    msg: ' This is the default information for the root component '
                }
            },
            components: {
                'subBox': subBox
            }
        })
        app.mount('#app')
    </script>
 Copy code 

8. slot

8.1 What is a slot

A slot is a placeholder provided by a child component to a parent component , Express with , The parent component can fill in this placeholder with any template code , Such as html, Components etc. , The filled content replaces the sub component label .

Or so to speak :slot The appearance of is so that the parent component can openly add content to the child component .

8.2 The use of slots

8.2.1 Anonymous slot ( Single slot 、 Default slot )

Anonymous slot is not set name Property . It can be placed anywhere in the component . There can only be one anonymous slot in a component . As an alternate slot when a matching content fragment cannot be found . Anonymous slots can only be used as slot The slot for the element of the property .

<div class="child">
    <h1> Child components </h1>
    <slot name="head"> Header defaults </slot>
    <slot name="body"> Principal defaults </slot>
    <slot> This is an anonymous slot ( No, name attribute ), This string of characters is the default value for anonymous slots .</slot>
 </div>
 Copy code 
<div class="parent">
     <h1> Parent component </h1>
     <child>
         <p slot="body"> I am the subject </p>
         <p> I'm something else </p>
         <p slot="footer"> I'm the tail </p>
     </child>
 </div>
 Copy code 
 Parent component 
 Child components 
 Header defaults  (head The default value of is rendered : The default value is rendered only when no content is provided .)
 I am the subject  (body The default value of is overwritten )
 I'm something else  ( The default value of slot name is overwritten )
 Copy code 

Be careful :

<p slot="footer"> I'm the tail </p>
 Copy code 

Discarded , Because there is no in the subcomponent name="footer" The slot matches it . If the anonymous slot in the subcomponent does not exist , be <p> I'm something else </p> Will also be discarded .

8.2.2 A named slot

Slot with name , Name pass attribute name To define . There can be many named slots in a component , In different places .

<!-- <base-layout> Components -->
<div class="container">
    <header>
        <slot name="header"></slot>
    </header>
    <main>
        <slot></slot>
    </main>
    <footer>
        <slot name="footer"></slot>
    </footer>
</div>
 Copy code 

Can be in a  <template> Use on element v-slot Instructions , And v-slot Provides the slot name as a parameter of ,

<base-layout>
  <template v-slot:header>
    <h1> I'm the head header</h1>
  </template>

  <p> I am a main The content of 111</p>
  <p> I am also main The content of 222</p>

  <template v-slot:footer>
    <p> I am a footer</p>
  </template>
</base-layout>
 Copy code 

Be careful : Anything not wrapped in a belt with v-slot Of template The contents in are treated as the contents of the default slot . One without name Of slot The slot will have an implied name default . If you want to be more specific , Can be in a <template> The contents of the default slot in the package :

<base-layout>
  <template v-slot:header>
    <h1> I'm the head header</h1>
  </template>

  <template v-slot:default>
    <p> I am a main The content of 111</p>
    <p> I am also main The content of 222</p>
  </template>

  <template v-slot:footer>
      <p> I am a footer</p>
  </template>
</base-layout>
 Copy code 

Be careful v-slot Can only be added to  <template>  On .

8.2.3 Scope slot

<!-- <Child>  Components : -->
<template>
  <div>
    <h1>hey, I am a component Child The title of the </h1>
    <slot></slot>
  </div>
</template>
<script>
export default {
  data() {
     return{
        childUser:{Name:"Tom",Age:23}
    }
}
</script>
 Copy code 

When using Child When the component , Want to visit Child Data in childUser And show it in the slot :

<!--  This is the parent component <Father> Oh -->
<div>
  <h1>hey, I am the parent component Father The title of the </h1>
  <Child>
    {{childUser.Name}},
    {{childUser.Age}}
  </Child>
</div>
 Copy code 

However, the above code will not work , Because everything in the parent template is compiled in the parent scope ; All contents in the child template are in the child template Compiled in scope . Only <Child> Components can access childUser, And what we provide :

{{childUser.Name}}, {{childUser.Age}}
 Copy code 

It's at the parent <Father> Rendered . In order to make childUser Available in the slot contents of the parent , Need to put childUser from <Child> Child scope passed to <Father> Parent scope . The way to do this is to childUser As <slot> An attribute of the element :

<template>
  <div>
    <h1>hey, I am a component Child The title of the </h1>
    <slot v-bind:childData="childUser"></slot>
  </div>
</template>
<script>
export default {
  data() {
     return{
        childUser:{Name:"Tom",Age:23}
    }
}
</script>
 Copy code 

Binding in <slot> Element attribute childData It is called a slot prop. Now in the parent scope , We can use... With values v-slot To define slot prop Name :

<!--  This is the parent component -->
<div>
  <h1>hey, I am the parent component Father The title of the </h1>
  <Child>
    <template v-slot:default="slotProps">
      {{ slotProps.childData.Name}}
      {{ slotProps.childData.Age}}
    </template>
  </Child>
</div>
 Copy code 

In this case , We will include All slots prop The object of Name it slotProps, You can also customize it . Because in the above case , Only the default slot is provided , The label of the component can be used as a template for the slot . So we can v-slot Use directly on components :

<!--  This is the parent component -->
<div>
  <h1>hey, I am the parent component Father The title of the </h1>
  <Child v-slot:default="slotProps">
      {{ slotProps.childData.Name}}
      {{ slotProps.childData.Age}}
  </Child>
</div>
 Copy code 

However, the abbreviation syntax of the default slot cannot be mixed with the named slot , Because it causes ambiguities in scope :

<!--  Invalid , Will lead to a warning  -->
<Child  v-slot="slotProps">
  {{ slotProps.childData.Name }}
  <template v-slot:other="otherSlotProps">
    slotProps is NOT available here
  </template>
</Child >
 Copy code 

As long as there are multiple slots , Please always use the complete base for all slots <template> The grammar of :

<Child >
  <template v-slot:default="slotProps">
    {{ slotProps.childData.Name }}
  </template>

  <template v-slot:other="otherSlotProps">
    ...
  </template>
</Child>
 Copy code 

8.2.4 Deconstruct slot prop

The internal working principle of the scope slot is to include the contents of your slot in a function passing in a single parameter , therefore , It means v-slot The value of can actually be anything that can be used as an argument in a function definition JavaScript expression .

<Child  v-slot="{ childData}">
  {{ childData.Name }}
</Child>
 Copy code 

This makes the template simpler , Especially in this slot there are many prop When . It also turns on prop Rename and so on , For example childData Rename it to person:

<Child   v-slot="{ childData: person }">
  {{ person.Name }}
</Child  >
 Copy code 

You can even define default content , For slots prop yes undefined The circumstances of :

<Child   v-slot="{ childData= { Name: 'Guest' } }">
  {{ childData.Name }}
</Child >
 Copy code 

Follow v-on and v-bind equally ,v-slot There are also abbreviations , Namely the v-slot: Replace with characters #. for example v-slot:header Can be rewritten as #header, Like other instructions , This abbreviation is only available when it has parameters .

If you want to use abbreviations , You must always replace it with a clear slot name ,default Don't omit :

<Child  #default="{ childData}">
  {{ childData.Name }}
</Child >
 Copy code 

9. Dynamic components

  • When switching between components , Sometimes you want to keep the state of these components , To avoid performance problems caused by repeated re rendering .
  • Dynamic components are based on changes in data , combination component label , To dynamically switch the display code of components . In fact, it is to dynamically adjust the component name .

Using dynamic components :is=‘ Dynamic variables ’ To realize the dynamic rendering of components , In fact, let's component The name changes dynamically .

<body>
    <div id="app">
    </div>
    <script>
        // Here is the root component 
        const app = Vue.createApp({
            data() {
                return {
                    // The value of the switch variable here is the name of the component 
                    showItem: 'mybutton' // It can also be myinput
                }
            },
            methods: {
                changeHandler() {
                    if (this.showItem === 'mybutton') {
                        this.showItem = 'myinput'
                    } else {
                        this.showItem = 'mybutton'
                    }
                }
            },
            // Use here :is=" Data name " To complete the effect of dynamic display , For deactivated components keep-alive To cache previously entered data 
            template: `      
                <keep-alive>
                    <component :is="showItem"></component>
                </keep-alive>
                <button @click="changeHandler"> Switch </button>
                `
            })
            //1、 Create a subcomponent 
            app.component('mybutton', {
                template: `<button> Button global component </button>`
            })
            app.component('myinput', {
                template: `<input type="text" placeholder=" Please enter something "/>`
            })
            app.mount('#app')
    </script>
</body>
 Copy code 

10. Father son component props Dynamic binding parameter passing by value

<body>
    <div id="app">
        <subcom></subcom>
    </div>
    <script>
        // Create a subcomponent 
        const sub = {
            data() {
                return {
                    mytotal: this.total
                }
            },
            props: ['number1', 'number2', 'number3', 'number4'],
            template: `
                        <h3> I am a subcomponent </h3>
                        <div> data 1:{{number1}}</div>
                        <div> data 2:{{number2}}</div>
                        <div> data 3:{{number3}}</div>
                        <div> data 4:{{number4}}</div>
                      `
        }
        // Here is the root component 
        const app = Vue.createApp({
            data() {
                return {
                    numberObj: {
                        number1: 100,
                        number2: 200,
                        number3: 300,
                        number4: 400,
                    }
                }
            },
            components: {
                'subcom': sub
            },
            template: `
                <subcom v-bind="numberObj"></subcom>
            `
        })
        app.mount('#app')
    </script>
</body
 Copy code 

11.no-props The parent component passes the label property to the child component

non-prop attribute : When a parent component passes content to a child component , Subcomponent does not pass pros Reception time , The situation is as follows :

  • 1. When a child component has a single root node
    • The bottom layer will place the content passed by the parent component at the outermost layer of the child component dom On the label , Become the outermost layer of sub components dom An attribute of the tag
    • If you do not want to display this property on the label of the child component , Can pass inheritAttrs: false, Do not inherit from the parent component non-props attribute
  • 2. When there are multiple root nodes in a child component
    • If you want the parent component to pass non-props The order comes into force ,
    • Can pass v-bind Instructions ,v-bind='$attrs', All data passed from the parent component non-props Attribute to the specified div On ,
    • You can also specify specific properties , Such as :msg='$attrs.msg'
  • 3. No matter inheritAttrs by true perhaps false, All sub components can pass $attrs Property gets the property passed from the parent component , The default value is true.
<body>
    <div id="app">
    </div>
    <script>
        // Create a subcomponent 
        const sub = {
            props: ['info'],
            template: `
        <h3> I am a subcomponent --{{info}}</h3>
        <div :info="$attrs.info"> I am a subcomponent --{{info}}</div>
        <div :style="$attrs.style"> I am a subcomponent --{{info}}</div>
        <div v-bind="$attrs"> I am a subcomponent --{{info}}</div>
       `
        }
        // Here is the root component 
        const app = Vue.createApp({
            components: {
                'subcom': sub
            },
            // Pass parent component to child component 
            template: `
        <subcom info="test attrs" style="width: 200px; height: 100px; background-color: red"></subcom>
       `
        })
        app.mount('#app')
    </script>
</body>
 Copy code 

5、 ... and 、ES6 Promise usage

1.ES6 Promise Let's take a walk

Don't talk about complicated concepts first , Let's simply and roughly put Promise Use it. , Have an intuitive feeling . So the first question is ,Promise What is it ? Is a class ? object ? Array ? function ?   Don't guess , Just print it out ,console.dir(Promise), It's so simple and rude . image.png I can see at a glance ,Promise It's a constructor , I have all、reject、resolve These familiar methods , Prototype has then、catch And so on . So it works Promise new There must be then、catch Method , you 're right .   It would be new Let's play with one .

var p = new Promise(function(resolve, reject){
    // Do some asynchronous operations 
    setTimeout(function(){
        console.log(' Execution completed ');
        resolve(' Any data ');
    }, 2000);
});
 Copy code 

Promise Constructor of takes a parameter , Is the function , And two parameters are passed in :resolve,reject, It represents the callback function after the asynchronous operation succeeds and the callback function after the asynchronous operation fails . Actually, it's used here “ success ” and “ Failure ” It's not accurate to describe , According to the standard ,resolve Yes, it will Promise The status of is set to fullfiled,reject Yes, it will Promise The status of is set to rejected. But in the beginning, we can understand that , I'll go into the concept later .

In the code above , We performed an asynchronous operation , That is to say setTimeout,2 Seconds later , Output “ Execution completed ”, And call resolve Method . Run code , Will be in 2 Second output “ Execution completed ”. Be careful ! I'm just new An object , It's not called , The function we passed in has been executed , This is a detail that needs attention . So we use Promise It's usually wrapped in a function , Run this function when needed , Such as :

function runAsync(){
    var p = new Promise(function(resolve, reject){
        // Do some asynchronous operations 
        setTimeout(function(){
            console.log(' Execution completed ');
            resolve(' Any data ');
        }, 2000);
    });
    return p;            
}
runAsync()
 Copy code 

You should have two questions at this time :1. Packaging such a function has wool ?2.resolve(' Any data '); It's dry ? Let's continue . At the end of our wrapped function , Meeting return Out Promise object , in other words , To execute this function, we get a Promise object . Remember Promise There are then、catch Methods! ? That's what's powerful , Look at the code below

runAsync().then(function(data){
    console.log(data);
    // You can use the data to do other operations later 
    //......
});
 Copy code 

stay runAsync() Called directly on the return of then Method ,then Receive a parameter , Is the function , And we'll get it runAsync Call in resolve Parameters of time transmission . Run this code , Will be in 2 Second output “ Execution completed ”, Followed by output “ Any data ”. It's time for you to understand , original then The function in it has the same meaning as our normal callback function , In the runAsync This asynchronous task is executed after execution . This is it. Promise The role of the , simply , It can separate the original callback writing method , After the asynchronous operation is completed , Executing callback function by chain call . You may be dismissive , It's so awesome Promise That's it ? I'll encapsulate the callback function , to runAsync Isn't it the same when it's passed in , Just like this. :

function runAsync(callback){
    setTimeout(function(){
        console.log(' Execution completed ');
        callback(' Any data ');
    }, 2000);
}
 
runAsync(function(data){
    console.log(data);
});
 Copy code 

The effect is the same , It's still hard to use. Promise why . So here comes the question , What to do if there are multiple callbacks ? If callback It's also an asynchronous operation , And the corresponding callback function is required after the execution , What to do ? You can't define another one callback2, And then to callback Let's go in. . and Promise The advantage is that , Can be in then Method relay renewal Promise Object and return , Then continue to call then For callback operation .

2. Usage of chain operation

therefore , On the face of it ,Promise It's just a way to simplify layers of callbacks , In essence ,Promise The essence of it is “ state ”, Maintenance status 、 The way to pass the state enables the callback function to call in time , It is more than pass. callback Function should be simple 、 Flexible . So use Promise The right scenario for :

runAsync1()
.then(function(data){
    console.log(data);
    return runAsync2();
})
.then(function(data){
    console.log(data);
    return runAsync3();
})
.then(function(data){
    console.log(data);
});
 Copy code 

This allows you to order , Output the contents of each asynchronous callback every two seconds , stay runAsync2 Pass to resolve The data of , Can be in the next then Method . The operation results are as follows :

image.png Guess runAsync1、runAsync2、runAsync3 How these three functions are defined ? you 're right , That's what it looks like ( If the code is long, please expand by yourself ):

function runAsync1(){
    var p = new Promise(function(resolve, reject){
        // Do some asynchronous operations 
        setTimeout(function(){
            console.log(' Asynchronous task 1 Execution completed ');
            resolve(' Any data 1');
        }, 1000);
    });
    return p;            
}
function runAsync2(){
    var p = new Promise(function(resolve, reject){
        // Do some asynchronous operations 
        setTimeout(function(){
            console.log(' Asynchronous task 2 Execution completed ');
            resolve(' Any data 2');
        }, 2000);
    });
    return p;            
}
function runAsync3(){
    var p = new Promise(function(resolve, reject){
        // Do some asynchronous operations 
        setTimeout(function(){
            console.log(' Asynchronous task 3 Execution completed ');
            resolve(' Any data 3');
        }, 2000);
    });
    return p;            
}
 Copy code 

stay then In the method , You can also directly return Data, not Promise object , In the rear then Data can be received in , Let's change the above code to this :

runAsync1()
.then(function(data){
    console.log(data);
    return runAsync2();
})
.then(function(data){
    console.log(data);
    return ' Direct return data ';  // Data is directly returned here 
})
.then(function(data){
    console.log(data);
});
 Copy code 

So that's what the output is like :

image.png

3.reject Usage of

Come here , You should be right. “Promise What is it ” With a basic understanding . So let's take a look ES6 Of Promise What are the other functions . We ran out of it resolve, Not yet. reject Well , What does it do ? in fact , In our previous examples, only “ Successful implementation ” The callback , Not yet “ Failure ” The situation of ,reject The function of Promise The status of is set to rejected, So we are then You can capture it in , And then execute “ Failure ” Situation callback . Look at the code below .

function getNumber(){
    var p = new Promise(function(resolve, reject){
        // Do some asynchronous operations 
        setTimeout(function(){
            var num = Math.ceil(Math.random()*10); // Generate 1-10 The random number 
            if(num<=5){
                resolve(num);
            }
            else{
                reject(' The number is too big ');
            }
        }, 2000);
    });
    return p;            
}
 
getNumber()
.then(
    function(data){
        console.log('resolved');
        console.log(data);
    }, 
    function(reason){
        console.log('rejected');
        console.log(reason);
    }
);
 Copy code 

getNumber Function to get a number asynchronously ,2 Execution completed in seconds , If the number is less than or equal to 5, We think it's “ success ” 了 , call resolve modify Promise The state of . Otherwise, we think it is “ Failure ” 了 , call reject And pass a parameter , As a cause of failure . function getNumber And in then Two parameters passed in ,then Method can take two parameters , First correspondence resolve The callback , Second correspondence reject The callback . So we can get their data separately . Run this code multiple times , You will get the following two results at random :

image.png

4.catch Usage of

We know Promise In addition to objects then Method , One more catch Method , What is it for ? In fact, it and then The second parameter is the same , Used to specify reject The callback , The usage is this :

getNumber()
.then(function(data){
    console.log('resolved');
    console.log(data);
})
.catch(function(reason){
    console.log('rejected');
    console.log(reason);
});
 Copy code 

Effect and write in then In the second parameter of . But it has another function : In execution resolve The callback ( That's up there then First parameter in ) when , If an exception is thrown ( Code error ), So it doesn't report the wrong card js, It's going to be here catch In the method . Look at the code below :

image.png That is to say, entering catch It's in the method , And spread the cause of the mistake reason Parameters in . Even if there is an error code, it will not report an error , It's about our try/catch Statement has the same function .

5.all Usage of

Promise Of all Methods provide the ability to perform asynchronous operations in parallel , And the callback is executed after all asynchronous operations have been executed . We still use the definition above runAsync1、runAsync2、runAsync3 These three functions , See the following example :

Promise
.all([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
    console.log(results);
});
 Copy code 

use Promise.all To execute ,all Receive an array parameter , All the values in it are finally returned Promise object . such , Parallel execution of three asynchronous operations , Wait until they're all done then Inside . that , Where are the data returned by the three asynchronous operations ? All in then Inside? ,all The result of all asynchronous operations will be put into an array and passed to then, It's up there results. So the output of the above code is :

image.png With all, You can perform multiple asynchronous operations in parallel , And process all the return data in a callback , Isn't it cool ? There's a scenario that's great for this , Some game materials are more widely used , When opening a web page , Preload various resources needed, such as pictures 、flash And various static files . When all is loaded , Let's initialize the page again .

6、 ... and 、axios

1.axios brief introduction

be based on promise, For browsers and node.js Of http client

2. characteristic

  • Support for browsers and node.js
  • Support promise
  • Can intercept requests and responses
  • Ability to transform request and response data
  • Can cancel the request
  • Automatic conversion JSON data
  • Browser side support to prevent CSRF ( Cross-site request forgery )

3. install

utilize npm install npm install axios --save

4. Example

4.1 Send a GET request

// By giving ID To send a request 
axios.get('/user?ID=12345')
  .then(function(response){
    console.log(response);
  })
  .catch(function(err){
    console.log(err);
  });
// The above requests can also be sent in this way 
axios.get('/user',{
  params:{
    ID:12345
  }
})
.then(function(response){
  console.log(response);
})
.catch(function(err){
  console.log(err);
});
 Copy code 

4.2 Send a POST request

axios.post('/user',{
  firstName:'Fred',
  lastName:'Flintstone'
})
.then(function(res){
  console.log(res);
})
.catch(function(err){
  console.log(err);
});
 Copy code 

4.3 Concurrent multiple requests at one time

function getUserAccount(){
  return axios.get('/user/12345');
}
function getUserPermissions(){
  return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(),getUserPermissions()])
  .then(axios.spread(function(acct,perms){
    // This function is triggered when both requests are completed , The two parameters represent the returned result 
  }))
 Copy code 

5.axios Of API

5.1 axios Can be configured by (config) To send a request

5.1.1 axios(config)

// Send a `POST` request 
axios({
    method:"POST",
    url:'/user/12345',
    data:{
        firstName:"Fred",
        lastName:"Flintstone"
    }
});
 Copy code 
5.1.2 axios(url[,config])
// Send a `GET` request ( Default request mode )
axios('/user/12345');
 Copy code 

5.2 Alias for request mode , Here we provide a convenient alias for all the supported request methods

axios.request(config);
axios.get(url[,config]);
axios.delete(url[,config]);
axios.head(url[,config]);
axios.post(url[,data[,config]]);
axios.put(url[,data[,config]])
axios.patch(url[,data[,config]])
 Copy code 

Be careful : When we use the alias method ,url,method,data These parameters do not need to be declared in the configuration

5.3 Concurrent request (concurrency)

//iterable It is a parameter that can be iterated, such as an array 
axios.all(iterable)
//callback Wait until all requests have been completed to execute 
axios.spread(callback)
 Copy code 

5.4 Create a axios example , And you can customize its configuration

5.4.1 axios.create([config])
var instance = axios.create({
  baseURL:"https://some-domain.com/api/",
  timeout:1000,
  headers: {'X-Custom-Header':'foobar'}
});
 Copy code 
5.4.2 Example method

Here is an example method , Note that the defined configuration will be used with create The configuration merge of the created instance .

axios#request(config)
axios#get(url[,config])
axios#delete(url[,config])
axios#head(url[,config])
axios#post(url[,data[,config]])
axios#put(url[,data[,config]])
axios#patch(url[,data[,config]])
 Copy code 

6. The default value is

You can set the default configuration , Valid for all requests

6.1 Global default configuration

axios.defaults.baseURL = 'http://api.exmple.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['content-Type'] = 'appliction/x-www-form-urlencoded';
 Copy code 

6.2 Custom instance default settings

// When creating an instance, configure the default configuration 
var instance = axios.create({
    baseURL: 'https://api.example.com'
});

// When the instance is created, modify the configuration 
instance.defaults.headers.common["Authorization"] = AUTH_TOKEN;
 Copy code 

6.3 Priority in configuration

config The configuration will be merged by priority , The order is lib/defauts.js Default configuration in , Then the default configuration in the instance , And finally, in the request config Parameter configuration , The later the level is higher , The latter will cover the previous example .

// When you create an instance, you use libray Default configuration in directory 
// ad locum timeout The configured value is 0, From libray The default value of 
var instance = axios.create();
// overwrite library The default value of 
// Now all requests have to wait 2.5S And then it will send out 
instance.defaults.timeout = 2500;
// there timeout Back to cover the previous 2.5S become 5s
instance.get('/longRequest',{
  timeout: 5000
});
 Copy code 

7. Interceptor

7.1 Request and response interceptors

You can ask for 、 The response is arriving then/catch Stop them before

// Add a request interceptor 
axios.interceptors.request.use(function(config){
  // Do something before the request is sent 
  return config;
},function(err){
  //Do something with request error
  return Promise.reject(error);
});
// Add a response interceptor 
axios.interceptors.response.use(function(res){
  // Process the returned data here 
  return res;
},function(err){
  //Do something with response error
  return Promise.reject(error);
})
 Copy code 

7.2 For custom axios Instance add interceptor

var instance = axios.create();
instance.interceptors.request.use(function(){})
 Copy code 

copyright notice
author[Beginner's self],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210827053937255Y.html

Random recommended