1. Vue3.0 is introduced

1.1 Why learn VUE 3

  1. Vue is one of the most popular front-end frameworks in China
  2. It has been about seven months since the official version of VUe3.0 was released, and the community ecology has been gradually improved
  3. Vue3 is already being used in production by some of the most aggressive companies

So, it’s about time

Currently, vuE3 UI component library is supported

  • ant-design-vue

    Antdv.com/docs/vue/in…

    Ant-design-vue is a VUE implementation of Ant Design, and the style of the components keeps pace with Ant Design

    Vue 3.0 support is currently available in beta 2.0.0

  • element-plus

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

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

  • vant

    Vant – contrib. Gitee. IO/vant/v3 / # / z…

    Lightweight, reliable mobile Vue component library

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

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

  • VueUse

    vueuse.org/

    A common collection based on the Composition API, used in part by the Bunny Fairy project

1.2 New changes brought by Vue3

  • Performance improvement

    • Faster first render
    • The Diff algorithm is faster
    • Less memory footprint
    • Smaller packing volume
  • Better Typescript support

  • Composition API (Emphasis)

    When developing more complex components using vue2.x, the logic is difficult to reuse, which can be solved by the advent of composite apis

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 some damaging syntax updates, which should be paid attention to

  1. Instance method $ON removed (Existing implementation mode of eventBus no longer supports tripartite plug-in instead)
  2. Filter removed (interpolation can no longer use filters, can use methods instead)
  3. .sync syntax removed (merged with V-model syntax)

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

2. Vue3 development environment construction

Next we will learn some new syntax of VUe3. First we will build a basic environment, or use the familiar VUE-CLI to quickly build an integrated vue3 environment

Objective of this section: How to use VUE-CLI to build a vue3.0 based development environment

(1) Select Custom configuration(2) Select the custom installation version(3) Select version 3.xAfter the above step, vuE-CLI will help us run a vUE project with vuE3 built in

Well, first of all we can take a lookpackage.jsonFile, as shown in the Dependencies configuration item, we are currently using version 3.0.0Then open themain.jsIn the import file, we noticed some changes in the Vue instantiation, from the previous new keyword instantiation to the createApp method invocation (more details:www.bilibili.com/read/cv1013…

vue2.x

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

vue3.x

import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
Copy the code

Finally, we opened a single file component and found that the single file component of Vue3.0 no longer requires a unique root element

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>
</template>
Copy the code

That’s all we need to focus on at this stage, so we can learn vue3’s new Composition API based on our current environment

3. Composite apis

The Composition API is a very valuable update to vue3 for us as developers. We don’t care about the syntax, but we have a general sense of it

3.1 composition vs the options

Objective of this section: To gain a general understanding of the composition API

The vUE application developed by options API is shown in the figure on the left. It is easy to understand, because each option has a fixed writing position. For example, responsive data is written into data selection, and operation methods are written into methods configuration items

The vUE application developed by Composition API is shown in the picture on the right. Its feature is that all things related to A particular function are maintained together, such as responsive data related to function A and methods of manipulating data. In this way, no matter how big the application is, all codes related to A particular function can be quickly read and easily maintained. If the function is complex and the amount of code is large, we can also carry out logical split processing Special attention:

  1. The two styles of optional API and composite API exist side by side and are not one or the other

  2. Scenarios that require a lot of logical composition can be enhanced using the Compition API

3.2 Case Comparison

In this section, we will take a closer look at the comparison of development modes between the two apis through a specific case study. We will ignore the syntax details for the moment and focus only on the code writing form

Objective: To understand the benefits of the Compition Api by implementing the same requirement in both Api forms

3.2.1 Understanding Requirements

Function: by clicking the button to control the text display and hide(1) Vue2. X Option Api version

<template>
<div>
  <button @click="showText">According to</button>
  <button @click="hideText">hidden</button>
  <p v-if="isShow">Here is some text to show the 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 the code

(2) Vue3.0 Composition API version

<template>
  <div>
    <button @click="showText">According to</button>
    <button @click="hideText">hidden</button>
    <p v-if="isShow">Here is some text to show the hidden</p>
  </div>

</template>

<script>
// Introduce the required methods
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 the method here
    const hideText = () = > {
      isShow.value = false
    }
    // Return everything you use
    return {
      isShow,showText,hideText
    }
  }
}
</script>

<style>

</style>
Copy the code

Above, we define function functions, separate function related code into a separate small function, and then combine the small function functions in the setUp function, so that we can not only clean up the setUp function, but also easy to maintain and quickly locate the function location

Nice ~ so far we have not focused on the details of the API, just to appreciate the benefits of the composite API. Now we will dive into the details of the API and see how the new API is used

3.3 Setup entry functions

Objective of this section: To understand what the setup function does and when to call it

  1. The setup function is a new component option that serves as a starting point (entry) for the composite API in the component
  2. From a lifecycle perspective, setup is executed before the beforeCreate hook function
  3. Setup cannot use this; this points to undefined
export default {
  setup () {
    console.log('Setup executes')
    console.log(this)},beforeCreate() {
    console.log('beforeCreate executed ')
    console.log(this)}}Copy the code

3.4 Responsive system API

3.4.1 track reactive function

Objective of this section: Understand the syntax of reactive functions

Reactive: Reactive is a function that receives a normal object, converts the object data into a reactive object and returns it

Using the step

  1. Import from the VUE frameworkreactivefunction
  2. Call reactive in the setup function and pass in the object data
  3. The setup function returns the value of a call to reactive as an object

Click age +1 to find the data is responsive

The code to the ground

<template>
  <div>
    <p>Age is {{user.age}}</p>
    <button @click="user.age++">Age + 1</button>
  </div>

</template>

<script>
// 1. Introduce reactive functions from vUE
import {reactive} from 'vue'

export default {
  setup() {
    // 2. Call the function in setup and bring in the data object
    const user = reactive({
      name: 'zs'.age: 18
    })
    // 3. In the setup function, the value of the call to reactive is returned as an object
    return {
      user
    }
  }
}
</script>

<style>

</style>
Copy the code

3.4.2 ref function

Objective of this section: To understand the syntactic use of the ref function

Ref is a function that takes an incoming simple type or complex type and returns a responsive, mutable ref object

Using the step

  1. Export from the VUE frameworkreffunction
  2. Called in the setup functionrefFunction and pass in data (simple or complex type)
  3. The setup function returns the value of the ref call as an object
  4. Note: To use ref results in the setup function, you need to pass.valueValue is not required for use in templates

Be born code

<template>
  <div>
    <p>The age is {{age}}</p>
    <button @click="addAge">Age + 1</button>
  </div>

</template>

<script>
// 1. Import the ref function from vUE framework
import {ref} from 'vue'

export default {
  setup() {
    // 2. Call the function in setup and bring in the data object
    const age = ref(18)

    const addAge = () = > {
      // This here refers to the underpay, so this cannot be used. To access the data
      // Use.value to access data
      age.value++
    }
    // 3. In the setup function, the value of the call to reactive is returned as an object
    return {
      age,addAge
    }
  }
}
</script>
Copy the code

Summary:

  1. A ref function can take a value of a simple type and return a ref-responsive object that can be changed to compensate for the lack of simple type support in reactive functions
  2. Reactive and REF functions both provide reactive data conversion. There are no community best practices on which API to use and when, so you can use your own API for conversion
  3. One way to write this is to use reactive only if we know the key of the field inside the object to be transformed, otherwise ref is used to reduce the mental burden of choosing a syntax

Rule 3.4.3 toRefs function

Problem of repetition

The goal of this section is to simplify the use of reactive objects using the toRefs function

Scenario: An object returned by a reactive function will lose its responsiveness if it is deconstructed or expanded. To solve this problem, the toRefs function needs to be introduced. ToRefs ensures that every attribute of the object is expanded in a reactive manner

Click the +1 button to see that the view has not changed. This is what we are talking about. If you deconstruct the return value of reactive, you will break the reactive nature of the call and need to use the toRefs method

<template>
  <div>
    <p>The age is {{age}}</p>
    <button @click="age++">Age + 1</button>
  </div>

</template>

<script>
// 1. Introduce reactive functions from vUE
import {reactive} from 'vue'

export default {
  setup() {
    // 2. Call the function in setup and bring in the data object
    const user = reactive({
      name: 'zs'.age: 18
    })
    // 3. In the setup function, the value of the call to reactive is returned as an object
    return {
      ...user
    }
  }
}
</script>
Copy the code

Processing method

3.4.4 computed

Objective of this section: To master the use of computed property functions in setup functions

Function: according to the existing responsive data through certain calculation to get new data

Using the step

  1. Import from the VUE frameworkcomputedfunction
  2. Perform a computed function in the setup function and pass in a function that defines the calculation formula
  3. Place the results of computed function calls into the return value object of setup

The code to the ground

<template>
  {{ list }}
  {{ filterList }}
  <button @click="changeList">change list</button>
</template>

<script>
// 1. Introduce computed attribute functions
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 list function
    function changeList() {
      list.value.push(6.7.8)}// 3. Data must return
    return {
      list,
      filterList,
      changeList
    }
  }
}
</script>
Copy the code

3.4.5 Watch listener

Objective of this section: To master the use of listeners in setup functions

Function: Performs callback logic based on changes in responsive data, exactly the same function as Watch in VUe2

  1. Ordinary listening
  2. Executed immediately
  3. The depth of the listening

Using the step

  1. Import from the VUE frameworkwatchfunction
  2. Enable listening for reactive data by executing the watch function in the setup function
  3. The watch function takes three general arguments
    1. The first argument is a function that returns the responsive data you want to listen for changes
    2. The second parameter is the callback function to execute after a reactive data change
    3. The third parameter is an object in which to enable immediate execution or deep listening

Code landing (1) Ordinary listening

<template>
  {{ age }}
  <button @click="age++">change age</button>
</template>

<script>
// 1. Introduce the watch function
import {ref, watch} from 'vue'

export default {
  setup() {
    // 2. Initialize a listener
    const age = ref(18)
    /** * watch (callback 1, callback 2) * callback 1 is the target to listen to return within the function, that is, listen * callback 2 is called after the listener has executed
    watch(() = > {
          return age.value
        },
        () = > {
          console.log('Listener function executed')})return {
      age
    }
  }
}
</script>
Copy the code

(2) Compared with the deep listening code landing and immediate execution enabled, ordinary listening only has one more parameter object in the watch function

<template>
  {{ user.age }}
  <button @click="user.age++">change age</button>
</template>

<script>
// 1. Introduce the watch function
import {ref, watch} from 'vue'

export default {
  setup() {
    // 2. Initialize a listener
    const user = ref({
      name: 'zs'.age: 20
    })
    /** * watch (callback function 1, callback function 2, object) ** watch (callback function 1, callback function 2, object) Depth Depth listening Default false Enable true * immediate: immediate listening Default false enable true */
    watch(() = > {
          return user
        },
        () = > {
          console.log('Listener function executed')}, {deep: true.// Enable deep listening
          immediate: true // Listen immediately})return {
      user
    }
  }
}
</script>
Copy the code

(3) Better practices

When using Watch, be as specific as possible about which properties you want to listen for to avoid the performance problems associated with using deep. For example, I only want to perform a callback when the age property of the state object changes

Instead of deep listening, the first callback in the watch function returns the property to listen for

<template>
  {{ user.age }}
  <button @click="user.age++">change age</button>
</template>

<script>
// 1. Introduce the watch function
import {ref, watch} from 'vue'

export default {
  setup() {
    // 2. Initialize a listener
    const user = ref({
      name: 'zs'.age: 20
    })
    /** * watch (callback function 1, callback function 2, object) ** watch (callback function 1, callback function 2, object) Depth Depth listening Default false Enable true * immediate: immediate listening Default false enable true */
    watch(() = > {
          return user.value.age // Listen for the desired properties
        },
        () = > {
          console.log('Listener function executed')}, {deep: true.// Enable deep listening
          immediate: true // Listen immediately})return {
      user
    }
  }
}
</script>
Copy the code

3.5 Life cycle function

Objective of this section: To learn how to use lifecycle hook functions in a composite API

Using the step

  1. Start by importing a lifecycle hook function starting with ON from vue
  2. Call the lifecycle function in the setup function and pass in the callback function
  3. Note: Lifecycle hook functions can be called multiple times

The code to the ground

<template>
  <div></div>
</template>

<script>
// introduce a declaration of periodic functions
import {onMounted} from "vue";

export default {
  setup(){
    // 2. Use the lifecycle
    // Can be used multiple times because the declaration cycle is in the form of a function call
    onMounted(() = > {
      console.log('Mouted life cycle executed')}}}</script>
Copy the code

3.6 Father-Son Communication

Objective of this section: Master parent-child communication under the combined API

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

Implementation steps

  1. The setup function takes two arguments, the first parameter being props and the second parameter being an object context
  2. The props object contains all prop data passed by the parent component. The Context object contains the attrs, slots, and EMIT properties, where the emit can trigger the execution of custom events to complete the parent

The code falls into 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 (parent to child)
    const name = ref('black')

    // 1. Custom event (child to parent)
    const getName = (newVal) = > {
      console.log(newVal)
    }
    return {
      name, getName
    }
  },
  components: {
    Son
  }
}


/** * Parent passes value to child * 1. Define data (parent to child) * 2. Define accept data and: name = value corresponding (parent to child) * 3. Pass props. Attribute name gets the parent value */
</script>
Copy the code

Son.vue

<template>
  <div>
    <div>Son components</div>
    <button @click="setMsgToSon">Click on the</button>
  </div>
</template>

<script>
export default {
  name: "Son".// 2. Define accept data and: name = value corresponding (parent child)
  props: {
    name: {
      type: String}},emits: ['getName'].setup(props, context) {
    // 2. Click to trigger custom event transfer through context
    const setMsgToSon = () = > {
      context.emit('getName'.'Condor Black Hand In detail')}// 3. Get the parent value from the props
    console.log('Parent component's name is', props.name)

    return {
      setMsgToSon
    }
  }
}


/** * Child passes value to parent * 1. Custom event on child @ Custom event name = function name * 2. Setup (props, context){* context.emit(' custom time name ', required value passed in) *} */
</script>
Copy the code

3.7 dojo.provide and inject

Usually, we use props to transfer data between parent and child. However, if components are nested at a deeper level, layer by layer transmission becomes very complicated. Is there a way to simplify this process? Together, they can easily transfer data across layers

Based on using

Objective of this section: To learn the basics of using provide and Inject in setup functions

Here is a requirement: the parent component has a piece of data passed to the grandson component for direct use

Implementation steps:

  1. The top-level component is used in the setup methodDojo.provide functionProvide data
  2. Any underlying component used in the Setup methodInject functionTo get the data

Code landing grandpa component – app.vue

<template>
  <div>I'm grandpa Component<Father />
    <Son/>
  </div>
</template>

<script>
import Son from "./components/Son"
import Father from "./components/Father"
import {provide, ref} from "vue";

// 1. Introduce the provide function

export default {
  setup() {
    // 2. Define the data to pass
    const name = ref('black')
    provide('name', name)
  },
  components: {
    Son,
    Father
  }
}

</script>
Copy the code

Suncomponent-components/son.vue

<template>
  <div>
    <div>I'm 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 the code

3.8 Using ref in the Template

When we use ref in templates, we all know that there are three common scenarios for using it

  1. Ref + Plain DOM tag gets the real DOM object
  2. The ref + component tag gets the component instance object
  3. Ref + V-for gets an array of DOM objects (instance objects) (not often used)

Objective of this section: To learn how to get a component instance using ref to get the real DOM in the Setup function

Implementation steps

  1. Create a ref object with null =>const hRef = ref(null)
  2. Create a template association by defining the name of the ref object created in the ref attribute =><h1 ref="hRef"></h1>
  3. Using = >hRef.value

The code falls into 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 the Dom after the Dom is mounted
    onMounted(() = > {
      console.log(hRef.value)
      console.log(sonRef.value)
    })

    return {
      hRef,sonRef
    }
  },
  components:{
    Son
  }
}
</script>
Copy the code

./components/Son.vue

<template>
  <div>I am the child component {{name}}</div>
</template>

<script>
import {ref} from "vue";

export default {
  name: "Son".setup() {
    const name = ref('black')
    return {
      name
    }
  }
}
</script>

<style scoped>

</style>
Copy the code