1 Create a VUE3 + TS project

main.ts

// Program main entry questionnaire, TS file
import { createApp } from 'vue'
import App from './App.vue'

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

App.vue

<template> <! HTML templates in VUe2 require a root tag, but vue3 does not.<img alt="Vue logo" src="./assets/logo.png">
<! -- 4. Use child components -->
  <HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
</template>


<script lang="ts">
    / / <! -- Using the ts code -->
    
// 1 defineComponent defines a component that can pass in a configuration object internally
import { defineComponent } from 'vue';
//2 Introduces a child component
import HelloWorld from './components/HelloWorld.vue';

//3 Exposes a defined component
export default defineComponent({
  // 3.1 The current component name is App
  name: 'App'.// 3.2 Registering components
  components: {
    // 3.3 Register a child component
    HelloWorld
  }
});
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
Copy the code

2 Composition API

setup

  • The new option, where all composition API functions are used, is executed only once during initialization
  • A function that returns an object, property or method in the object, can be used directly in a template
<template>
<div>good day</div>
  <h2>{{number}}</h2>
</template>


<script lang="ts">


// 1 defineComponent defines a component that can pass in a configuration object internally
import { defineComponent } from 'vue';

//3 Exposes a defined component
export default defineComponent({
  // 3.1 The current component name is App
  name: 'App'.Setup is the first function to be used in the composition API to test the code
    setup(){
      const number = 10
        return{
          number
        }
    }

});
</script>
Copy the code

Setup and ref are basic uses

  • Requirement: the page opens to see the data, and you can click the button to update the data
<template>
<h2>Setup and ref are basic uses</h2>
  <h3>{{count}}</h3>
  <button @click="updateCount">update count</button>
</template>


<script lang="ts">

import { ref,defineComponent } from 'vue';
export default defineComponent({
 name: 'App'.// Requirements: when the page opens, you can see the data and click the button to update the data
/ / vue2 method
    data(){
     return{
      count:0/ / property}},methods: {updateCount(){/ / method
            this.count++
        }
    },

// 3 Vue3 method
//3.1 Setup is the entry function to the composition API
    setup(){
     / / 3.3 variables
     // let count = 0
     // ref is a function that defines a responsive data and returns a ref object with a value attribute. If you need to operate on data, you need to operate on.value
     // ref is used to define a basic type of reactive data
        const count = ref(0)
     / / 3.4 method
       function updateCount(){
         // count++// error: count is a ref object
           count.value++
       }
     //3.2 returns an object
     return{
         count, / / property
         updateCount / / method}}});</script>
Copy the code

The use of reactive

- Reactive proxy = reactive(obj): The reactive Proxy object-reactive transformation that takes a normal object and then returns that normal object is "deep" : it affects all nested properties inside the object - internal es6-based Proxy implementations that operate on the internal data of the source object through the Proxy object are all reactiveCopy the code
  • Demand display user information, click the button, and new user information
< the template > < h2 > reactive basic use < / h2 > < h3 > name: {{user. The name}} < / h3 > < h3 > age: {{user. Age}} < / h3 > < h3 > friend: {{user. Friend}} < / h3 > <br> <button @click="updataUser">updata</button> </template> <script lang="ts"> import { reactive,defineComponent } from  'vue'; export default defineComponent({ name: 'App', setup(){//1 Change data to responsive const obj = {name:' Tom ', age:10, friend:{name:'lily', age:12, Books :['a','b','c']}} const user = reactive(obj) Console. log(user)//Proxy {name: 'Tom ', age: 10, friend: {... }}[[Handler]]: Object[[Target]]: Object[[IsRevoked]]: False //3 const updataUser =()=>{user.name ='lone' user.age ++ user.friend.name =' luca'} // 2 return return{user,  updataUser } } }); </script>Copy the code

Reactive and Ref – Details

  • Vue3 composition API is the two most important responsive API
  • Ref is used for primitive data and Reactive is used for objects (recursive deep responsiveness)
  • If you use a REF object/array, it automatically converts the object/array to a Reactive proxy object
  • Inside ref: Data hijacking by adding getters/setters to value properties
  • Internal Reactive: Hijacks all internal data of an object by using Proxy and works on the internal data of the object through Reflect
  • Ref data manipulation:.value is required in js, not in templates (.value is automatically added when templates are internally parsed)

toRefs

ToRefs is useful when returning a reactive object from a synthesized function, so that the consuming component can decompose the returned object without losing the reactive. All property values fetched by a Reactive object are non-reactive solutions: toRefs is used to convert all raw properties of a reactive object into reactive REF propertiesCopy the code

computed \watch \watchEffect

  • The computed function:

    • This function is consistent with computed configuration
    • Only the getter
    • Have a getter and setter
  • Watch function

    • The functions are the same as those configured on the Watch
    • Monitors one or more specified reactive data and automatically executes monitoring callbacks whenever the data changes
    • By default, the initial callback is not executed. However, you can specify that the initial callback is executed immediately by setting immediate to true
    • Deep monitoring is specified by setting deep to true
  • WatchEffect function

    • Instead of specifying the data to monitor directly, which reactive data is used in the callback function monitors which reactive data
    • By default, the first execution is performed initially so that data that needs to be monitored can be collected
    • Callback when monitoring data changes
<template>
  <h2>App</h2>
  fistName:
  <input v-model="user.firstName" />
  <br />
  lastName:
  <input v-model="user.lastName" />
  <br />
  fullName1:
  <input v-model="fullName1" />
  <br />
  fullName2:
  <input v-model="fullName2" />
  <br />
  fullName3:
  <input v-model="fullName3" />
  <br />
</template>

<script lang="ts">
/* Calculate attributes and monitor 1. Computed functions: In accordance with computed configuration, only getters have getters and setters. 2. In accordance with watch configuration, the watch function monitors one or more specified responsive data and automatically executes monitoring callbacks when the data changes. The watchEffect function does not specify the data to be monitored directly. The watchEffect function does not specify the data to be monitored. By default, the first time is executed when the callback function is initialized, so that the data that needs to be monitored can be collected to monitor the callback */ when the data changes

import { reactive, ref, computed, watch, watchEffect } from 'vue'

export default {
  setup() {
    const user = reactive({
      firstName: 'A'.lastName: 'B'
    })

    // Only getter computed properties
    const fullName1 = computed(() = > {
      console.log('fullName1')
      return user.firstName + The '-' + user.lastName
    })

    Getters and setters
    const fullName2 = computed({
      get() {
        console.log('fullName2 get')
        return user.firstName + The '-' + user.lastName
      },

      set(value: string) {
        console.log('fullName2 set')
        const names = value.split(The '-')
        user.firstName = names[0]
        user.lastName = names[1]}})const fullName3 = ref(' ')

    /* watchEffect: Monitors the data used in all callbacks */
    /* watchEffect(() => { console.log('watchEffect') fullName3.value = user.firstName + '-' + user.lastName }) */

    /* Use two features of Watch: deep monitor initialization immediately */
    watch(
      user,
      () = > {
        fullName3.value = user.firstName + The '-' + user.lastName
      },
      {
        immediate: true.// Whether to initialize immediately. Default is false
        deep: true // If it is deep monitoring, the default is false})/* watch a data is executed by default when the data changes */
    watch(fullName3, value= > {
      console.log('watch')
      const names = value.split(The '-')
      user.firstName = names[0]
      user.lastName = names[1]})/* watch multiple data: use an array to specify a value in a ref object, and use a function to specify a value in a Reactive object
    watch([() = > user.firstName, () = > user.lastName, fullName3], values= > {
      console.log('Monitor multiple data', values)
    })

    return {
      user,
      fullName1,
      fullName2,
      fullName3
    }
  }
}
</script>
Copy the code

3 Differences between VUE2 (Option API) and VUe3 (Composition API)

Adding or modifying a requirement in the traditional Option API requires modification in Data, Methods.com puted, or WATCHED. The scrolled bar moves around the Composition API is more elegant. Each requirement is written together and the code structure of related functions is more orderly.

4 Comparing the response formula of Vue2 and Vue3 (important)

The response formula of VUe2

  • Core:

    • Objects: Hijacking (monitoring/intercepting) the reading and modification of existing attribute values of objects via defineProperty
    • Array: Element modification hijacking is implemented by overriding an array to update a series of array elements
Object.defineProperty(data, 'count', {
  get() {},
  set(){}})Copy the code
  • The problem

    • The interface does not automatically update newly added attributes or delete existing attributes
    • Arr [1] = {}

Response formula of Vue3

  • Core:

    • Through Proxy(Proxy): intercept any (13) operation of any data attribute, including reading and writing of attribute value, adding attribute, deleting attribute, etc..

    • Reflect: Dynamically performs a specific action on the corresponding property of the proxied object

    • Documents:

      • Developer.mozilla.org/zh-CN/docs/…
      • Developer.mozilla.org/zh-CN/docs/…
Get (target, prop) {return reflect. get(target, prop)}, // Add a new attribute set(target, prop) Value) {return reflect. set(target, prop, value)}, prop) { return Reflect.deleteProperty(target, prop) } }) proxy.name = 'tom'Copy the code
<! DOCTYPE html><html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <title>The Proxy to Reflect</title>
  </head>
  <body>
    <script>
      const user = {
        name: 'John'.age: 12
      }

      /* proxyUser is a proxy object, and user is a proxy object
      const proxyUser = new Proxy(user, {
        get(target, prop) {
          console.log('hijacked the get ()', prop)
          return Reflect.get(target, prop)
        },

        set(target, prop, val) {
          console.log('hijacked set ()', prop, val)
          return Reflect.set(target, prop, val) / / (2)
        },

        deleteProperty(target, prop) {
          console.log('Hijack delete attribute', prop)
          return Reflect.deleteProperty(target, prop)
        }
      })
      // Read the property value
      console.log(proxyUser === user)
      console.log(proxyUser.name, proxyUser.age)
      // Set the property value
      proxyUser.name = 'bob'
      proxyUser.age = 13
      console.log(user)
      // Add attributes
      proxyUser.sex = 'male'
      console.log(user)
      // Delete attributes
      delete proxyUser.sex
      console.log(user)
    </script>
  </body>
</html>
Copy the code

Vue data hijacking agent

Object.defineproperty is used to implement data hijacking and proxy. This method has get and set attributes. Get attributes are used to get data attributes, and set attributes are used to monitor the current data. The set method is also used to update the data in the original data.

// Simulate the data option in Vue

let data = {
  username: 'A'.age: 33
}


// Simulate an instance of the component
let _this = {

}

/ / use Object. DefineProperty ()
for(let item in data){
  // console.log(item, data[item]);
  Object.defineProperty(_this, item, {
    // get: Used to get the value of the extended attribute. The get method is called when the value of the attribute is obtained
    get(){
      console.log('get()');
      return data[item]
    },
    // set: monitors extended attributes, called whenever they have been modified
    set(newValue){
      console.log('set()', newValue);
      // _this.username = newValue; Do not modify the value of the current extended attribute in the set. This will cause an infinite loop
      data[item] = newValue;// You can modify the value of the original data here}})}console.log(_this);
// Extended attributes added through the get method of Object.defineProperty cannot be added directly to the Object. Attribute changes
_this.username = 'B';
console.log(_this.username);
Copy the code

6 Data Binding (bidirectional and unidirectional)

  1. Vue
    1. Initializes data in data
    2. Modify data: this.key = value
    3. The data flow:
      1. Vue is a single data stream: Model –> View

      2. Two-way data binding is implemented in Vue: v-Model

  1. Small program
    1. Initializes data in data
    2. Modify data: this.setData()
      1. The behavior of modifying data is always synchronous
    3. The data flow:
      1. Single item: Model –> View
  2. React
    1. State initializes state data
    2. Modify data: this.setState()
      1. Native hook function (componentDidMount) asynchronous
      2. Synchronized in a non-own hook function
    3. The data flow:
      1. Single item: Model –> View

7 VuE2 and VUE3 life cycles

Vue2 lifecycle hook function

When talking about the Vue lifecycle,

In the new Vue () object, init and call the beforeCreate.

It then calls Created again when the injection or reactivity is invoked.

When created is created, it determines if the instance contains “el” option. If not, it calls the vm.$mount(el) method and proceeds to the next step. If yes, go to the next step.

It then determines if it contains the “template” option, and if it does, it parses template into a render function that returns a createElement method, The render function happens between beforeMount and Mounted,

BeforeMount is executed when the render function is executed, mounts is called when the render function is executed, and the instance is finished running after mounted.

Subsequent hook functions perform procedures that require an external trigger to execute:

For example, with data changes, beforeUpdate is called,

Then through the Virtual DOM, finally updated.

When a component is destroyed, it calls beforeDestory, and deStoryed.

The lifecycle of VUE3

A composite API corresponding to the 2.x release lifecycle

  • beforeCreate– > usesetup()
  • created– > usesetup()
  • beforeMount -> onBeforeMount
  • mounted -> onMounted
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeDestroy -> onBeforeUnmount
  • destroyed -> onUnmounted
  • errorCaptured -> onErrorCaptured

8 nextTick

  1. This.$nextTick(()=>{}) will execute after DOM asynchronous rendering is complete. I can get the changed data
  2. DOM asynchronous rendering is batch and results directly.