Take you to explore Vue 3.0 by hand | JD Logistics Technical Team

1 Introduction

It has been a while since the official release of Vue 3.0. On February 7, the Vue team officially announced that Vue 3 has officially become the new default version. The new projects I have been exposed to recently are also developed using Vue 3.0, so it is necessary to summarize and learn about it.

2 Introduction

In the very beginning, Vue was just a runtime library. But after years of development, it has gradually become a framework with many sub-projects. Vue's core library only focuses on layers, which is not only easy to use, but also easy to integrate with third-party libraries or existing projects. So what new performance does Vue 3.0 bring?

  • Virtual Dom rewritten
  • Optimization of Compiled Templates
  • More efficient component initialization
  • SSR speed increased by 2~3 times
  • Update performance improved by 1.3~2 times
  • It seems that Vue 3 has greatly improved its performance compared to 2. As end users, let's take a look at how the code is implemented.

3 new features

3.1 Composition API

Vue 2 uses the Options API (option-style API), that is, write codes in data, methods, computed, and watch respectively. If we need to add a logic, we need to repeatedly jump across these options, which makes the components difficult to understand and read. Vue 3 has added a setup option, which is the entry point of the combined API. It collects code related to the same logic concern, so that when we need to maintain a function point, we don't need to care about other logic.

for example

<template>
  <div>{{number}}</div>
  <button @click="add">Add</button>
</template>

<script>
import { ref } from 'vue'

export default {
  setup () {
    const number = ref(0)  //ref()函数使变量变为响应式
    const add = () => {
      number.value++   //使用ref创建的响应式变量需要加.value
    }
    return {  //返回的变量和方法可以在模板中直接使用
      number,  
      add
    }
  }
}
</script>

Doesn’t it look like putting all the contents of data and methods into the setup? There’s not much difference? In fact, we can also divide the contents of the setup into independent functions, and each function is responsible for an independent function. In this way, we can reuse in different components and simplify the code, which is the power of the combined API.

3.2 Responsive API

3.2.1 ref

In the above code, we use ref to create a responsive object, which accepts js basic types or reference types as parameters, and returns a RefImp object that only contains the parameter named value. If we want to use the responsive object in the setup function, we need to add .value. But when rendered in the template, the internal value is automatically expanded, so there is no need to append .value in the template.

Ref is often used for basic types. If ref is passed into an object, it will be converted to reactive internally for processing.

import { ref } from "vue";
const str = ref("");
const male = ref(true);

str.value = "new val";
console.log(str.value);  //new val

male.value = false;
console.log(male.value)  //fals

3.2.2 reactive

The reactive function only accepts complex data types such as object and array, and it returns a proxy object. Reactive can be recursive at a deep level, that is, if it is found that the expanded attribute value is a reference type and is referenced, it will be processed recursively with reactive. And properties can be modified. Proxy is a proxy function used to create an object in es6, which can realize the interception and customization of basic operations such as adding, deleting, modifying and checking the target object.

const p=new Proxy(target,handler) //target是proxy包装的目标对象,handler是一个以函数作为属性的对象

Simple simulation implements reactive to implement responsiveness:

      const obj={a:1,b:2}
      const p=new Proxy(obj,{
          get(target,key){
            console.log(`p的${key}属性被访问了!`)
            return Reflect.get(target,key)
          },
          set(target,key,value){
            console.log(`p的${key}属性被修改了!`)
            return Reflect.set(target,key,value)
          },
          deleteProperty(target,key){
            console.log(`p的${key}属性被删除了!`)
            return Reflect.deleteProperty(target,key)
          }
        })

3.2.3 toRefs

Through the above introduction, we already know that ref is usually used to create two-way binding of basic type data, and reactive is usually used to create two-way binding of reference data type. In addition, ref can also create two-way bindings of complex types, while reactive cannot proxy basic types. Let's look at an example:

<template>
  <div>{{user.name}}</div>
  <div>{{user.age}}</div>
  <div>{{user.sex}}</div>
  <button @click="changeInfo">更改个人信息</button>
</template>

<script>
import { ref } from 'vue'

export default {
  setup () {
    const user = ref({name:'张三',age:'18',sex:'男'})  
    const changeInfo = () => {
      user.name.value='李四'
      user.age=20
      user.sex='女'
    }
    return {  
       user
    }
  }
}
</script>

In the above code, we bind to the page using user.name, user.age, which feels very cumbersome to write. Can we deconstruct the user and use it directly in the template? The answer is no, doing so will cause the user to lose responsiveness. But by using toRefs, you can use the destructured data directly. toRefs is used to convert a reactive object into a normal object whose properties are all ref objects. The specific usage is as follows:

<template>
  <div>{{name}}</div>
  <div>{{age}}</div>
  <div>{{sex}}</div>
  <button @click="changeInfo">更改个人信息</button>
</template>

<script>
import { ref } from 'vue'

export default {
  setup () {
    const user = ref({name:'张三',age:'18',sex:'男'})  
    const changeInfo = () => {
      user.name.value='李四'
      user.age=20
      user.sex='女'
    }
    return {  
       ...toRefs(user)  //使用toRefs
    }
  }
}

3.3 Responsive listening

The watch function is used to listen to a specific data source and perform side effects in the callback function. The default is lazy, which means that the callback is only executed when the listening source data changes.

watch(source,callback,[options])
  • source: can support string, Object, Function, Array; used to specify the responsive variable to be listened to
  • callback: the callback function to execute
  • options: optional, support deep, immediate and flush

Usage of listening to a single data source:

import { reactive, ref, watch } from "vue";

const state = reactive({
  number:0,
  id:'01'
});
//侦听reative对象
watch(
  () => state.number,
  (newvalue, oldvalue) => {
    console.log(newvalue, oldvalue); //1 0
  }
);
state.number++;

const count = ref(0);
//侦听ref对象
watch(count, (count, prevCount) => {
  console.log(count, prevCount, "watch"); //2 0
});
count.value = 2

Usage of listening to multiple data sources:

import { reactive, ref, watch } from "vue";


const state = reactive({
  number:0,
  id:'01'
});
const count = ref(0);
watch([count,()=>{state.number}],([curcount,precount],[curnumber,prenumber])=>{
  console.log(curcount,precount)  //2 0
  console.log(curnumber,prenumber) //1 0
})
state.number++
count.value=2

For multi-level nested reference objects, you can use {deep:true} to enable deep monitoring. Otherwise, only outer layer data changes can be monitored. As mentioned earlier, the callback function of the watch under clearing by default is lazy, and will only be executed when the monitoring data changes. When {immediate: true} is configured, the callback function can be executed immediately.

3.4 Life cycle

There are 8 lifecycle functions in Vue2:

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed

In vue3, a new setup life cycle function is added. The timing of setup execution is before the beforeCreate life function, so the instance cannot be obtained through this in this function; at the same time, for the unification of naming, beforeDestroy is renamed to beforeUnmount, and destroyed is renamed to unmounted, so vue3 has the following life cycle functions:

  • beforeCreate -> not required
  • created -> not required
  • beforeMount -> onBeforeMount
  • mounted -> onMounted
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeUnmount -> onBeforeUnmount
  • unmounted -> onUnmounted
  • errorCaptured -> onErrorCaptured
  • renderTracked -> onRenderTracked
  • renderTriggered -> onRenderTriggered

4 Summary

Through the summary of the above knowledge, I have a further understanding of Vue 3, which can basically meet the project development. For more changes, you can check the official documents and read the source code by yourself. I believe that Vue 3 can bring us more new experiences.

Author: JD Logistics Yan Zhiting

Source: JD Cloud developer community Ziqishuo Tech

The 8 most in-demand programming languages ​​in 2023: PHP is strong, C/C++ demand is slowing Musk announced that Twitter will be renamed X, and the logo will be changed for five years, Cython 3.0 is officially released GPT-4 is getting more and more stupid? The accuracy rate dropped from 97.6% to 2.4%. MySQL 8.1 and MySQL 8.0.34 were officially released. The father of C# and TypeScript announced the latest open source project: TypeChat Meta Enlargement move: released an open source large language model Llama 2, which is free for commercial use . React core developer Dan Abramov announced his resignation from Meta. ChatGPT for Android will be launched next week. Pre-registration starts now . needs? Maybe this 5k star GitHub open source project can help - MetaGPT
{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4090830/blog/10090343