0. Vue3 upgrade

  • The performance of VU3 is improved
  • Source code upgrade:
    • Source TS rewrite, new TS support
    • Use Proxy instead of defineProperty to implement responsiveness
    • Rewrite the implementation of the virtual DOM
      • PatchFlagCompile the template, and mark the dynamic nodes into different types asTEXT PROPSTo facilitate diff algorithm to better distinguish between static and different types of dynamic nodes
      • hoistStaticStatic nodes improve the parent scope cache, multiple adjacent static nodes will be merged, space for time optimization strategy
      • cacheHandlerCache event
    • Tree-Shaking
      • At compile time, different apis are introduced for different situations
    • SSR optimization
      • Static nodes are output directly, bypassing VDOM. Dynamic nodes still need to be rendered dynamically
  • New features:
    • Composition API
    • New built-in components
      • Fragment
      • Teleport
      • Suspense
  • Global API changes
    • Put the global API, namely:Vue.xxxAdjust 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
  • Other changes:

    • Asynchronous components are requireddefineAsyncComponentCreation method, component V-Model, custom instruction,$attrscontainsclass&style, v-for and V-if priorities, transition class names changed
  • The data option should always be declared as a function, the option in the beforeDestroy life cycle is renamed to beforeUnmount, the option in the Destroyed life cycle is renamed to unmounted

  • Removed keyCode support as a V-on modifier and also removed config.keycodes support

  • Remove the $children, filter, V-on. native modifier (custom events are defined in the emits option, undefined events are native),.sync modifier, and so on

    • $on.$off$onceThe instance method has been removed
    • .
  • Better peripheral tools: Vite, Pinia

The latest Vue3.2 is a huge improvement on ref performance, and it is recommended to always use ref to define reactive, new script setup syntax

Component state-driven dynamic CSS values: p{color: v-bind(color)} where color is the defined variable

.

1.extends

Earlier I removed the public logic and used mixins supported by both Vue2 and Vue3

Another way to look like mixins is through the extends property

Extends is rarely used in development. Mixins are recommended in Vue2, while Composition APIS are recommended in Vue3

2. Disadvantages of the Options API

In Vue2, we write components through the Options API, and write corresponding functional modules in corresponding properties, such as data defining data, methods defining methods in methods, computed defining computing properties, monitoring property changes in watch, and life cycle hooks

However, there is a drawback to this. When we implement a function, the implementation code will be split into various properties. As the component logic increases, the fragmentation of the same function can lead to the code being difficult to read and understand

Defining and using data is split across components, resulting in the need to constantly scroll through the page to see the specific business logic

As components become more complex, fragmentation becomes more severe, and this is the problem that CompositionAPI addresses

Finally through hook function to define the data and the use of data logic together for processing, in order to achieve more readable, more convenient extension purposes!

Location where the 3.CompositionAPI was written

The place to write code using the CompositionAPI is the Setup function, which is equivalent to another option for the component

But this option can replace most of the previous options, such as methods, computed, watch, data, life cycle, and so on

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

4. Parameters and return values of the setup function

Setup function parameters

The setup function takes two arguments

  • The first argument: props, the properties passed by the parent component will be used in the props object, through the first argument of the function

  • The second argument: the context object, which we also call a SetupContext, contains three properties

    • Attrs: All non-prop attributes
    • Slots: Slots passed by the parent component (this is useful when returned as a render function, as described below)
    • Emit: Emit is used when we need to emit events within our component

    Note: Accessing this in the setup function does not find a component instance, because setup calls occur before data, computed, and methods are resolved, so it is not possible to use this.$emit and other related methods

The setup function returns a value

The return value:

  • If an object is returned, the attributes and methods in the object can be used directly in the template. (Focus! Equivalent to data and methods instead of options)
  • If a render function is returned: then you can customize the render content. (understand)

Note:

  • Do not mix 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 the same name exists, setup takes precedence

  • Setup cannot be an async function because the return value is no longer a return object, but a promise, and the 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 counter variable changed when we clicked button, but Vue had no template and didn’t track its updated interface

Get the component instance from the setup function

There’s no this in the CompositionAPI

You can get the current instance by using getCurrentInstance

Note that all apis used need to be imported from vUE

Import {onMounted, getCurrentInstance} from “vue”

5.Reactive API

If you want the data defined in setup to provide reactive properties, you can use functions of Reactive

Because when we use reactive functions to process our data, dependency collection happens when the data is used again

When the data changes, all the collected dependencies are used to perform corresponding reactive actions (such as updating the interface)

In fact, the data option that we write is also handed in internally to reactive functions to make it a reactive object

Reactive data defined by reactive functions is “deep” and is implemented internally by es6-based proxies, which operate on internal data of source objects through Proxy objects

6.Ref API

The Reactive API has restrictions on the type that can be passed in. It requires an object or array type to be passed in, and alerts you if you pass in a primitive data type

At this point Vue3 gives us another API: the Ref APIs, which returns a mutable reactive object that maintains the value of its internal value attribute as a reactive reference

Basic types of data: Responsivity is still done by object.defineProperty () get and set

Object type data: Internal “recourse” to a new function in Vue3.0 called Reactive

Shallow unpacking of ref

We can use ref to get elements or components, just define a REF object and bind it to the element or component’s REF attribute

7. ToRefs and toRef

ToRef converts an attribute in a reactive object toRef

Usage scenario: There is a reactive object data, but only one of the data is needed in the template

ToRefs can convert properties in objects returned by reactive toRefs

Usage scenario: You want to use multiple or all properties of a reactive object as reactive data

The use of toRef

The use of toRefs

8.computed

We can use a computed method in the setup function to write a computed property

Method 1: Receives a getter function and returns a constant ref object for the value returned by the getter function

Method 2: Receive an object with get and set and return a mutable (read-write) ref object

9. Watch and watchEffect

In the Composition API, you can use watchEffect and Watch to listen for reactive data

WatchEffect is a dependency that automatically collects reactive data, and can be used when we want to do something when we are listening for changes in reactive data

Watch needs to manually specify the data source to listen on

WatchEffect basic use

First, the functions passed in by watchEffect are executed immediately and dependencies are collected as they are executed

Second, the watchEffect function passed in is executed again only if the collected dependencies change

WatchEffect stops listening

We want to stop listening, at which point we can get the watchEffect return value function and call it

For example, age above, we want to stop listening when the number reaches 20

WatchEffect clears side effects

Clear side effects, such as when we execute a network request in the listener, but we stop the listener before the network request is reached, or when the listener listener executes again depending on the data change

Then the last network request should be cancelled, and we can remove the last side effect

When the function we passed to watchEffect is called back, we actually get one argument: onInvalidate

The callback passed in by the function is executed when the side effect is about to be reexecuted or the listener is stopped, and some cleanup is done in the callback

Execution timing of watchEffect

By default, components are updated before side effects are executed

The result will be printed twice:

  1. When our setup function executes, it immediately executes the side effect function passed in. The DOM is not mounted, so it prints null
  2. When the DOM is mounted, the title ref object is assigned a new value, and the side effect function is executed again, printing out the corresponding element

We can configure the second watchEffect parameter flush to adjust the timing of execution:

  • Default is pre, DOM mount or update before execution
  • Post: Executes after the DOM is mounted or updated and is used when template elements are needed
  • Sync, which forces effects to always fire synchronously. Not recommended

Basic use of Watch

Watch needs to listen for specific data sources and perform side effects in callback functions

It is lazy by default and only performs callbacks when the source being listened to changes

In comparison to the watchEffect, Watch allows us

  • Lazy execution side effects (no direct execution the first time)
  • Be more specific about which states trigger listener execution when they change
  • Access values before and after listening state changes

Listening to a single data source

Listening to multiple data sources

Watch the options

  • Deep listening, set deep to true
  • Run the command immediately and set immediate to true

10. Lifecycle hooks

Setup has been used above in place of data, methods, computed, watch, and so on

How do we use life cycle functions in setup

Lifecycle hooks can be registered using the directly imported onX function:

  • The mapping between vue2. x and vue2. x hooks is as follows:
    • beforeCreate= = = >setup()
    • created= = = = = = = >setup()
    • beforeMount= = = >onBeforeMount
    • mounted= = = = = = = >onMounted
    • beforeUpdate= = = >onBeforeUpdate
    • updated= = = = = = = >onUpdated
    • beforeUnmount= = >onBeforeUnmount
    • unmounted= = = = = >onUnmounted

11. Other CompositionAPI

1. With shallowReadonly readonly

Readonly Makes responsive data read-only (deep read-only)

However, the original object of the readOnly wrapper is allowed to be modified. Try not to change the value of the ReadOnly wrapper

The setter method of the read-only proxy that is essentially the native object returned by ReadOnly has been hijacked

ShallowReadonly: To make responsive data read-only (shallow read-only)

They commonly pass in parameters

  1. Ordinary objects
  2. Ref object
  3. Reactive object

2. ShallowReactive and shallowRef

  • 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 the properties in that object, but instead generate a new object to replace ===> shallowRef.

3. ToRaw markRaw

  • 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. Dojo.provide and inject

  • Function: Implements communication between ancestor and descendant components
  • The parent component has oneprovideOption to provide data, descendant component has oneinjectOptions to start using the data, provide responsiveness, and use ref and Reactive when providing values
  • Provide can be passed two parameters: 1. the name of the provided property and 2. the value of the provided property
  • Inject can also be passed two parameters: 1.provide the provided attribute name, 2. The default value
  • Specific writing:

If you want to modify a value, it is best to provide a method to the underlying component that is called and the data is modified at the location provided

5.customRef

Create a custom REF with explicit control over its dependency trace and update trigger

It requires a factory function that takes track and trigger functions as arguments

And it should return an object with get and set

Anti-shake effect for bidirectional binding properties:

6. Judgment of responsive data

IsRef: Checks whether a value is a ref object

IsReactive: Checks whether an object is a reactive agent created by Reactive. It also returns true if the agent is created by ReadOnly and wraps around another agent created by Reactive

IsReadonly: Checks whether an object is a read-only proxy created by readOnly

IsProxy: Checks whether an object is a proxy created by reactive or readonly methods

7. Ref other apis

Unref: gets the value in a ref reference, returns the internal value if the argument isRef, otherwise returns the argument itself, which is val = isRef(val)? Val. value: The syntactic sugar function of val

TriggerRef: Manually triggers side effects associated with shallowRef

12. Custom Hook functions

A hook is essentially a function that encapsulates the Composition API used in the Setup function

Similar to the mixin in vue2. X, it can better extract logic and reuse code

Package useCounter to pull out calculator logic:

Encapsulate useTitle. Modify title.

Encapsulate useScrollPosition to listen for the scrolling position of the interface

Encapsulate useMousePosition to listen for mouse position

Encapsulates useLocalStorage to store and obtain data

Set up unified exits for these hooks (not required)

Required components use:

< the template > < div > < h2 > current count: {{counter}} < / h2 > < h2 > count * 2: {{ doubleCounter }}</h2> <button @click="increment">+1</button> <button @click="decrement">-1</button> <h2>{{ data Data </button> <p class="content"></p> <div class="scroll"> <div class="scroll-x">scrollX: {{ scrollX }}</div> <div class="scroll-y">scrollY: {{ scrollY }}</div> </div> <div class="mouse"> <div class="mouse-x">mouseX: {{ mouseX }}</div> <div class="mouse-y">mouseY: {{ mouseY }}</div> </div> </div> </template> <script> import { ref, computed } from "vue"; import { useCounter, useLocalStorage, useMousePosition, useScrollPosition, useTitle } from "./hooks"; export default { setup() { // counter const { counter, doubleCounter, increment, decrement } = useCounter(); Const titleRef = useTitle("coderwhy"); // modify title const titleRef = useTitle("coderwhy"); setTimeout(() => { titleRef.value = "kobe"; }, 3000); Const {scrollX, scrollY} = useScrollPosition(); // Const {scrollX, scrollY} = useScrollPosition(); Const {mouseX, mouseY} = useMousePosition(); // localStorage const data = useLocalStorage("info"); const changeData = () => (data.value = "yunmu"); return { counter, doubleCounter, increment, decrement, scrollX, scrollY, mouseX, mouseY, data, changeData, }; }}; </script> <style scoped> .content { width: 3000px; height: 5000px; } .scroll { position: fixed; right: 30px; bottom: 30px; } .mouse { position: fixed; right: 30px; bottom: 80px; } </style>Copy the code