Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
Ò»ÕÅͼÀíÇå Vue 3.0 µÄÏìӦʽϵͳ
 
 
  1733  次浏览      33
 2021-2-26 
 
±à¼­ÍƼö:
±¾ÎÄÖØµã½²½âÁËÒ»¸ö»ù±¾µÄÀý×Ó£¬Í¨¹ý³õʼ»¯½×¶Î¡¢ÒÀÀµÊÕ¼¯½×¶Î¡¢ÏìÓ¦½×¶ÎÕ⼸¸ö·½ÃæÀ´½éÉÜÁË¡£
±¾ÎÄÀ´×ÔÓÚÍøÂç,ÓÉ»ðÁú¹ûÈí¼þAnna±à¼­ÍƼö¡£

ÕýÎÄ

Ëæ×Å Vue 3.0 Pre Alpha °æ±¾µÄ¹«²¼£¬ÎÒÃǵÃÒÔÒ»¿úÆäÔ´ÂëµÄʵÏÖ¡£Vue ×îÇÉÃîµÄÌØÐÔÖ®Ò»ÊÇÆäÏìӦʽϵͳ£¬¶øÎÒÃÇÒ²Äܹ»ÔÚ²Ö¿âµÄ packages/reactivity Ä£¿éÏÂÕÒµ½¶ÔÓ¦µÄʵÏÖ¡£

ËäȻԴÂëµÄ´úÂëÁ¿²»¶à£¬ÍøÉϵķÖÎöÎÄÕÂÒ²ÓÐÒ»¶Ñ£¬µ«ÊÇÒªÏëÇåÎúµØÀí½âÏìӦʽԭÀíµÄ¾ßÌåʵÏÖ¹ý³Ì£¬»¹ÊÇͦ·ÑÄÔ½îµÄÊÂÇé¡£¾­¹ýÒ»ÌìµÄÑо¿ºÍÕûÀí£¬ÎÒ°ÑÆäÏìӦʽϵͳµÄÔ­Àí×ܽá³ÉÁËÒ»ÕÅͼ£¬¶ø±¾ÎÄÒ²½«Î§ÈÆÕâÕÅͼȥ½²Êö¾ßÌåµÄʵÏÖ¹ý³Ì¡£

ÎÄÕÂÉæ¼°µ½µÄ´úÂëÎÒÒ²ÒѾ­ÉÏ´«µ½²Ö¿â£¬½áºÏ´úÂëÔĶÁ±¾ÎÄ»á¸üΪÁ÷³©Å¶£¡

Ò»¸ö»ù±¾µÄÀý×Ó

Vue 3.0 µÄÏìӦʽϵͳÊǶÀÁ¢µÄÄ£¿é£¬¿ÉÒÔÍêÈ«ÍÑÀë Vue ¶øÊ¹Óã¬ËùÒÔÎÒÃÇÔÚ clone ÁËÔ´ÂëÏÂÀ´ÒԺ󣬿ÉÒÔÖ±½ÓÔÚ packages/reactivity Ä£¿éϵ÷ÊÔ¡£

1.ÔÚÏîÄ¿¸ùĿ¼ÔËÐÐ yarn dev reactivity£¬È»ºó½øÈë packages/reactivity Ŀ¼ÕÒµ½²ú³öµÄ dist/reactivity.global.js Îļþ¡£

2.н¨Ò»¸ö index.html£¬Ð´ÈëÈçÏ´úÂ룺

<script src="./dist/reactivity.global.js"></script>
<script>
const { reactive, effect } = VueObserver


const origin = {
count: 0
}
const state = reactive(origin)


const fn = () => {
const count = state.count
console.log(`set count to ${count}`)
}
effect(fn)
</script>

 

1. ÔÚä¯ÀÀÆ÷´ò¿ª¸ÃÎļþ£¬ÓÚ¿ØÖÆÌ¨Ö´ÐÐ state.count++£¬±ã¿É¿´µ½Êä³ö set count to 1¡£

ÔÚÉÏÊöµÄÀý×ÓÖУ¬ÎÒÃÇʹÓà reactive() º¯Êý°Ñ origin ¶ÔÏóת»¯³ÉÁË Proxy ¶ÔÏó state£»Ê¹Óà effect() º¯Êý°Ñ fn() ×÷ΪÏìӦʽ»Øµ÷¡£µ± state.count ·¢Éú±ä»¯Ê±£¬±ã´¥·¢ÁË fn()¡£½ÓÏÂÀ´ÎÒÃǽ«ÒÔÕâ¸öÀý×Ó½áºÏÉÏÎĵÄÁ÷³Ìͼ£¬À´½²½âÕâÌ×ÏìӦʽϵͳÊÇÔõôÔËÐеġ£

³õʼ»¯½×¶Î

ÔÚ³õʼ»¯½×¶Î£¬Ö÷Òª×öÁËÁ½¼þÊ¡£

°Ñ origin ¶ÔÏóת»¯³ÉÏìӦʽµÄ Proxy ¶ÔÏó state¡£

°Ñº¯Êý fn() ×÷Ϊһ¸öÏìӦʽµÄ effect º¯Êý¡£

Ê×ÏÈÎÒÃÇÀ´·ÖÎöµÚÒ»¼þÊ¡£

´ó¼Ò¶¼ÖªµÀ£¬Vue 3.0 ʹÓÃÁË Proxy À´´úÌæÖ®Ç°µÄ Object.defineProperty()£¬¸ÄдÁ˶ÔÏóµÄ getter/setter£¬Íê³ÉÒÀÀµÊÕ¼¯ºÍÏìÓ¦´¥·¢¡£µ«ÊÇÔÚÕâÒ»½×¶ÎÖУ¬ÎÒÃÇÔÝʱÏȲ»¹ÜËüÊÇÈçºÎ¸Äд¶ÔÏóµÄ getter/setter µÄ£¬Õâ¸öÔÚºóÐøµÄ¡±ÒÀÀµÊÕ¼¯½×¶Î¡°»áÏêϸ˵Ã÷¡£ÎªÁ˼òµ¥Æð¼û£¬ÎÒÃÇ¿ÉÒÔ°ÑÕⲿ·ÖµÄÄÚÈÝŨËõ³ÉÒ»¸öÖ»ÓÐÁ½ÐдúÂëµÄ reactive() º¯Êý£º

export function reactive(target) {
const observed = new Proxy(target, handler)
return observed
}

ÍêÕû´úÂëÔÚ reactive.js¡£ÕâÀïµÄ handler ¾ÍÊǸÄÔì getter/setter µÄ¹Ø¼ü£¬ÎÒÃǷŵ½ºóÎĽ²½â¡£

½ÓÏÂÀ´ÎÒÃÇ·ÖÎöµÚ¶þ¼þÊ¡£

µ±Ò»¸öÆÕͨµÄº¯Êý fn() ±» effect() °ü¹üÖ®ºó£¬¾Í»á±ä³ÉÒ»¸öÏìӦʽµÄ effect º¯Êý£¬¶ø fn() Ò²»á±»Á¢¼´Ö´ÐÐÒ»´Î¡£

ÓÉÓÚÔÚ fn() ÀïÃæÓÐÒýÓõ½ Proxy ¶ÔÏóµÄÊôÐÔ£¬ËùÒÔÕâÒ»²½»á´¥·¢¶ÔÏóµÄ getter£¬´Ó¶øÆô¶¯ÒÀÀµÊÕ¼¯¡£

³ý´ËÖ®Í⣬Õâ¸ö effect º¯ÊýÒ²»á±»Ñ¹ÈëÒ»¸öÃûΪ¡±activeReactiveEffectStack¡°£¨´Ë´¦Îª effectStack£©µÄÕ»ÖУ¬¹©ºóÐøÒÀÀµÊÕ¼¯µÄʱºòʹÓá£

À´¿´¿´´úÂ루Íê³É´úÂëÇë¿´ effect.js£©£º

export function effect (fn) {
// ¹¹ÔìÒ»¸ö effect
const effect = function effect(...args) {
return run(effect, fn, args)
}
// Á¢¼´Ö´ÐÐÒ»´Î
effect()
return effect
}


export function run(effect, fn, args) {
if (effectStack.indexOf(effect) === -1) {
try {
// Íù³Ø×ÓÀï·ÅÈ뵱ǰ effect
effectStack.push(effect)
// Á¢¼´Ö´ÐÐÒ»±é fn()
// fn() Ö´Ðйý³Ì»áÍê³ÉÒÀÀµÊÕ¼¯£¬»áÓõ½ effect
return fn(...args)
} finally {
// Íê³ÉÒÀÀµÊÕ¼¯ºó´Ó³Ø×ÓÖÐÈÓµôÕâ¸ö effect
effectStack.pop()
}
}
}

ÖÁ´Ë£¬³õʼ»¯½×¶ÎÒѾ­Íê³É¡£½ÓÏÂÀ´¾ÍÊÇÕû¸öϵͳ×î¹Ø¼üµÄÒ»²½¡ª¡ªÒÀÀµÊÕ¼¯½×¶Î¡£

ÒÀÀµÊÕ¼¯½×¶Î

Õâ¸ö½×¶ÎµÄ´¥·¢Ê±»ú£¬¾ÍÊÇÔÚ effect ±»Á¢¼´Ö´ÐУ¬ÆäÄÚ²¿µÄ fn() ´¥·¢ÁË Proxy ¶ÔÏóµÄ getter µÄʱºò¡£¼òµ¥À´Ëµ£¬Ö»ÒªÖ´Ðе½ÀàËÆ state.count µÄÓï¾ä£¬¾Í»á´¥·¢ state µÄ getter¡£

ÒÀÀµÊÕ¼¯½×¶Î×îÖØÒªµÄÄ¿µÄ£¬¾ÍÊǽ¨Á¢Ò»·Ý¡±ÒÀÀµÊÕ¼¯±í¡°£¬Ò²¾ÍÊÇͼʾµÄ¡±targetMap"¡£targetMap ÊÇÒ»¸ö WeakMap£¬Æä key ÖµÊÇ~~µ±Ç°µÄ Proxy ¶ÔÏó state~~´úÀíǰµÄ¶ÔÏóorigin£¬¶ø value ÔòÊǸöÔÏóËù¶ÔÓ¦µÄ depsMap¡£

depsMap ÊÇÒ»¸ö Map£¬key ֵΪ´¥·¢ getter ʱµÄÊôÐÔÖµ£¨´Ë´¦Îª count£©£¬¶ø value ÔòÊÇ´¥·¢¹ý¸ÃÊôÐÔÖµËù¶ÔÓ¦µÄ¸÷¸ö effect¡£

»¹ÊÇÓеãÈÆ£¿ÄÇôÎÒÃÇÔپٸöÀý×Ó¡£¼ÙÉèÓиö Proxy ¶ÔÏóºÍ effect ÈçÏ£º

const state = reactive({
count: 0,
age: 18
})


const effect1 = effect(() => {
console.log('effect1: ' + state.count)
})


const effect2 = effect(() => {
console.log('effect2: ' + state.age)
})


const effect3 = effect(() => {
console.log('effect3: ' + state.count, state.age)
})

ÄÇôÕâÀïµÄ targetMap Ó¦¸ÃΪÕâ¸öÑù×Ó£º

ÕâÑù£¬{ target -> key -> dep } µÄ¶ÔÓ¦¹ØÏµ¾Í½¨Á¢ÆðÀ´ÁË£¬ÒÀÀµÊÕ¼¯Ò²¾ÍÍê³ÉÁË¡£´úÂëÈçÏ£º

export function track (target, operationType, key) {
const effect = effectStack[effectStack.length - 1]
if (effect) {
let depsMap = targetMap.get(target)
if (depsMap === void 0) {
targetMap.set(target, (depsMap = new Map()))
}


let dep = depsMap.get(key)
if (dep === void 0) {
depsMap.set(key, (dep = new Set()))
}


if (!dep.has(effect)) {
dep.add(effect)
}
}
}

ŪÃ÷°×ÒÀÀµÊÕ¼¯±í targetMap ÊǷdz£ÖØÒªµÄ£¬ÒòΪÕâÊÇÕû¸öÏìӦʽϵͳºËÐÄÖеĺËÐÄ¡£

ÏìÓ¦½×¶Î

»Ø¹ËÉÏÒ»Õ½ڵÄÀý×Ó£¬ÎÒÃǵõ½ÁËÒ»¸ö { count: 0, age: 18 } µÄ Proxy£¬²¢¹¹ÔìÁËÈý¸ö effect¡£ÔÚ¿ØÖÆÌ¨ÉÏ¿´¿´Ð§¹û£º

Ч¹û·ûºÏÔ¤ÆÚ£¬ÄÇôËüÊÇÔõôʵÏÖµÄÄØ£¿Ê×ÏÈÀ´¿´¿´Õâ¸ö½×¶ÎµÄÔ­Àíͼ£º

µ±Ð޸ĶÔÏóµÄij¸öÊôÐÔÖµµÄʱºò£¬»á´¥·¢¶ÔÓ¦µÄ setter¡£

setter ÀïÃæµÄ trigger() º¯Êý»á´ÓÒÀÀµÊÕ¼¯±íÀïÕÒµ½µ±Ç°ÊôÐÔ¶ÔÓ¦µÄ¸÷¸ö dep£¬È»ºó°ÑËüÃÇÍÆÈëµ½ effects ºÍ computedEffects£¨¼ÆËãÊôÐÔ£© ¶ÓÁÐÖУ¬×îºóͨ¹ý scheduleRun() °¤¸öÖ´ÐÐÀïÃæµÄ effect¡£

ÓÉÓÚÒѾ­½¨Á¢ÁËÒÀÀµÊÕ¼¯±í£¬ËùÒÔÒªÕÒµ½ÊôÐÔËù¶ÔÓ¦µÄ dep Ò²¾ÍÇá¶øÒ×¾ÙÁË£¬¿ÉÒÔ¿´¿´¾ßÌåµÄ´úÂëʵÏÖ£º

export function trigger (target, operationType, key) {
// È¡µÃ¶ÔÓ¦µÄ depsMap
const depsMap = targetMap.get(target)
if (depsMap === void 0) {
return
}
// È¡µÃ¶ÔÓ¦µÄ¸÷¸ö dep
const effects = new Set()
if (key !== void 0) {
const dep = depsMap.get(key)
dep && dep.forEach(effect => {
effects.add(effect)
})
}
// ¼ò»¯°æ scheduleRun£¬°¤¸öÖ´ÐÐ effect
effects.forEach(effect => {
effect()
})
}

ÕâÀïµÄ´úÂëûÓд¦ÀíÖîÈçÊý×éµÄ length ±»Ð޸ĵÄÒ»Ð©ÌØÊâÇé¿ö£¬¸ÐÐËȤµÄ¶ÁÕß¿ÉÒԲ鿴 vue-next ¶ÔÓ¦µÄÔ´Â룬»òÕßÕâÆªÎÄÕ£¬¿´¿´ÕâЩÇé¿ö¶¼ÊÇÔõô´¦ÀíµÄ¡£

ÖÁ´Ë£¬ÏìӦʽ½×¶ÎÍê³É¡£

×ܽá

ÔĶÁÔ´ÂëµÄ¹ý³Ì³äÂúÁËÌôÕ½ÐÔ£¬µ«Í¬Ê±Ò²³£³£±» Vue µÄһЩʵÏÖ˼·¸ø¾ªÑÞµ½£¬ÊÕ»ñÁ¼¶à¡£±¾Îİ´ÕÕÏìӦʽϵͳµÄÔËÐйý³Ì£¬»®·ÖÁË¡±³õʼ»¯¡°£¬¡±ÒÀÀµÊÕ¼¯¡°ºÍ¡±ÏìӦʽ¡°Èý¸ö½×¶Î£¬·Ö±ð²ûÊöÁ˸÷¸ö½×¶ÎËù×öµÄÊÂÇ飬Ӧ¸ÃÄܹ»½ÏºÃµØ°ïÖú¶ÁÕßÀí½âÆäºËÐÄ˼·¡£×îºó¸½ÉÏÎÄÕÂʵÀý´úÂëµÄ²Ö¿â µØÖ·.

 

 
   
1733 ´Îä¯ÀÀ       33
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì
×îл¼Æ»®
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢ 6-12[ÏÃÃÅ]
È˹¤ÖÇÄÜ.»úÆ÷ѧϰTensorFlow 6-22[Ö±²¥]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 6-30[±±¾©]
ǶÈëʽÈí¼þ¼Ü¹¹-¸ß¼¶Êµ¼ù 7-9[±±¾©]
Óû§ÌåÑé¡¢Ò×ÓÃÐÔ²âÊÔÓëÆÀ¹À 7-25[Î÷°²]
ͼÊý¾Ý¿âÓë֪ʶͼÆ× 8-23[±±¾©]
 
×îÐÂÎÄÕÂ
ÈçºÎÉè¼Æ¸ßÀ©Õ¹µÄÔÚÏßÍøÒ³ÖÆ×÷ƽ̨
electronÈëÃÅÐĵÃ
ʹÓà Electron ¹¹½¨×ÀÃæÓ¦ÓÃ
VUE.JS×é¼þ»¯¿ª·¢Êµ¼ù
ÉîÈëÀí½âJSCore
×îпγÌ
HTML 5 + CSS3 Ô­ÀíÓ뿪·¢Ó¦ÓÃ
Webǰ¶Ë¸ß¼¶¹¤³Ìʦ±Ø±¸¼¼ÄÜʵս
Vue´óÐÍÏîÄ¿¿ª·¢ÊµÕ½
ReactÔ­ÀíÓëʵ¼ù
Vue.js½ø½×Óë°¸Àýʵ¼ù
³É¹¦°¸Àý
Öн»¼¯ÍÅ ¹¹½¨Web×Ô¶¯»¯²âÊÔ¿ò¼Ü
ijָÃûµçÐŹ«Ë¾ Vue.js½ø½×Óë°¸Àý
¹úµçÍ¨ÍøÂç¼¼Êõ HTML5+CSS3 +webǰ¶Ë¿ò
ÒÆ¶¯Í¨ÐÅ ÒÆ¶¯»¥ÁªÍøÓ¦Óÿª·¢Ô­Àí
ijµçÁ¦ÐÐ android¿ª·¢Æ½Ì¨×î¼Ñ