Vue3 was released a long time ago, but the bloggers didn’t start learning until today, mainly because the bloggers didn’t learn the front end for a long time, there are too many things to learn in the front end, plus the books and learning projects bought by the bloggers are Vue2, so they have been studying Vue2, and today they are finally ready to start Vue3!! Let’s get you started

This article is based on the B station is still Silicon Valley video “Is still Silicon Valley Vue2.0+Vue3.0 complete tutorial, the latest and strongest vuejs from the entry to master” Vue3 part of the formation of notes

A list,

Vue. Js version 3.0 was released on 18 September 2020.

Github.com/vuejs/vue-n…

New things will make sense, so let’s take a look at what Vue3 does better than Vue2.

1. Performance improvement

  • Package size reduced by 41%

  • Initial rendering is 55% faster and updated rendering is 133% faster

  • Memory reduced by 54%

The above data comes from the official, seeing this, the enthusiasm to learn Vue3 has increased a little

2. Upgrade the source code

  • Use Proxy instead of defineProperty to implement responsiveness

  • Rewrite virtual DOM implementation and tree-shaking

Bloggers before the source series of notes are Vue3, this time to learn the comparison

3. Embrace the TypeScript

  • Vue3 can be better supportedTypeScript

Anyway, the next stack to learn is TS!!

4. New features

  1. Composition API

    • setupconfiguration
    • refwithreactive
    • watchwithwatchEffect
    • providewithinject
  2. New built-in components

    • Fragment
    • Teleport
    • Suspense
  3. Other changes

    • New lifecycle hooks
    • data Options should always be declared as a function
    • removekeyCodeSupport asv-onThe modifier

There are a lot of new terms here, so don’t worry, let’s get started quickly!

Create a Vue project

1. Use vue-CLI to create a vm

The official document: cli.vuejs.org/zh/guide/cr…

Check the @vue/ CLI version and ensure that the @vue/ CLI version is above 4.5.0
vue --version
Install or upgrade your @vue/ CLI
npm install -g @vue/cli
To create a Vue project, select Vue3
vue create vue_test
# # start
cd vue_test
npm run serve
Copy the code

It can also be created using visual panels

The blogger thinks that, as a front-end development engineer, everything is visualized well!! Haha, I like to use visual palette, including git, and I also like visual palette with VScode

vue ui 
Copy the code

Vue3 is the default when creating a project

2. Create the vm using Vite

The official document: v3.cn.vuejs.org/guide/insta…

Vite official website: vitejs.cn

  • What is a Vite? — Is a new generation of front-end building tools created by Vue team.

  • Advantages:

    • Development environment, no packaging operation, fast cold start.
    • Lightweight fast thermal overload (HMR).
    • True on-demand compilation, no longer waiting for the entire application to compile.
  • Traditional build vs. Vite build

The traditional build model is to pack up all the resources and go live

Vite is a bit of an on-demand load

Next we will use Vite to create a Vue3 project

## Create project
npm init vite-app yk_vue3
Enter the project directory
cd yk_vue3
# install dependencies
npm install
# # to run
npm run dev
Copy the code

Build speed is obviously faster than Vite

Now that the project is built, let’s take a look at the visual differences between Vue3 and Vue2

3. Analyze the file directory

main.js

The Vue2 project’s main.js

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

Vue.config.productionTip = false

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

What is vm

const vm = new Vue({
  render: h= > h(App),
})

console.log(vm)

vm.$mount('#app')
Copy the code

Let’s take a look at main.js in the Vue3 project

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

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

So let’s analyze it

// Instead of introducing the Vue constructor, a factory function called createApp is introduced
import { createApp } from 'vue'
import App from './App.vue'

// Create an application instance object -- app(similar to the VM in Vue2 before, but lighter)
const app = createApp(App)
console.log(app)
/ / a mount
app.mount('#app')

Copy the code

So what’s the app here? Let’s export it to the console

App.vue

Let’s look at the components

There is no root tag in the template tag

<template>
	<! Template structures in Vue3 components can have no root tag.
	<img alt="Vue logo" src="./assets/logo.png">
	<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>
Copy the code

Next, we will formally learn the content of Vue3

Fourth, Composition API

The official translation is the composite API

The official document: v3.cn.vuejs.org/guide/compo…

In Vue2, we use the Options API, the configuration item API, we create a Vue instance, and then pass in a configuration object, in which to write data, methods, watch, etc., while Vue3 proposes a new Composition API, Instead of creating a Vue instance directly, we create an app and import the required API as needed to use it…

Sections 1 and 2 can be skipped first, and it will be better to come back after reading this chapter to see the comparison picture

1. Problems with the Options API

Using the traditional Options API, if a requirement is added or modified, it needs to be modified in Data, Methods, and computed.

2.Com Position API advantages

We can organize our code and functions more elegantly. Keep the code of related functions organized.

Don’t panic, learn the following content, and then come back to see you understand ~

3. Common Composition apis

① The preludesetup

  1. Understanding: a new configuration item in Vue3.0 with a value of a function.
  2. setupIs that allComposition API“A stage for performance”.
  3. Components used in:data,methodsAnd so on, all should be configured insetupIn the.
  4. setupThe function returns two values:
    1. If an object is returned, the attributes and methods in the object can be used directly in the template. (Focus!)
    2. If a render function is returned: then you can customize the render content. (Not often used)
<template>
  <h1>Information about the blogger</h1>
  <h2>Name: {{name}}</h2>
  <h2>Age: {{age}}</h2>
  <h2>Gender: {{gender}}</h2>
  <button @click="sayInfo">According to the information</button>
</template>

<script>
// import {h} from 'vue'
export default {
  name: "App".// This is just a setup test, leaving reactive issues aside for now.
  setup(){
    / / data
    let name = "YK bacteria"
    let age = 18
    let gender = "Male"

    / / method
    function sayInfo(){
      alert(Hi `${name}You are too good)}return {
      name,age, gender,sayInfo
    }
    // return ()=> h('h1','YK ')}};</script>
Copy the code

If it returns a render function

That you are intemplateThe page renders the contents of the h function you wrote

  1. Note:
    1. As far as possibleDon’tThis parameter is used with the Vue2. X configuration
      • Vue2. X configuration (Data, Methos, computed…) You can access properties and methods in setup.
      • But you can’t access the Vue2. X configuration (data, methos, computed…) in SETUP. .
      • If there’s a duplicate name,setupIs preferred.
    2. setupIt can’t be aasyncFunction, because the return value is no longer an object, butpromiseThe template does not see the properties in the return object. You can also return a Promise instance later, but it needs to work with Suspense and asynchronous components.

The above data is not responsive data, we modify it, the page does not update, how to define responsive data?

2.reffunction

  • Function: Define a reactive data
  • Grammar:const xxx = ref(initValue)
    • Create a reference object (ref object) that contains responsive data.
    • Operating data in JS:xxx.value
    • Read data from templates: no need.valueDirectly:<div>{{xxx}}</div>
  • Remark:
    • The data received can be either a primitive type or an object type.
    • Basic types of data: Reactive is still dependentObject.defineProperty()thegetwithsetThe finished.
    • Object type data: internal“Help”A new function in Vue3.0 —reactiveFunction.
<template>
  <h1>Information about the blogger</h1>
  <h2>Name: {{name}}</h2>
  <h2>Age: {{age}}</h2>
  <h2>Job: {{job. Type}}</h2>
  <h2>Salary: {{job. Salary}}</h2>
  <button @click="sayInfo">According to the information</button>
  <button @click="changeInfo">Modify the information</button>
</template>

<script>
import { ref } from "vue";
export default {
  name: "App".setup() {
    / / data
    let name = ref("YK bacteria");
    let age = ref(18);
    let job = ref({
      type: "Front End Engineer".salary: "30K"});/ / method
    function sayInfo() {
      alert(Hi `${name.value}You're amazing, salary${job.value.salary}So high `);
    }
    function changeInfo() {
      name.value = "YK bacteria 30 years later.";
      age.value = 48;
      job.value.type = "Engineer";
      job.value.salary = "200K";
    }
    return{ name, age, job, sayInfo, changeInfo, }; }};</script>
Copy the code

3.reactivefunction

  • What it does: Define aObject typeReactive data (basic type do not use it, use itrefFunction)
  • Grammar:Const proxy = Reactive (source object)Receives an object (or array) and returns oneProxy object (ProxyInstance object, for shortproxyObject)
  • reactiveResponsive data is defined as “deep”.
  • Internal ES6 basedProxyImplementation, through the proxy object to operate on the internal data of the source object.
<template>
  <h1>Information about the blogger</h1>
  <h2>Name: {{yk.name}}</h2>
  <h2>Age: {{yk.age}}</h2>
  <h2>{{yk.job.type}}</h2>
  <h2>Salary: {{yk.job. Salary}}</h2>
  <h2>{{yk.hobby}}</h2>
  <h3>{{yk.job.a.b.c}}</h3>
  <button @click="changeInfo">Modify the information</button>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "App".setup() {
    / / data
    let yk = reactive({
      name: "YK bacteria".age: 18.hobby: ["Blog"."Learning"."Reading"].job: {
        type: "Front End Engineer".salary: "30K".a: {
          b: {
            c: Awesome!,},},},});/ / method
    function changeInfo() {
      yk.name = "YK bacteria 30 years later.";
      yk.age = 48;
      yk.job.type = "Engineer";
      yk.job.salary = "200K";
      yk.a.b.c = 888;
      // Response can be triggered by modifying the array subscript directly
      yk.hobby[0] = "Write a novel.";
    }
    return{ yk, changeInfo, }; }};</script>
Copy the code

④ Responsivity principle in Vue3.0

The response of Vue2. X

  • Realize the principle of

    • Object types: Intercepts reading and modifying attributes via Object.defineProperty() (data hijacking).

    • Array types: Interception is implemented by overriding a series of methods that update an array. The array change method is wrapped.

      Object.defineProperty(data, 'count', {
          get () {}, 
          set () {}
      })
      Copy the code
  • There is a problem

    • The interface will not be updated when adding or deleting properties.
    • Modify the array directly by subscript, the interface does not automatically update.
  • The solution

    • useVue.set,Vue.deleteorvm.$set,vm.$deleteThese apis

Simulation Vue2 to achieve the response

/ / the source data
let person = {
	name:'Joe'.age:18
}
// Simulate Vue2 to implement responsivity
let p = {}
Object.defineProperty(p,'name', {configurable:true.get(){ // called when someone reads name
		return person.name
	},
	set(value){ // called when someone modifies name
		console.log('Someone changed the name property, I found it, I'm going to update the interface! ')
		person.name = value
	}
})
Object.defineProperty(p,'age', {get(){ // called when someone reads age
		return person.age
	},
	set(value){ // called when someone changes age
		console.log('Someone changed the age property, I found it, I'm going to update the interface! ')
		person.age = value
	}
})
Copy the code

Responsiveness of Vue3.0

In the example above, we saw that arrays can be modified by subscript. Let’s test how well adding and removing attributes work in Vue3

<template>
  <h1>Information about the blogger</h1>
  <h2>Name: {{yk.name}}</h2>
  <h2 v-show="yk.age">Age: {{yk.age}}</h2>
  <h2 v-show="yk.gender">Gender: {{yk.gender}}</h2>
  <h2>{{yk.job.type}}</h2>
  <h2>Salary: {{yk.job. Salary}}</h2>
  <h2>{{yk.hobby}}</h2>
  <h3>{{yk.job.a.b.c}}</h3>
  <button @click="changeInfo">Modify the information</button>
  <button @click="addGender">Increase the gender</button>
  <button @click="deleteAge">Delete the age</button>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "App".setup() {
    / / data
    let yk = reactive({
      name: "YK bacteria".age: 18.hobby: ["Blog"."Learning"."Reading"].job: {
        type: "Front End Engineer".salary: "30K".a: {
          b: {
            c: Awesome!,},},},});/ / method
    function changeInfo() {
      yk.name = "YK bacteria 30 years later.";
      yk.age = 48;
      yk.job.type = "Engineer";
      yk.job.salary = "200K";
      yk.a.b.c = 888;
      yk.hobby[0] = "Write a novel.";
    }

    function addGender() {
      yk.gender = "Male";
    }
    function deleteAge() {
      delete yk.age;
    }

    return{ yk, changeInfo, addGender, deleteAge, }; }};</script>
Copy the code

  • Realize the principle of
    • throughProxy(proxy) : Intercepts the change of any property in the object, including: reading and writing of property value, adding property, deleting property, etc.
    • throughReflect(Reflection) : Operates on the properties of the source object.
    • Described in the MDN documentationProxywithReflect:
      • Proxy:developer.mozilla.org/zh-CN/docs/…

      • Reflect:developer.mozilla.org/zh-CN/docs/…

See this blog post about agents and reflection

Vue3 simulation to achieve the response

let person = {
	name:'YK bacteria'.age:18
}

const p = new Proxy(person,{
	// called when someone reads a property of p
	get(target,propName){
		console.log('Someone read p's${propName}Attribute `)
       // return target[propName]
		return Reflect.get(target,propName)
	},
	// When someone modifies a property of p or appends a property to p
	set(target,propName,value){
		console.log('Someone has altered p's${propName}Properties, I'm going to update the interface! `)
        // target[propName] = value
		return Reflect.set(target,propName,value)
	},
	// called when someone removes an attribute of p
	deleteProperty(target,propName){
		console.log('Someone deleted the${propName}Properties, I'm going to update the interface! `)
		// return delete target[propName]
       return Reflect.deleteProperty(target,propName)
	}
})
Copy the code

5.reactivecontrastref

  • fromdefineData Angle comparison
    • refUsed to define:Basic type data.
    • reactiveUsed to define:Object (or array) type data.
    • Remark:refIt can also be used to defineObject (or array) type dataIt will automatically pass through internallyreactivetoProxy objects.

  • fromThe principle ofPoint of comparison
    • refthroughObject.defineProperty()thegetwithsetTo achieve responsiveness (data hijacking).
    • reactiveThrough the use ofProxyTo achieve responsiveness (data hijacking), and throughReflectoperationThe source objectInternal data.

  • fromusePoint of comparison
    • refDefined data: operational dataNeed to be.valueTo read data directly from the templateDon’t need.value.
    • Data defined by Reactive: Operating data and reading data:All don’t need.value.

6.setupTwo points to note

  • The timing of setup execution

    • inbeforeCreateOnce before,thisisundefined.
  • The parameters of the setup

Print the two parameters (props, context) received by Setup on the console as follows

  • propsThe: value is an object containing: properties that are passed from outside the component and declared to be received inside the component.
  • context: context object
    • attrsThe: value is an object containing: properties passed from outside the component, but not declared in the props configuration, equivalent tothis.$attrs.
    • slots: Indicates the received slot contentthis.$slots.
    • emit: a function that distributes custom events, equivalent tothis.$emit.

Test the

App component and HelloWorld component

The parent component passes property parameters to the child component
<template>
  <h1>Information about the blogger</h1>
  <HelloWorld msg="Hello?" school="ABC"></HelloWorld>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
  name: "App".components: { HelloWorld },
};
</script>

<style></style>
Copy the code
<template>
  <h2>Name: {{yk.name}}</h2>
</template>

<script>
import { reactive } from "@vue/reactivity";
export default {
  name: "HelloWorld".props: ['msg'].// Do not write a warning
  setup(props, context) {
    let yk = reactive({
      name: "YK bacteria"});console.log('props-----',props);
    console.log()
    console.log('context.attrs-----', context.attrs)
    return{ yk }; }};</script>
Copy the code

Custom events
<template>
  <h1>Information about the blogger</h1>
  <HelloWorld @hello="showHelloMsg"></HelloWorld>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
  name: "App".setup() {
    function showHelloMsg(value) {
      alert('Hello, you triggered the Hello event and the argument I received was:${value}! `);
    }
    return { showHelloMsg };
  },
  components: { HelloWorld },
};
</script>
Copy the code
<template>
  <h2>Name: {{yk.name}}</h2>
  <button @click="test">Test to trigger the Hello event of the HelloWorld component</button>
</template>

<script>
import { reactive } from "@vue/reactivity";
export default {
  name: "HelloWorld".emits: ["hello"].// Do not write to execute, but will report a warning
  setup(props, context) {
    let yk = reactive({
      name: "YK bacteria"});function test() {
      context.emit("hello"."** Information for child components **");
    }
    return{ yk,test }; }};</script>
Copy the code

If the emits option is not used, a warning is reported

slot

The default slot

<template>
  <h1>Information about the blogger</h1>
  <HelloWorld>
    <span>Hello, YK bacteria</span>
  </HelloWorld>
</template>
Copy the code
<template>
  <h2>Name: {{yk.name}}</h2>
  <slot></slot>
</template>
Copy the code

A named slot

<template>
  <h1>Information about the blogger</h1>
  <HelloWorld>
	<template v-slot:ykMsg>
		<span>Hello, YK bacteria</span>
	</template>
  </HelloWorld>
</template>
Copy the code
<template>
  <h2>Name: {{yk.name}}</h2>
  <slot name="ykMsg"></slot>
</template>
Copy the code

⑦ Compute properties and monitoring

computedfunction

  • This function is consistent with computed configuration in vue2. x

  • writing

import {computed} from 'vue'

setup(){...// Calculate attributes - short for
    let fullName = computed(() = >{
        return person.firstName + The '-' + person.lastName
    })
    // Calculate attributes -- complete
    let fullName = computed({
        get(){
            return person.firstName + The '-' + person.lastName
        },
        set(value){
            const nameArr = value.split(The '-')
            person.firstName = nameArr[0]
            person.lastName = nameArr[1]}})}Copy the code

watchfunction

  • The function is the same as that configured on Watch in vue2. x

  • Two little pits:

    • monitoringreactiveWhen defining reactive data:oldValueUnable to get, force deep monitoring on (deepConfiguration failure).
    • monitoringreactiveWhen an attribute is defined in reactive data:deepThe configuration is valid.

Case 1: Monitor reactive data defined by ref

// Monitor reactive data defined by ref
watch(sum,(newValue,oldValue) = >{
	console.log('Sum changes',newValue,oldValue)
},{immediate:true})
Copy the code

If you define an object with ref

watch(person.value,(newValue,oldValue) = >{
	console.log('Person has changed',newValue,oldValue)
}) 
Copy the code

Or it

watch(person,(newValue,oldValue) = >{
	console.log('Person has changed',newValue,oldValue)
},{deep: true}) 
Copy the code

Case 2: Monitoring reactive data defined by multiple Refs

// Monitor reactive data defined by multiple refs
watch([sum,msg],(newValue,oldValue) = >{
	console.log('Sum or MSG changes',newValue,oldValue)
}) 
Copy the code

Case 3: Monitoring reactive data defined by Reactive

  • If watch monitors reactive data, oldValue cannot be obtained correctly.
  • If watch monitors reactive data, in-depth monitoring is forcibly enabled
watch(person,(newValue,oldValue) = >{
	console.log('Person has changed',newValue,oldValue)
},{immediate:true.deep:false}) // The deep configuration here no longer works
Copy the code

Case 4: Monitor an attribute in reactive data defined by Reactive

// Monitor a property in reactive data defined by Reactive
watch(() = >person.job,(newValue,oldValue) = >{
	console.log('Person's job has changed',newValue,oldValue)
},{immediate:true.deep:true}) 
Copy the code

Case 5: Monitor some properties in reactive data defined by Reactive

// Case 5: Monitor some properties in reactive data defined by Reactive
watch([() = >person.job,() = >person.name],(newValue,oldValue) = >{
	console.log('Person's job has changed',newValue,oldValue)
},{immediate:true.deep:true})
Copy the code

A special case

// Special circumstances
watch(() = >person.job,(newValue,oldValue) = >{
    console.log('Person's job has changed',newValue,oldValue)
},{deep:true}) The deep configuration is valid because you are monitoring a property in an object defined by Reactive
Copy the code

watchEffectfunction

  • The watch routine is to specify both the monitoring properties and the monitoring callbacks.

  • The watchEffect formula is this: you don’t have to specify which property to watch, just watch which property is used in the monitored callback.

  • WatchEffect is a bit like computed:

    • butcomputedWe care about the calculated value (the return value of the callback function), so we must write the return value.
    • whilewatchEffectYou focus more on the procedure (the body of the callback function), so you don’t write the return value.
// Whenever the data used in the watchEffect callback changes, the callback is reexecuted.
watchEffect(() = >{
    const x1 = sum.value
    const x2 = person.age
    console.log('watchEffect configured callback executes')})Copy the code

⑧ Life cycle

  • Vue3.0 can continue to use lifecycle hooks from Vue2.x, but two have been renamed:
    • beforeDestroyrenamedbeforeUnmount
    • destroyedrenamedunmounted

Lifecycle hooks can be used either directly as configured items or as a composite API, with as much uniformity as possible

Generally, hooks in the composite API are executed before hooks in configuration items, and the name of the composite API hook has been changed

  • Vue3.0 also provides lifecycle hooks in the form of Composition API, which correspond to Vue2. X hooks as follows:
    • beforeCreate= = = >setup()
    • created= = = = = = = >setup()
    • beforeMount= = = >onBeforeMount
    • mounted= = = = = = = >onMounted
    • beforeUpdate= = = >onBeforeUpdate
    • updated= = = = = = = >onUpdated
    • beforeUnmount= = >onBeforeUnmount
    • unmounted= = = = = >onUnmounted

Pet-name ruby customhookFunction (emphasis)

  • What is a hook? This is essentially a function that encapsulates the Composition API used in setup functions.

  • Similar to mixins in vue2. X.

  • Advantages of custom hooks: Reusing code makes the logic in setup much clearer and easier to understand.

Create a hooks folder where you will create the file usepoint.js

import { reactive, onMounted, onBeforeUnmount } from "vue";
export default function() {
  // Implement mouse "dot" related data
  let point = reactive({
    x: 0.y: 0});// Implement mouse "dot" related methods
  function savePoint(event) {
    point.x = event.pageX;
    point.y = event.pageY;
    console.log(event.pageX, event.pageY);
  }

  // Implement mouse "dotting" related lifecycle hooks
  onMounted(() = > {
    window.addEventListener("click", savePoint);
  });

  onBeforeUnmount(() = > {
    window.removeEventListener("click", savePoint);
  });

  return point;
}
Copy the code

Used in component classes

<template>
	<h2>I'm the HelloWorld component</h2>
	<h2>X: {{point.x}}, y: {{point.y}}</h2>
</template>

<script>
	import usePoint from '.. /hooks/usePoint'
	export default {
		name:'HelloWorld'.setup(){
			const point = usePoint()
			return {point}
		}
	}
</script>
Copy the code

attendingtoRef

  • Creates a ref object whose value points to an attribute in another object.

  • Const name = toRef(person,’name’)

  • Application: When an attribute in a reactive object is individually provided for external use.

  • Extension: toRefs has the same functionality as toRef, but can batch create multiple REF objects, syntax: toRefs(person)

<template>
	<h4>{{person}}</h4>
	<h2>Name: {{name}}</h2>
	<h2>Age: {{age}}</h2>
	<h2>Salary: {{job. J1. Salary}} K</h2>
	<button @click="name+='~'">Modify the name</button>
	<button @click="age++">Growth of age</button>
	<button @click="job.j1.salary++">Pay rise</button>
</template>

<script>
	import {ref,reactive,toRef,toRefs} from 'vue'
	export default {
		name: 'Demo'.setup(){
			/ / data
			let person = reactive({
				name:'Joe'.age:18.job: {j1: {salary:20}}})// const name1 = person.name
			// console.log('%%%',name1)

			// const name2 = toRef(person,'name')
			// console.log('####',name2)

			const x = toRefs(person)
			console.log('* * * * * *',x)

			return {
				person,
				// name:toRef(person,'name'),
				// age:toRef(person,'age'),
				// salary:toRef(person.job.j1,'salary'),. toRefs(person) } } }</script>
Copy the code

Other Composition apis

1. shallowReactiveshallowRef

  • ShallowReactive: Handles only the responsivity (shallow responsivity) of the outermost attributes of the object.

  • ShallowRef: Only primitive data type responsivity is handled, not object responsivity.

  • When to use it?

    • If you have an object data, the structure is deep, but changes only when the outer properties change ===>shallowReactive.
    • If you have an object data, subsequent functions do not modify properties in that object, but instead generate new objects to replace ===>.shallowRef.

2. readonlyshallowReadonly

  • readonly: Makes reactive data read-only (deep read – only).
  • shallowReadonly: Makes reactive data read-only (shallow read-only).
  • Application scenario: Data is not modified.

3. toRawmarkRaw

  • toRaw

    • Role: will a byreactiveThe generatedResponsive objecttoOrdinary objects.
    • Usage scenario: Used to read a common object corresponding to a responsive object. All operations on this common object do not cause page updates.
  • markRaw

    • Function: Marks an object so that it will never be a reactive object again.
    • Application Scenarios:
      1. Some values should not be set to reactive, such as complex third-party libraries.
      2. Skipping reactive transformations can improve performance when rendering large lists with immutable data sources.

4. customRef

  • What it does: Creates a custom REF with explicit control over its dependency trace and update trigger.

  • Achieve anti-shake effect

<template>
  <input type="text" v-model="keyWord" />
  <h3>{{ keyWord }}</h3>
</template>

<script>
import { customRef } from "vue";
export default {
  name: "App".setup() {
    // Create a custom ref named myRef
    function myRef(value, delay) {
      let timer;
      return customRef((track, trigger) = > {
        return {
          get() {
            console.log('Someone is reading data from myRef, and I'm putting${value}Give him a `);
            track(); // Tell Vue to track value changes (check with GET in advance to make sure the value is useful)
            return value;
          },
          set(newValue) {
            console.log('Someone changed myRef to:${newValue}`);
            clearTimeout(timer);
            timer = setTimeout(() = > {
              value = newValue;
              trigger(); // Tell Vue to reparse the template}, delay); }}; }); }// let keyWord = ref('hello') // use Vue supplied ref
    let keyWord = myRef("hello".500); // Use programmer-defined ref

    return{ keyWord }; }};</script>
Copy the code

5. provideinject

  • Function: Implements communication between ancestor and descendant components

  • Formula: The parent component has a provide option to provide data, and the descendant component has an Inject option to start using that data

  • Specific writing:

Ancestor components:

setup(){...let car = reactive({name:'Mercedes'.price:'400000'})
    provide('car',car) // Pass data to its descendant components. }Copy the code

In descendant components:

setup(props,context){...const car = inject('car') // Get the ancestor data
    return {car}
	......
}
Copy the code

6. Judgment of responsive data

  • isRef: Checks whether a value is onerefobject
  • isReactive: Checks whether an object is created byreactiveCreate a responsive proxy
  • isReadonly: Checks whether an object is created byreadonlyThe read-only agent created
  • isProxy: Checks whether an object is created byreactiveorreadonlyMethod to create an agent

That’s about the Composition API, go back and look at the GIF and Vue3 smells good!

New components

1. Fragment

  • In Vue2: Components must have a root tag
  • In Vue3: Components can have no root tag and internally contain multiple tags in oneFragmentVirtual element
  • Benefits: Reduced label hierarchy and memory footprint

2. Teleport

  • What is theTeleport? –TeleportIt’s the kind of thing that gets usComponent HTML structureThe technique of moving to a specified position.
<teleport to="Move position">
	<div v-if="isShow" class="mask">
		<div class="dialog">
			<h3>I'm a popover</h3>
			<button @click="isShow = false">Close Windows</button>
		</div>
	</div>
</teleport>
Copy the code

Take a popover component as an example

Let’s make a nested box, and then in the innermost box we’re going to pop over

App

<template>
  <div class="app">
    <h3>I'm an App component</h3>
    <Child />
  </div>
</template>

<script>
import Child from "./components/Child";
export default {
  name: "App".components: { Child },
};
</script>

<style>
.app {
  background-color: gray;
  padding: 10px;
}
</style>

Copy the code

Child

<template>
  <div class="child">
    <h3>I am the Child component</h3>
    <Son />
  </div>
</template>

<script>
import Son from "./Son";
export default {
  name: "Child".components: { Son },
};
</script>

<style>
.child {
  background-color: skyblue;
  padding: 10px;
}
</style>

Copy the code

Son

<template>
  <div class="son">
    <h3>I'm Son component</h3>
    <Dialog />
  </div>
</template>

<script>
import Dialog from "./Dialog.vue";
export default {
  name: "Son".components: { Dialog },
};
</script>

<style>
.son {
  position: relative;
  background-color: orange;
  padding: 10px;
}
</style>

Copy the code

Dialog

<template>
  <div>
    <button @click="isShow = true">Click on me to pop a window</button>
    <div v-if="isShow" class="mask">
      <div class="dialog">
        <h3>I'm a popover</h3>
        <h4>Some content</h4>
        <h4>Some content</h4>
        <h4>Some content</h4>
        <button @click="isShow = false">Close Windows</button>
      </div>
    </div>
  </div>
</template>

<script>
import { ref } from "vue";
export default {
  name: "Dialog".setup() {
    let isShow = ref(false);
    return{ isShow }; }};</script>

<style>
.mask {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(0.0.0.0.5);
}
.dialog {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  width: 300px;
  height: 300px;
  background-color: green;
}
</style>

Copy the code

I deliberately added positioning to the innermost box, because the relative positioning will locate the nearest outer positioning box, so the effect is like this, we want this popover to be presented under the body

We add a teleport tag to the Dialog component

<template>
  <div>
    <button @click="isShow = true">Click on me to pop a window</button>
    <teleport to="body">
    <div v-if="isShow" class="mask">
      <div class="dialog">
        <h3>I'm a popover</h3>
        <h4>Some content</h4>
        <h4>Some content</h4>
        <h4>Some content</h4>
        <button @click="isShow = false">Close Windows</button>
      </div>
    </div>
    </teleport>
  </div>
</template>
Copy the code

That’s it

3. Suspense

  • Render some extra content while waiting for asynchronous components to make the application a better user experience

  • Use steps:

    • Asynchronously importing components
import {defineAsyncComponent} from 'vue'
const Child = defineAsyncComponent(() = >import('./components/Child.vue'))
Copy the code

Wrap components in Suspense and configure default and fallback

<template>
	<div class="app">
		<h3>I'm an App component</h3>
		<Suspense>
			<template v-slot:default>
				<Child/>
			</template>
			<template v-slot:fallback>
				<h3>Loading in...</h3>
			</template>
		</Suspense>
	</div>
</template>
Copy the code

Default: is what the component should display

Fallback: a component that is not fully loaded “fallback”

Seven, other

1. Global API transfer

  • Vue 2.x has a number of global apis and configurations.
    • For example, register global components, register global directives, etc.
// Register the global component
Vue.component('MyButton', {
  data: () = > ({
    count: 0
  }),
  template: '<button @click="count++">Clicked {{ count }} times.</button>'
})

// Register the global directive
Vue.directive('focus', {
  inserted: el= > el.focus()
}
Copy the code

Changes to these apis have been made in Vue3.0:

  • Adjust the global API, i.e. Vue.xxx, to the application instance (app)

    2. X global API (Vue) 3.x instance API (app)
    Vue.config.xxxx app.config.xxxx
    Vue.config.productionTip remove
    Vue.component app.component
    Vue.directive app.directive
    Vue.mixin app.mixin
    Vue.use app.use
    Vue.prototype app.config.globalProperties

2. Other changes

1.dataOptions should always be declared as a function

② Change the name of the transition class

Vue2. X

.v-enter..v-leave-to {
  opacity: 0;
}
.v-leave..v-enter-to {
  opacity: 1;
}
Copy the code

Vue3. X

.v-enter-from..v-leave-to {
  opacity: 0;
}

.v-leave-from..v-enter-to {
  opacity: 1;
}
Copy the code

(3) removekeyCodeAs av-onIs also no longer supportedconfig.keyCodes

(4) removev-on.nativeThe modifier

  • Bind events in the parent component
<my-component
  v-on:close="handleComponentEvent"
  v-on:click="handleNativeClickEvent"
/>
Copy the code

Declare custom events in child components

<script>
  export default {
    emits: ['close']
  }
</script>
Copy the code

⑤ Remove the filter

Filters While this may seem convenient, it requires a custom syntax to break the assumption that expressions in braces are “just JavaScript”, and there are not only learning costs, but implementation costs too! It is recommended to replace filters with method calls or computed properties.

reference

  • Vue3 official document v3.cn.vuejs.org/
  • Vite official document cn.vitejs.dev/
  • Vue-cli official document cli.vuejs.org/zh/
  • Yet in silicon valley Vue3 video www.bilibili.com/video/BV1Zy…