The experience of switching from Vue2.0 to Vue3.0

The experience of switching from Vue2.0 to Vue3.0

1. Introduction to Vue3.0

1.1 Why learn vue 3

  1. Vue is currently one of the most popular front-end frameworks developed in China
  2. The official version of vue3.0 has been released for about seven months, and the community ecology has been gradually improved
  3. Some companies with aggressive technology selection have already used vue3 in the production environment

So, it's time~

Currently supports vue3 UI component library

  • ant-design-vue

    antdv.com/docs/vue/in...

    ant-design-vue is the Vue implementation of Ant Design, and the style of the component is kept in sync with Ant Design

    The 2.0.0 beta version that currently supports Vue 3.0 has been released

  • element-plus

    element-plus.gitee.io/#/zh-CN

    Element Plus, a set of Vue 3.0-based desktop component libraries for developers, designers and product managers

  • vant

    vant-contrib.gitee.io/vant/v3/#/z...

    Lightweight and reliable mobile Vue component library

    Vant is an open source mobile component library of Youzan front-end team. It was open sourced in 2016 and has been maintained for 4 years.

    At present, Vant has completed the adaptation of Vue 3.0 and released the Vant 3.0 version

  • VueUse

    vueuse.org/

    Based on the commonly used collection of composition combination api, the Little Rabbit Fairy project will be partially used

1.2 New changes brought by Vue3

  • Performance improvement

    • Faster first rendering
    • diff algorithm is faster
    • Less memory footprint
    • Packing volume becomes smaller
  • Better Typescript support

  • Composition API (emphasis)

    When using the vue2.x version to develop more complex components, the logic is difficult to reuse, and the emergence of combined api can solve such problems

Related Reading:

  1. Vue3 Chinese document

  2. Vue3 design concept

1.3 Destructive syntax updates

Vue3.0 is compatible with most of the syntax of version 2.0, but there are also some destructive syntax updates. Please pay special attention to this.

  1. Instance method $on removed (eventBus existing implementation mode is no longer supported and can be replaced by third-party plug-ins)
  2. Filter filter removed (filters can no longer be used in interpolation expressions, and methods can be used instead)
  3. .sync syntax removed (merged with v-model syntax)

More reading:

https://v3.cn.vuejs.org/guide/migration/introduction.html

2. Vue3 development environment setup

Next, we will learn some new syntax of vue3. 1. we will build a basic environment first, or use the familiar vue-cli to quickly generate an environment integrated with vue3

Objectives of this section:
Master how to use vue-cli to build a development environment based on vue3.0

(1) Choose a custom configuration (2) Choose a custom installation version (3) Choose the 3.x version and press Enter after the above steps, vue-cli will help us run a vue project with a built-in vue3 version

First we can take a look

package.json
File, displayed in the dependencies configuration item, the version we are currently using is 3.0.0 and then open
main.js
In the entry file, it is found that the instantiation of Vue has undergone some changes, from the previous instantiation of the new keyword to the call form of the createApp method (more details: www.bilibili.com/read/cv1013...

vue2.x

new Vue({ el : '#app' , render : h => h(App) }) Copy code

vue3.x

Import {createApp} from 'VUE' Import the App from './App.vue' createApp (the App) .mount ( '#app' ) copying the code

Finally, we opened a single-file component and found that the single-file component of vue3.0 is no longer mandatory to have a unique root element

< Template > < IMG Alt = "Vue logo" the src = "./assets/logo.png" > < the HelloWorld MSG = "Your Vue.js available for purchase to the App"/> </Template > copy the code

The above is all the things we need to pay attention to at the current stage, and then we can learn the new composition API of vue3 based on the current environment

3. Combined API

The composite api (Composition API) is an api update that is very valuable for our developers in vue3. We don t pay attention to the specific syntax first, and have a big perception of it.

3.1 composition vs options

Objectives of this section:
Have a general understanding of composite api (composition api)

The vue application developed by the options API is shown on the left. Its characteristic is easy to understand, because each option has a fixed writing position. For example, the responsive data is written to the data selection, and the operation method is written to the methods configuration item, etc. , After the application is big, I believe everyone will encounter the dilemma of coming back and forth to find code

The vue application developed by the composition API is shown on the right. Its characteristic is that everything related to a specific function is put together and maintained, such as the response data related to function A, the method of operating data, etc., so that no matter how big the application , you can quickly read all relevant code targeted to a function, easy to maintain, if set up complex function, large amount of code, we can logically split processing special attention:

  1. The two styles of optional api and combined api are coexisting, not one or the other

  2. Scenarios that require a large number of logical combinations can be enhanced using the compilation API

3.2 Case comparison

We briefly understand the brand new api form brought by vue3 through the diagram. In this section, we have a more in-depth experience of the development mode comparison between the two apis through a specific small case. We will ignore the grammatical details for the time being and just focus on Code writing form

Objectives of this section:
Realize the same requirement through two Api forms, understand
compition api
The benefits

3.2.1 Understanding requirements

Function: Control the display and hiding of text by clicking the button (1) vue2.x option Api version

< template > < div > < button @ click = "showText" > Show </button > < button @ click = "hideText" > Hide </button > < p v-if = "isShow" > Here are some texts used Show hidden </p > </div > </template > < script > export default { name : 'App' , data () { return { isShow : true } }, methods :{ showText () { this .isShow = true }, hideText () { this .isShow = false } } } </script > <style > </ style > Copy code

(2) vue3.0 composition api version

< template > < div > < button @ click = "showText" > Show </button > < button @ click = "hideText" > Hide </button > < p v-if = "isShow" > Here are some texts used Show hidden </p > </div > </template > < Script > The method of introducing desired//Import {REF} from 'VUE' export default { name : 'App' , setup () { //Define the data here const isShow = ref( true ) //Write the method here const showText = () => { isShow.value = true } //write method here const hideText = () => { isShow.value = false } //Everything used needs to be returned return { isShow,showText,hideText } } } </script > < style > </style > Copy code

Above, by defining the function function, we separate the function-related code into an independent small function, and then combine the small function functions in the setUp function. In this way, we can both turn the setup function into Refreshing and easy to maintain and quickly locate the functional position

nice~ So far we did not pay attention to the details of the api, but realized the benefits of the combined api. Next, we will go into the details of the api and see how the new api should be used.

3.3 Setup entry function

Objectives of this section:
Understand the role and timing of the setup function

  1. The setup function is a new component option that serves as the starting point (entry) of the combined API in the component
  2. From a life cycle perspective, setup will be executed before the beforeCreate hook function
  3. This cannot be used in setup, this points to undefined
export default { setup () { console .log( 'setup executed' ) console .log( this ) }, beforeCreate () { console .log( 'beforeCreate executed' ) console .log( this ) } } Copy code

3.4 Responsive system API

3.4.1 reactive function

Objectives of this section:
Understand the syntax of reactive functions

Role: reactive is a function that receives an ordinary object and transfers

Object data
Convert into a responsive object and return

Steps for usage

  1. Import from the vue framework
    reactive
    function
  2. Call the reactive function in the setup function and pass in the object data
  3. In the setup function, return the return value after the reactive function is called in the form of an object

At this time, click on age +1 and find that the data is responsive

Code landing

< template > < div > < p > Age is {{ user.age }} </p > < button @ click = "user.age++" > Age+1 </button > </div > </template > < Script > //1. introduced reactive function of the frame from vue Import {reactive} from 'vue' export default { setup () { //2. Call the function in setup and introduce the data object const user = reactive({ name : 'zs' , age : 18 }) //3. In the setup function, return the return value after the reactive function is called in the form of an object return { user } } } </script > < style > </style > Copy code

3.4.2 ref function

Objectives of this section:
Understand the syntax of ref function

Role: ref is a function that accepts a simple type or a complex type and returns a reactive and variable ref object

Steps for usage

  1. Export from the vue framework
    ref
    function
  2. Called in the setup function
    ref
    Function and pass in data (simple type or complex type)
  3. In the setup function, return the return value of the ref function in the form of an object
  4. Note: To use the ref result in the setup function, you need to pass
    .value
    Access, use in the template does not need to add .value

Landing code

< template > < div > < p > Age is {{ age }} </p > < button @ click = "addAge" > Age+1 </button > </div > </template > < Script > //1. ref function is introduced from the frame vue Import {ref} from 'vue' export default { setup () { //2. Call the function in setup and introduce the data object into const age = ref( 18 ) const addAge = () => { //The this point here is underfined, so this cannot be used. To access the data //To access the data here, you need to use .value age.value++ } //3. In the setup function, return the return value after the reactive function is called in the form of an object return { age,addAge } } } </script > copy code

Summary description:

  1. The ref function can receive a simple type value and return a changeable ref reactive object, thus making up for the problem that the reactive function does not support simple types
  2. Both reactive and ref functions can provide responsive data conversion. There is no best practice in the specific API community when you need to use which API. You can use your own proficient API to perform the conversion for the time being.
  3. Recommend a way of writing: we only use reactive if we clearly know the field name (key) inside the object to be converted, otherwise we will always use ref, thereby reducing the mental burden on syntax choices

3.4.3 toRefs function

Problem recurring

Objectives of this section:
Use the toRefs function to simplify the use of reactive objects

Scenario: The object returned after the reactive function is processed. If the object is deconstructed or expanded, the data will lose its responsive ability. In order to solve this problem, the toRefs function needs to be introduced. The toRefs function can be used to ensure that every attribute of the object is expanded. Is responsive

Click the +1 button and find that the view has not changed. This is what we said. If the return value of reactive is deconstructed, it will destroy the responsive feature of the call, and we need to use the toRefs method for processing.

< template > < div > < p > Age is {{ age }} </p > < button @ click = "age++" > Age+1 </button > </div > </template > < Script > //1. introduced reactive function of the frame from vue Import {reactive} from 'vue' export default { setup () { //2. Call the function in setup and introduce the data object const user = reactive({ name : 'zs' , age : 18 }) //3. In the setup function, return the return value after the reactive function is called in the form of an object return { ...user } } } </script > copy code

Approach

3.4.4 computed

Objectives of this section:
Master the use of calculated attribute functions in the setup function

Function: According to the existing responsive data, new data can be obtained after certain calculations

Steps for usage

  1. Import from the vue framework
    computed
    function
  2. Execute the computed function in the setup function, and pass in a function, and define the calculation formula in the function
  3. Put the execution result of the computed function call into the return value object of setup

Code landing

< template > {{ list }} {{ filterList }} < button @ click = "changeList" > change list </button > </template > < Script > //property calculation function incorporated 1. Import {computed, REF} from 'VUE' Export default { Setup ( ) { //This is an array for filtering const list = ref([ 1 , 2 , 3 , 4 , 5 ]) //2. Use computed const filterList = computed( () => { return list.value.filter( item => item> 3 ) }) //modify the function list of function changeList () { list.value.push( 6 , 7 , 8 ) } //3. Data must be returned to return { list, filterList, changeList } } } </script > copy code

3.4.5 watch listener

Objectives of this section:
Master the use of listeners in the setup function

Function: Execute callback logic based on the change of responsive data, which is exactly the same as the function of watch in vue2

  1. Normal monitor
  2. Execute immediately
  3. In-depth monitoring

Steps for usage

  1. Import from the vue framework
    watch
    function
  2. Execute the watch function in the setup function to turn on the monitoring of responsive data
  3. The watch function receives three general parameters
    1. The first parameter is a function, which returns the responsive data you want to monitor for changes
    2. The second parameter is the callback function to be executed after the response data changes
    3. The third parameter is an object, in which you can configure whether to enable immediate execution or in-depth monitoring

Code landing (1) Ordinary listening

< template > {{ age }} < button @ click = "age++" > change age </button > </template > < Script > //1. watch function introducing Import {REF, watch} from 'VUE' export default { setup () { //2. Initialize a monitoring data const age = ref( 18 ) /** * watch (callback function 1, callback function 2) * Callback function 1 is the target that needs to be listened, and the function returns and listens * Callback function 2 is called after the listening function is executed */ watch( () => { return age.value }, () => { console .log( 'Monitor function executed' ) } ) return { age } } } </script > copy code

(2) open at once and depth monitor the implementation of the code landing

Compared with ordinary monitoring, there is only one more parameter object in the watch function.

< template > {{ user.age }} < button @ click = "user.age++" > change age </button > </template > < Script > //1. watch function introducing Import {REF, watch} from 'VUE' export default { setup () { //2. Initialize a monitoring data const user = ref({ name : 'zs' , age : 20 }) /** * watch (callback function 1, callback function 2, object) * Callback function 1 is the target that needs to be listened, and the function returns and listens * Callback function 2 is called after the listening function is executed * Object deep: deep monitoring is false by default and true is enabled * immediate: Immediately monitor the default false and enable true */ watch( () => { return user }, () => { console .log( 'Monitor function executed' ) }, { deep : true , //enable deep monitoring immediate : true //immediately monitor } ) return { user } } } </script > copy code

(3) Better practice

When using watch, try to indicate in detail which attribute you want to monitor to avoid performance problems caused by using deep. For example, I just want to execute a callback when the age attribute of the state object changes. You can write like this

Compared with the previous deep listening, the first callback function of the watch function returns the property to be listened to.

< template > {{ user.age }} < button @ click = "user.age++" > change age </button > </template > < Script > //1. watch function introducing Import {REF, watch} from 'VUE' export default { setup () { //2. Initialize a monitoring data const user = ref({ name : 'zs' , age : 20 }) /** * watch (callback function 1, callback function 2, object) * Callback function 1 is the target that needs to be listened, and the function returns and listens * Callback function 2 is called after the listening function is executed * Object deep: deep monitoring is false by default and true is enabled * immediate: Immediately monitor the default false and enable true */ watch( () => { return user.value.age //listen to the required attributes }, () => { console .log( 'Monitor function executed' ) }, { deep : true , //enable deep monitoring immediate : true //immediately monitor } ) return { user } } } </script > copy code

3.5 Life cycle function

Objectives of this section:
Master the use of life cycle hook functions in the combined API

Steps for usage

  1. First import the life cycle hook function starting with on from vue
  2. Call the life cycle function in the setup function and pass in the callback function
  3. Note: The life cycle hook function can be called multiple times

Code landing

< template > < div > </div > </template > < script > //Import the declaration cycle function import {onMounted} from "vue" ; export default { setup () { //2. Use life cycle //It can be used multiple times because the life cycle is a form of function call onMounted( ()=> { console .log( 'mouted life cycle executed' ) }) } } </script > copy code

3.6 Father-son communication

Objectives of this section:
Master the father-son communication under the combined API

In the combined API of vue3, the basic routine of passing from parent to child is exactly the same. The basic idea is still: parent passing child is passed in through prop, and child passing to parent is completed by calling custom events.

Implementation steps

  1. The setup function provides two parameters, the first parameter is props, and the second parameter is an object context
  2. Props is an object, which contains all prop data passed by the parent component. The context object contains attrs, slots, and emit properties. The emit can trigger the execution of custom events to complete the child transmission to the parent.

Code landing Father.vue

< template > < div > < Son :name = "name" @ getName = "getName"/> </div > </template > < script > import Son from "./components/Son" import {ref} from "vue" ; export default { setup () { //1. Define data (father to son) const name = ref( 'black hand' ) //1. Custom event (child to parent) const getName = ( newVal ) => { console .log(newVal) } return { name, getName } }, components : { Son } } /** * Father passes value to son * 1. Define data (parent to child) * 2. Define the accepted data and: name=value correspondence (parent to child) * 3. Get the father's value through props. property name */ </script > Copy code

Son.vue

< template > < div > < div > Son component </div > < button @ click = "setMsgToSon" > click </button > </div > </template > < script > export default { name : "Son" , //2. Define the accepted data and: name=value correspondence (parent to child) props : { name : { type : String } }, emits : [ 'getName' ], setup ( props, context ) { //2. Click to trigger a custom event. Pass the value through the context const setMsgToSon = () => { context.emit( 'getName' , 'Condor Black Hand elaborates on the front end' ) } 3. father//get values props. Attribute name Console .log ( 'parent component name is' , props.name) return { setMsgToSon } } } /** * Son passes value to father * 1. Custom events on the sub-component @Custom Event Name = Function Name * 2. Bind the click event to the child element to trigger the pass value * setup(props, context){ * context.emit('Custom time name', the value that needs to be passed in) *} */ </script > Copy code

3.7 provide and inject

Usually we use props to transfer data between father and child, but if the nesting level of components is deep, it will be very cumbersome to pass down one by one. Is there a way to simplify this process? Some , That is, provide and inject that we are going to learn soon, they can work together to easily complete the cross-layer data transfer

Basic use

Objectives of this section:
Master the basic usage of provide and inject in the setup function

Here is a requirement: a piece of data in the grandfather component is passed to the grandchild component for direct use

Implementation steps:

  1. Top-level components are used in the setup method
    provide function
    provide data
  2. Any underlying components are used in the setup method
    inject function
    retrieve data

Code landing

Grandpa component-app.vue

< template > < div > I am grandpa component < Father/> < Son/> </div > </template > < script > import Son from "./components/Son" import Father from "./components/Father" import {provide, ref} from "vue" ; //1. Introduce provide function export default { setup () { //2. Define the passed data const name = ref( 'black hand' ) provide( 'name' , name) }, components : { Son, Father } } </script > copy code

Sun components-components/Son.vue

< template > < div > < div > I am a Son component </div > </div > </template > < script > import {inject} from "vue" ; export default { name : "Son" , setup () { const name = inject( 'name' ) console .log(name.value) } } </script > copy code

3.8 Use of ref in templates

We are all aware of the use of ref in the template, it generally has three usage scenarios

  1. ref + ordinary dom tag to get the real dom object
  2. ref + component tag to get component instance object
  3. ref + v-for Get an array of dom objects (instance objects) ( not often used )

Objectives of this section:
Master the method of using ref to obtain real dom to obtain component instances in the setup function

Implementation steps

  1. Use ref function to pass in null to create ref object =>
    const hRef = ref(null)
  2. In the template, the association is established by defining the ref attribute equal to the ref object name created in 1 =>
    <h1 ref="hRef"></h1>
  3. Use =>
    hRef.value

Code landing

Father.vue

< template > < div ref = "hRef" > 123 </div > < Son ref = "sonRef"/> </template > < script > import Son from './components/ Son ' import {onMounted, ref} from "vue" ; export default { setup () { const hRef = ref( null ) const sonRef = ref( null ) //Get Dom after Dom is mounted onMounted( () => { console .log(hRef.value) console .log(sonRef.value) }) return { hRef,sonRef } }, components :{ Son } } </script > copy code

./components/Son.vue

< template > < div > I am a child component {{ name }} </div > </template > < script > import {ref} from "vue" ; export default { name : "Son" , setup () { const name = ref( 'Black Hand' ) return { name } } } </script > < style scoped > </style > Copy code