Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the principle of vue3.0 response function?

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article will explain in detail what the principle of vue3.0 response function is. The editor thinks it is very practical, so I share it for you as a reference. I hope you can get something after reading this article.

Foreword:

Vue3 rewrites the responsive system. Compared with Vue2, the bottom layer is implemented by Proxy object. During initialization, there is no need to traverse all the properties and then convert the properties to get and set through defineProperty. In addition, if there are multiple layers of properties nested, the properties at the next level will be processed recursively only when a property is accessed, so the performance of the responsive system in Vue3 is better than that of Vue2.

Next, we implement the core function (reactive/ref/toRefs/computed/effect/track/trigger) of Vue3 responsive system to learn the principle of responsive.

First, we use Proxy to implement the first function in the response, reactive.

1.reactive

Reactive receives a parameter, first of all to determine whether the parameter is an object, if not returned directly, reactive can only convert the object into a responsive object, which is different from ref.

Next, the interceptor object handler is created, in which intercept methods such as get,set,deleteProperty are hugged, and finally the Proxy object is created and returned.

/ / determine whether it is an object const isObject = val = > val! = = null & & typeof val = = 'object'//. If it is an object, call reactiveconst convert= target = > isObject (target)? Reactive (target): target// determines whether there is a key attribute const haOwnProperty = Object.prototype.hasOwnPropertyconst hasOwn = (target, key) = > haOwnProperty.call (target, key) export function reactive (target) {if (! isObject (target)) {/ / if it is not an object, return return target} const handler = {get (target, key) directly Receiver) {/ / Collection dependency const result = Reflect.get (target, key, receiver) / / Recursive processing return convert (result)}, set (target, key, value, receiver) {const oldValue = Reflect.get (target, key, receiver) let result = true if the attribute is an object / / you need to determine whether the new value passed in is equal to oldValue, and if not, overwrite the old value. And trigger update if (oldValue! = = value) {result = Reflect.set (target, key, value, receiver) / / trigger update.} / / the set method needs to return a Boolean value return result }, deleteProperty (target, key) {/ / first determine whether the current target has its own key attribute / / if there is a key attribute And delete the update to trigger const hasKey = hasOwn (target, key) const result = Reflect.deleteProperty (target, key) if (hasKey & & result) {/ / trigger update.} return result }} return new Proxy (target, handler)}

Now that the reactive function is finished, let's write the process of collecting dependencies.

In the process of dependency collection, three collections are created, namely targetMap,depsMap and dep.

Where targetMap is used to record the target object and dictionary he uses weakMap,key is the target object, the value of targetMap is depsMap, and the type is Map, where key is the attribute name of the target object, the value is a Set collection, and the elements stored in the collection are Effect functions. Because you can call the same Effect multiple times to access the same property in Effect, this property will collect multiple dependencies corresponding to multiple Effect functions.

An attribute can correspond to multiple Effect functions. When an update is triggered, you can find the corresponding Effect function through the attribute and execute it.

Let's implement the effect and track functions respectively.

The effect function takes a function as an argument, and we first specify a variable to store callback on the outside so that the track function can access the callback.

Let activeEffect = null;export function effect (callback) {activeEffect = callback; / / access responsive object properties, collection dependency callback (); / / dependency collection ends with null activeEffect = null;}

The track function takes two parameters, the target object and the property, and its internal target is stored in the targetMap. You need to define such a Map first.

Let targetMap = new WeakMap () export function track (target, key) {/ / determine whether if (! activeEffect) {return exists in activeEffect } / / correspondence between depsMap storage object and effect let depsMap = targetMap.get (target) / / if it does not exist, create a map to store in targetMap if (! depsMap) {targetMap.set (target, (depsMap = new Map ())} / / find the corresponding dep object let dep = depsMap.get (key) / / dep is a collection according to the attribute To store the effect function if (! dep) {/ / if it does not exist, create a new collection and add it to the depsMap depsMap.set (key, (dep = new Set ()} dep.add (activeEffect)}

Track is a function that relies on collection. It needs to be called in the get method of the reactive function.

Get (target, key, receiver) {/ / collect dependencies track (target, key) const result = Reflect.get (target, key, receiver) / / if the attribute is an object, it needs to recursively process return convert (result)}

In this way, the whole dependency collection is complete. Then the trigger update is implemented, and the corresponding function is trigger, which is the opposite of the process of track.

The trigger function takes two parameters, target and key.

Export function trigger (target, key) {const depsMap = targetMap.get (target) / / if not found, return if (! depsMap) {return;} const dep = depsMap.get (key) if (dep) {dep.forEach (effect = > {effect ()})}}

The trigger function is triggered in set and deleteProperty in the reactive function.

Set (target, key, value, receiver) {const oldValue = Reflect.get (target, key, receiver) let result = true; / / you need to determine whether the new value currently passed is equal to oldValue, if not, overwrite the old value, and trigger the update if (oldValue! = = value) {result = Reflect.set (target, key, value, receiver) / / trigger the update. The trigger (target, key)} / / set method needs to return a Boolean value return result;}, deleteProperty (target, key) {/ / first determine whether there is its own key attribute in the current target / / if there is a key attribute, and delete to trigger the update const hasKey = hasOwn (target, key) const result = Reflect.deleteProperty (target, key) if (hasKey & result) {/ / trigger the update. Trigger (target, key)} return result;} 2.ref

Ref receives a parameter that can be either the original value or an object. If the object is passed in and the object created by ref, it returns directly. If it is a normal object, call reactive to create a responsive object, otherwise create a responsive object with only the value attribute.

Export function ref (raw) {/ / determines whether raw is an object created by ref. If you directly return if (isObject (raw) & & raw.__v__isRef) {return raw} / / previously defined convert function, if the parameter is an object, call the reactive function to create a responsive let value = convert (raw). Const r = {_ _ v__isRef: true, get value () {track (r, 'value') return value} Set value (newValue) {/ / determine whether the new value and the old value are equal if (newValue! = = value) {raw = newValue value = convert (raw) / / trigger update trigger (r, 'value')}} return r} 3.toRefs

ToRefs receives the responsive object returned by the reactive function, or returns directly if it is not responsive. Convert all the properties of the incoming object into an object similar to that returned by ref and mount the quasi-replaced properties on a new object.

Export function toRefs (proxy) {/ / if it is an array to create an array of the same length, otherwise it returns an empty object const ret = proxy instanceof Array? New Array (proxy.length): {} for (const key in proxy) {ret [key] = toProxyRef (proxy, key)} return ret } function toProxyRef (proxy, key) {const r = {_ _ v__isRef: true, get value () {/ / this is already a responsive object, so there is no need to collect dependent return proxy [key]}, set value (newValue) {proxy [key] = newValue}} return r}

The role of toRefs is to make every attribute in reactive responsive. The reactive method creates a responsive object, but it is no longer used if the object returned by reactive is deconstructed

It is responsive, and the function of toRefs is to support that it will remain responsive after deconstruction.

4.computed

Then let's simulate the internal implementation of the computed function.

Computed needs to receive a function with a return value as a parameter, and the return value of this function is the value of the calculated property, which needs to listen for changes in the response data within the function, and finally return the result of the function execution.

Export function computed (getter) {const result = ref () effect (() = > (result.value = getter () return result}

The computed function listens for changes in responsive data within getter through effect, because when getter is executed in effect, the attributes accessing responsive data will collect dependencies, and when the data changes, the effect function will be re-executed to store the results of getter in result.

This is the end of the article on "what is the principle of vue3.0 responsive function". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report