当前位置:网站首页>Vue3 reactive database
Vue3 reactive database
2022-06-30 17:45:00 【twinkle||cll】
Please read the following code carefully , reflection vue3 How to make responsive data ?
let temp
// reactive Is to make an object a proxy
const counter = reactive({
num: 0 });
// effect The main responsibility is to start dependency collection , wait for get To complete the normal dependent storage
effect(() => (temp = counter.num));
// Trigger update
counter.num = 1;
Is there anyone here who wants to say , We are in daily development , Directly in
vueOn the template, there is arefAutomatically helped us with Turn on Rely on collection , When we call get Storage dependency . When things go out of whack, they will
stay vue In the source renderer.ts There is such a code snippet in
const mountComponent: MountComponentFn = (
initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized
) => {
// ... Omit others
// A method will be called here setupRenderEffect
setupRenderEffect(
instance,
initialVNode,
container,
anchor,
parentSuspense,
isSVG,
optimized
)
}
const setupRenderEffect: SetupRenderEffectFn = (
instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized
) => {
const componentUpdateFn = () => {
// Omit component update logic
}
// This passage means to create a ReactiveEffect To save each individual proxy,
// and effect The effect is the same
const effect = new ReactiveEffect(
componentUpdateFn,
() => queueJob(instance.update),
instance.scope // track it in component's effect scope
)
}
Sum up , We are
TemplatesUse inref,reactiveIs such as vue When rendering, it will put the whole component into ReactiveEffect Dependency collection in , Throw out arunMethod ,run Method is used to determine whether dependency collection is required , aboutrefPrepare to deal with ordinary data in another space
reactive
reactive Is used to turn an object into a proxy object ,proxy

function createReactiveObject(
target: Target,
baseHandlers: ProxyHandler<any>,
proxyMap: WeakMap<Target, any>) {
// The core is proxy
// The purpose is to listen to the user get perhaps set The action of
// If you hit it, just return directly
// Optimization points made with cache
const existingProxy = proxyMap.get(target);
if (existingProxy) {
return existingProxy;
}
const proxy = new Proxy(target, baseHandlers);
// Create a good proxy Save it ,
proxyMap.set(target, proxy);
return proxy;
}
effect
effect The collection dependency() function is used to turn on the collection dependency , return run function

export function effect<T = any>(
fn: () => T,
options?: ReactiveEffectOptions
): ReactiveEffectRunner {
const _effect = new ReactiveEffect(fn);
// Merge options
extend(_effect, options);
// When I come in, I execute the opening run Turn on dependency collection
_effect.run();
// hold _effect.run This method returns
// Let the user choose the time to call ( call fn)
const runner: any = _effect.run.bind(_effect);
runner.effect = _effect;
return runner;
}
// stay ReactiveEffect run The content of the function is to enable dependency collection
export class ReactiveEffect {
active = true;
deps = [];
public onStop?: () => void;
constructor(public fn, public scheduler?) {
console.log(" establish ReactiveEffect object ");
}
run() {
// function run When , Can be controlled Do you want to perform the next step of collecting dependencies
// For now , Just execute fn Then the collection dependency is executed by default
// Here we need to control
// Whether to collect dependent variables
// perform fn But do not collect dependencies
if (!this.active) {
return this.fn();
}
// perform fn Collection dependency
// You can start collecting dependencies
shouldTrack = true;
// When executing, give the global activeEffect assignment
// Use global attributes to get the current effect
activeEffect = this as any;
// Execute the fn
const result = this.fn();
// Reset
shouldTrack = false;
activeEffect = undefined;
return result;
}
}
baseHandlers
baseHandlers It's used to deal with proxy Inside get and set Of , When proxy call get and set Will trigger the corresponding function
get The operation flow is as follows :

set The operation flow is as follows :

export const mutableHandlers: ProxyHandler<object> = {
get:(isReadonly = false, shallow = false) {
return function get(target, key, receiver) {
// Get right target Of key Value
const res = Reflect.get(target, key, receiver);
// problem : Why readonly When you don't do dependency collection
// readonly Words , Can not be set Of , That can't be set It means that it will not trigger trigger
// So there is no need to collect dependencies
if (!isReadonly) {
// It's triggering get To collect dependencies
track(target, "get", key);
}
// All that is inside is object All the values are in reactive The parcel , Become a responsive object
// If you say this res Value is an object , So we need to get the res It also translates into reactive
if (isObject(res)) {
// res be equal to target[key]
return isReadonly ? readonly(res) : reactive(res);
}
return res;
};
},
// set Value to trigger
set:(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver);
// It's triggering set Trigger dependency when
trigger(target, "set", key);
return result;
};,
};
track
stay get When , Notification for dependency collection ,
During dependency collection , Cache incoming objects :

The cache dependency step here is :
- First step : When running
counter.numIt will triggerproxyOfgetMethod - The second step : There is a big picture
targetMapIt's aweakMapTo recordcouter This objectWhether there is , alsoweakMap Of keyyes couter This object , To be is to use , Create if it does not exist ,counterOfvalueAnotherMap, It recordscounter Inside keyandcounter Object's keyIt's one-to-one - The third step : stay
mapMedium judgementkey yes numWhether there is , To be is to use , If it doesn't exist, create aSetTo save the currentReactiveEffectobject ,ReactiveEffectObjects contain run Method wait trigger Trigger
export function track(target, type, key) {
if (!isTracking()) {
return;
}
// 1. Based on target Find the corresponding dep
// If it's the first time , So you need to initialize
let depsMap = targetMap.get(target);
if (!depsMap) {
// initialization depsMap The logic of
depsMap = new Map();
targetMap.set(target, depsMap);
}
let dep = depsMap.get(key);
if (!dep) {
dep = createDep();
depsMap.set(key, dep);
}
if (!dep.has(activeEffect)) {
dep.add(activeEffect);
(activeEffect as any).deps.push(dep);
}
}
trigger
When it comes to track Come on ,trigger What needs to be done will be much simpler
export function trigger(target, type, key) {
const depsMap = targetMap.get(target);
if (!depsMap) return;
// For the time being GET type
// get Type only needs to be taken out
const dep = depsMap.get(key);
// Omit other logic
// Trigger run function
for (const effect of dep) {
if (effect.scheduler) {
// scheduler You can let the user choose the timing of the call
// In this way, you can flexibly control the call
// stay runtime-core in , Is to use scheduler Implemented in the next ticker Logic called in
effect.scheduler();
} else {
// Trigger function
effect.run();
}
}
}
Realize it by yourself
Said so much , It is better to implement a simple responsive system by yourself

边栏推荐
- Fragmentary knowledge points of MySQL
- Course design for the end of the semester: product sales management system based on SSM
- EMQ 助力青岛研博建设智慧水务平台
- Hyper-V: enable SR-IOV in virtual network
- Building a basic buildreoot file system
- Map集合
- Acwing game 57
- Tubes响应性数据系统的设计与原理
- Cesium-1.72 learning (camera tracking)
- [零基础学IoT Pwn] 环境搭建
猜你喜欢

将 EMQX Cloud 数据通过公网桥接到 AWS IoT

Horizontal visual error effect JS special effect code

EMQ helps Qingdao Yanbo build a smart water platform

The new version of Shangding cloud | favorites function has been launched to meet personal use needs

Ningx 1.20.2

Nouvelle version de shangdingyun | la fonction favorite est en ligne pour répondre aux besoins d'utilisation personnelle

Servlet operation principle_ API details_ Advanced path of request response construction (servlet_2)

Radio and television 5g officially set sail, attracting attention on how to apply the golden band
![[200 opencv routines] 215 Drawing approximate ellipse based on polyline](/img/43/fd4245586071020e5aadb8857316c5.png)
[200 opencv routines] 215 Drawing approximate ellipse based on polyline

Hyper-v:在虚拟网络中启用 SR-IOV
随机推荐
Share 5 commonly used feature selection methods, and you must see them when you get started with machine learning!!!
Network: principle and practice of server network card group technology
美国PARKER派克传感器P8S-GRFLX
Servlet运行原理_API详解_请求响应构造进阶之路(Servlet_2)
美国穆格moog伺服阀D661-4577C
Implementation of graduation project management system based on SSM
如何写一个技术方案
New power of data analysis -- the first open source integrated real-time HTAP database in China was released by stonedb
水平视觉错误效果js特效代码
[C language] explain threads - start two threads
【C语言】详解线程 — 通过 “加锁” 解决并发程序引起的共享内存问题
【架构】1366- 如何画出一张优秀的架构图
Property or method “approval1“ is not defined on the instance but referenced during render
腾讯云的一场硬仗
Map collection
阿里云ECS导入本地,解决部署的问题
编译生成busybox文件系统
5G商用三年,未来创新何去何从?
4年工作经验,多线程间的5种通信方式都说不出来,你敢信?
Radio and television 5g officially set sail, attracting attention on how to apply the golden band