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

1Ôª 10Ôª 50Ôª





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



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
Preact£ºÒ»¸ö±¸Ì¥µÄ×ÔÎÒÐÞÑø
 
×÷Õߣºmoon
  2090  次浏览      27
 2021-2-24 
 
±à¼­ÍƼö:
±¾ÎÄ×ÅÖØ½éÉÜÁËPreactµÄ¹¤×÷Á÷³ÌÒÔ¼°ÆäÖи÷¸öÄ£¿éµÄһЩ¹¤×÷ϸ½Ú£¬Ï£Íû¿ÉÒÔ´ïµ½Å×שÒýÓñµÄ×÷Óá£
±¾ÎÄÀ´×ÔÓÚÖªºõ,ÓÉ»ðÁú¹ûÈí¼þAnna±à¼­ÍƼö¡£

ǰһ¶Îʱ¼äÓÉÓÚReact LicenceµÄÎÊÌ⣬ÍŶÓÄÚ²¿»ý¼«µÄ̽Ë÷ReactµÄÌæ´ú·½°¸£¬Í¬Ê±¿¼Âǵ½Ö®ºó¿ÉÄÜ¿ªÕ¹µÄÒÆ¶¯¶ËÒµÎñ£¬ÍŶÓÄ¿±êÊÇÏ£ÍûÄܹ»ÕÒµ½Ò»¸öÇ¨ÒÆ³É±¾µÍ£¬ÌåÁ¿Ð¡µÄÌæ´ú²úÆ·¡£¾­¹ý¶à·½Ì½Ë÷£¬Preact½øÈëÁËÎÒÃǵÄÊÓÒ°¡£´Ó½Ó´¥µ½Preact¿ªÊ¼£¬Ò»Â·Ñ§Ï°ÏÂÀ´ÕÛËðÁËÐí¶àÍ··¢£¬Ò²ÊÕ»ñ²»ÉÙ˼¿¼£¬ÕâÀïÏëºÍ´ó¼Ò½éÉÜÒ»ÏÂPreactµÄʵÏÖ˼·£¬Ò²·ÖÏíÒ»ÏÂ×Ô¼ºµÄ˼¿¼ËùµÃ¡£

PreactÊÇʲô

Ò»¾ä»°½éÉÜPreact£¬ËüÊÇReactµÄ3KBÇáÁ¿Ìæ´ú·½°¸£¬ÓµÓÐͬÑùµÄES6 API¡£Èç¹û¾õµÃ¾ÍÕâôһ¾ä»°Ì«Ä£ºýµÄ»°£¬ÎÒ»¹¿ÉÒÔÔÙ†ªà¼¸¾ä¡£Preact = performance + react£¬ÕâÊÇPreactÃû×ÖµÄÓÉÀ´£¬ÆäÖÐÒ»¸öperformance×ãÒÔ¿ú¼û×÷ÕßµÄÓÃÐÄ¡£ÏÂÃæÕâÕÅͼ·´Ó³ÁËÔÚ³¤Áбí³õʼ»¯µÄ³¡¾°Ï£¬²»Í¬¿ò¼ÜµÄ±íÏÖ£¬¿ÉÒÔ¿´³öPreactȷʵÐÔÄܳöÖÚ¡£

¸ßÐÔÄÜ£¬ÇáÁ¿£¬¼´Ê±Éú²úÊÇPreact¹Ø×¢µÄºËÐÄ¡£»ùÓÚÕâЩÖ÷Ì⣬Preact¹Ø×¢ÓÚReactµÄºËÐŦÄÜ£¬ÊµÏÖÁËÒ»Ì×¼òµ¥¿ÉÔ¤²âµÄdiffË㷨ʹËü³ÉΪ×î¿ìµÄÐéÄâ DOM ¿ò¼ÜÖ®Ò»£¬Í¬Ê±preact-compatΪ¼æÈÝÐÔÌṩÁ˱£Ö¤£¬Ê¹µÃPreact¿ÉÒÔÎÞ·ì¶Ô½ÓReactÉú̬ÖеĴóÁ¿×é¼þ£¬Í¬Ê±Ò²²¹³äÁ˺ܶàPreactûÓÐʵÏֵŦÄÜ¡£

³¤Áбí³õʼ»¯Ê±¼ä¶Ô±È

PreactµÄ¹¤×÷Á÷³Ì

¼òµ¥½éÉÜÁËPreactµÄǰÉú½ñÊÀÒԺ󣬽ÓÏÂÀ´ËµÏÂPreactµÄ¹¤×÷Á÷³Ì£¬Ö÷Òª°üº¬Îå¸öÄ£¿é£º

component

hº¯Êý

render

diffËã·¨

»ØÊÕ»úÖÆ

Á÷ת¹ý³Ì¼ûÏÂͼ¡£

Ê×ÏÈÊÇÎÒÃǶ¨ÒåºÃµÄ×é¼þ£¬ÔÚäÖȾ¿ªÊ¼µÄʱºò£¬Ê×ÏÈ»á½øÈëhº¯ÊýÉú³É¶ÔÓ¦µÄvirtual node£¨Èç¹ûÊÇJSX±àд£¬Ö®Ç°»¹ÐèÒªÒ»²½×ªÂ룩¡£Ã¿Ò»¸övnodeÖаüº¬×ÔÉí½ÚµãµÄÐÅÏ¢£¬ÒÔ¼°×Ó½ÚµãµÄÐÅÏ¢£¬Óɴ˶øÁ¬½á³ÉΪһ¿Ãvirtual domÊ÷¡£»ùÓÚÉú³ÉµÄvnode£¬renderÄ£¿é»á½áºÏµ±Ç°domÊ÷µÄÇé¿ö½øÐÐÁ÷³Ì¿ØÖÆ£¬²¢ÎªºóÐøµÄdiff²Ù×÷×öһЩ׼±¸¹¤×÷¡£PreactµÄdiffË㷨ʵÏÖÓбðÓÚreact»ùÓÚË«virtual domÊ÷µÄ˼·£¬Preactֻά³ÖÒ»¿ÃеÄvirtual domÊ÷£¬diff¹ý³ÌÖлá»ùÓÚdomÊ÷»¹Ô­³ö¾ÉµÄvirtual domÊ÷£¬ÔÙ½«Á½Õß½øÐбȽϣ¬²¢ÔڱȽϹý³ÌÖÐʵʱ¶ÔdomÊ÷½øÐÐpatch²Ù×÷£¬×îÖÕÉú³ÉеÄdomÊ÷¡£Óë´Ëͬʱ£¬diff¹ý³ÌÖб»Ð¶ÔصÄ×é¼þºÍ½Úµã²»»á±»Ö±½Óɾ³ý£¬¶øÊDZ»·Ö±ð·ÅÈë»ØÊÕ³ØÖлº´æ£¬µ±ÔÙ´ÎÓÐͬÀàÐ͵Ä×é¼þ»ò½Úµã±»¹¹½¨Ê±£¬¿ÉÒÔÔÚ»ØÊÕ³ØÖÐÕÒµ½Í¬ÃûÔªËØ½øÐиÄÔ죬±ÜÃâ´ÓÁã¹¹½¨µÄ¿ªÏú¡£

Preact¹¤×÷Á÷³Ìͼ

ÔÚÁ˽âÁËPreactµÄ¹¤×÷Á÷³ÌÖ®ºó£¬½ÓÏÂÀ´»á¶ÔÉÏÎÄÌáµ½µÄÎå¸öÄ£¿éÒ»Ò»½â¶Á¡£

1. Component

¹Ø¼ü´Ê£ºhook£¬linkState, ÅúÁ¿¸üÐÂ

ÏàÐÅÓйýreact¿ª·¢¾­ÑéµÄͬѧ¶ÔcomponentµÄ¸ÅÄî¶¼²»»áİÉú£¬ÕâÀïÒ²²»×ö¹ý¶à½âÊÍ£¬Ö»ÊǽéÉÜһЩPreactÔÚcomponent²ãÃæÉϵÄÌí¼ÓµÄÐÂÌØÐÔ¡£

hookº¯Êý

³ýÁË»ù±¾µÄÉúÃüÖÜÆÚº¯ÊýÍ⣬Preact»¹ÌṩÈý¸öhookº¯Êý£¬·½±ãÓû§ÔÚÖ¸¶¨µÄʱ¼äµãÖ´ÐÐͳһ²Ù×÷¡£

afterMount

afterUpdate

beforeUnmount

linkState

linkStateÕë¶ÔµÄ³¡¾°ÊÇÔÚrender·½·¨ÖÐΪÓû§²Ù×÷µÄ»Øµ÷°ó¶¨this£¬ÕâÑùÿ´ÎäÖȾ¶¼ÔÚ¾Ö²¿´´½¨Ò»¸öº¯Êý±Õ°ü£¬ÕâÑùЧÂÊÊ®·ÖµÍ϶øÇÒ»áÆÈʹÀ¬»ø»ØÊÕÆ÷×öÐí¶à²»±ØÒªµÄ¹¤×÷¡£linkStateÀíÏëÖеÄÓ¦Óó¡¾°ÈçÏ¡£

export default class App extends Component {
constructor() {
super();
this.state = {
text: 'initial'
}
}

handleChange = e => {
this.setState({
text: e.target.value
})
}

render({desc}, {text}} {
return (
<div>
<input value={text} onChange= {this.linkState('text', 'target.value')}>
<div>{text}</div>
</div>
)
}
}

È»¶ølinkStateµÄʵÏÖ·½Ê½¡£¡£¡£ÊÇÔÚ×é¼þ³õʼ»¯µÄʱºòΪÿ¸ö»Øµ÷´´½¨±Õ°ü£¬°ó¶¨this£¬Í¬Ê±´´½¨Ò»¸öʵÀýÊôÐÔ½«°ó¶¨ºó»Øµ÷º¯Êý»º´æÆðÀ´£¬ÕâÑùÔÙ´ÎrenderµÄʱºò¾Í²»ÐèÒªÔٴΰ󶨡£Êµ¼ÊЧ¹ûµÈͬÓÚÔÚ×é¼þµÄconstructorÖа󶨡£ÞÏÞÎÖ®´¦ÔÚÓÚ£¬linkStateÄÚ²¿Ö»ÊµÏÖÁËsetState²Ù×÷£¬Í¬Ê±Ò²²»Ö§³Ö×Ô¶¨Òå²ÎÊý£¬Ê¹Óó¡¾°±È½ÏÓÐÏÞ¡£

//linkStateÔ´Âë
//»º´æ»Øµ÷
linkState(key, eventPath) {
let c = this._linkedStates || (this._linkedStates = {});
return c[key+eventPath] || (c[key+eventPath] = createLinkedState(this, key, eventPath));
}

//Ê×´Î×¢²á»Øµ÷µÄʱºò´´½¨±Õ°ü
export function createLinkedState(component, key, eventPath) {
let path = key.split('.');
return function(e) {
let t = e && e.target || this,
state = {},
obj = state,
v = isString(eventPath) ? delve(e, eventPath) : t.nodeName ? (t.type.match(/^che|rad/) ? t.checked : t.value) : e,
i = 0;
for ( ; i<path.length-1; i++) {
obj = obj[path[i]] || (obj[path[i]] = !i && component.state[path[i]] || {});
}
obj[path[i]] = v;
component.setState(state);
};
}

ÅúÁ¿¸üÐÂ

PreactʵÏÖÁË×é¼þµÄÅúÁ¿¸üУ¬¾ßÌåʵÏÖ˼·¾ÍÊÇÿ´ÎÖ´ÐÐstate or props¸üÐÂ֮ʱ£¬¶ÔÓ¦µÄÊôÐԻᱻÁ¢¿Ì¸üУ¬µ«ÊÇ»ùÓÚnew state or propsµÄäÖȾ²Ù×÷»á±»push½øµ½Ò»¸ö¸üжÓÁÐÖУ¬ÔÚµ±Ç°event loopµÄ×îºó»òÕßÊÇÔÚÏÂÒ»¸öevent loopµÄ¿ªÊ¼£¬²Å»á½«¶ÓÁÐÖеIJÙ×÷Ò»Ò»Ö´ÐС£Í¬Ò»¸ö×é¼þ״̬µÄ¶à´Î¸üУ¬²»»áÖØ¸´½øÈë¶ÓÁС£ÈçÏÂͼËùʾ£¬ÊôÐÔ¸üÐÂÖ®ºó£¬×é¼þäÖȾ֮ǰ£¬_dirtyֵΪtrue£¬Òò´Ë£¬×é¼þäÖȾ֮ǰºóÐøµÄÊôÐÔ¸üвÙ×÷¶¼²»»áʹ×é¼þÖØ¸´Èë¶Ó¡£

//¸üжÓÁÐÔ´Âë
export function enqueueRender(component) {
if (!component._dirty && (component._dirty = true) && items.push(component)==1) {
(options.debounceRendering || defer)(rerender);
}
}

2. hº¯Êý

¹Ø¼ü´Ê£º½ÚµãºÏ²¢

hº¯ÊýµÄ×÷ÓÃÈçͬReact.CreateElement£¬ÓÃÓÚÉú³Évirtual node¡£Æä½ÓÊܵÄÊäÈë¸ñʽÈçÏ£¬Èý¸ö²ÎÊý·Ö±ðΪ½ÚµãÀàÐÍ£¬½ÚµãÊôÐÔ£¬×ÓÔªËØ¡£

h('a', { href: '/', h{'span', null, 'Home'}})

 

½ÚµãºÏ²¢

hº¯ÊýÔÚÉú³ÉvnodeµÄ¹ý³ÌÖУ¬»á¶ÔÏàÁڵļòµ¥½Úµã½øÐкϲ¢²Ù×÷£¬Ä¿µÄÊÇΪÁ˼õÉÙ½ÚµãÊýÁ¿£¬¼õÇádiff¸ºµ£¡£ Çë¿´ÏÂÃæµÄÀý×Ó¡£

import { h, Component } from 'preact';
const innerinnerchildren = [['innerchild2', 'innerchild3'], 'innerchild4'];
const innerchildren = [
<div>
{innerinnerchildren}
</div>,
<span>desc</span>
]

export default class App extends Component {
render() {
return (
<div>
{innerchildren}
</div>
)
}
}

 

3. Render

¹Ø¼ü´Ê£ºÁ÷³Ì¿ØÖÆ£¬diff×¼±¸

Ê×ÏÈÏȽâÊÍһϣ¬ÕâÀïµÄrenderÄ£¿é·ºÖ¸Õû¸öÁ÷³ÌÖн«vnode²åÈëµ½domÊ÷ÖеIJÙ×÷£¬È»¶øÕâÀà²Ù×÷ÖÐÓÖÓÐÒ»²¿·Ö¹¤×÷±»diffÄ£¿é³Ðµ££¬ËùÒÔʵ¼ÊÉÏrenderÄ£¿éµÄ¸ü¶à³Ðµ£µÄÊÇÁ÷³Ì¿ØÖÆÒÔ¼°½øÈëdiffµÄǰÖù¤×÷¡£

Á÷³Ì¿ØÖÆ

ËùνÁ÷³Ì¿ØÖÆ£¬¾ßÌåµÄÄÚÈÝ·ÖΪÁ½²¿·Ö£¬½ÚµãÀàÐ͵ÄÅжϣ¬ÊÇ×Ô¶¨ÒåµÄ×é¼þ»¹ÊÇÔ­ÉúµÄdom½Úµã£¬äÖȾÀàÐ͵ÄÅжϣ¬ÊÇÊ×´ÎäÖȾ»¹ÊǸüвÙ×÷¡£¸ù¾Ý²»Í¬Çé¿ö£¬Ö¸¶¨²»Í¬µÄäÖȾ·Ïߣ¬Ö´ÐÐÏàÓ¦µÄÉúÃüÖÜÆÚ·½·¨£¬hookº¯ÊýºÍäÖȾÂß¼­¡£

Diff×¼±¸

ÈçǰËùÊö£¬PreactÔÚÄÚ´æÖÐֻά³ÖÒ»¿Ã°üº¬¸üÐÂÄÚÈݵÄеÄvirtual domÊ÷£¬ÁíÒ»¸ö´ú±í±»¸üеľɵÄvirtual domÊ÷ʵ¼ÊÉÏÊÇ´ÓdomÊ÷»¹Ô­»ØÀ´µÄ£¬Óë´Ëͬʱ£¬domÊ÷µÄ¸üвÙ×÷Ò²ÊÇÔڱȽϹý³ÌÖУ¬Ò»±ß±È½ÏÒ»±ßpatchµÄ¡£ÎªÁËÈ·±£ÉÏÊö²Ù×÷²»³öÏÖ»ìÂÒ£¬ÔÚÉú³É/¸üеÄdomÊ÷µÄ֮ǰ£¬ÐèÒªÔÚdom½ÚµãÉÏÌí¼ÓһЩ×Ô¶¨ÒåµÄÊôÐԼǼ״̬¡£

//´´½¨×Ô¶¨ÒåÊôÐԼǼ
export function renderComponent (component, opts, mountAll, isChild) {
if (component._disable) return;

let skip, rendered,
props = component.props,
state = component.state,
context = component.context,
previousProps = component.prevProps || props,
previousState = component.prevState || state,
previousContext = component.prevContext || context,
isUpdate = component.base,
nextBase = component.nextBase,
initialBase = isUpdate || nextBase,
initialChildComponent = component._component,
inst, cbase;


4. DiffËã·¨

¹Ø¼ü´Ê£ºDOMÒÀÀµ£¬Disconnected or Not£¬DocumentFragment

diff¹ý³ÌÖ÷Òª·ÖΪÁ½¸ö½×¶Î£¬µÚÒ»¸ö½×¶ÎÊǽ¨Á¢virual nodeÓëdom½ÚµãÖ®¼äµÄ¶ÔÓ¦¹ØÏµ£¬µÚ¶þ¸ö½×¶Î±ãÊǶÔÁ½Õß½øÐбȽϲ¢¸üÐÂdom½Úµã¡£

ÔÚʵ¼ÊÖ´Ðйý³ÌÖУ¬diff²Ù×÷µÄÆðµãÊÇupdate×é¼þµÄ¸ù½ÚµãÓë´ú±íÆäÏÂÒ»¸ö״̬µÄvnode֮ǰµÄ±È½Ï¡£ÕâÒ»²½ÖÐÁ½ÕßÖ®¼äµÄ¶ÔÓ¦¹ØÏµÊ®·ÖÃ÷È·£¬¶øµ½ÁËÏÂÒ»²½£¬ÔòÐèÒªÔÚÁ½ÕßµÄ×ÓÔªËØÖÐÈ·¶¨¶ÔÓ¦¹ØÏµ£¬¾ßÌåµÄ·½·¨ÊÇÊ×ÏȶÔÏàͬkeyÖµµÄ×Ó½ÚµãÅä¶Ô£¬Ö®ºó½«Í¬ÀàÐ͵ĽڵãÅä¶Ô£¬×îºóûÓб»Åä¶ÔµÄvnodeÊÓΪÐÂÌí¼ÓµÄ½Úµã£¬¶øÂäµ¥µÄdom½ÚµãµÄÃüÔËÔòÊDZ»»ØÊÕ¡£

½øÈëµ½¸üн׶ÎÖ®ºó£¬»á¸ù¾Ývirtual nodeµÄÀàÐͺÍdomÊ÷ÖвÎÕÕ½ÚµãµÄÇé¿ö·ÖÀà´¦Àí£¬²¢ÔÚdiffµÄ¹ý³ÌÖÐʵʱµÄ½øÐÐpatch²Ù×÷£¬×îÖÕÉú³ÉеÄdom½Úµã£¬È»ºó¶Ô×Ó½ÚµãµÝ¹é¡£

DiffÁ÷³Ìͼ

DOMÒÀÀµ

¾­¹ýÇ°ÃæµÄ½éÉÜ£¬ÏàÐÅ´ó¼Ò¶ÔPreactµÄvirtual domʵÏÖÒѾ­ÓÐÁËÒ»¶¨µÄÁ˽⣬ÕâÀï²»ÔÙ׸Êö¡£ÕâÖÖʵÏÖ·½Ê½£¬ÓŵãÔÚÓÚ×ÜÄÜÕæÊµµÄ·´Ó³Ö®Ç°virtual domÊ÷µÄÇé¿ö£¬È±µã¾ÍÊÇ´æÔÚÄÚ´æÐ¹Â¶µÄ·çÏÕ¡£

Disconnected or Not

What does Disconnected mean

ÎÒÃǶ¼ÖªµÀ£¬µ±ÎÒÃÇÏòdomÊ÷ÖеĽڵãÖ´ÐÐappendChild£¬removeChild²Ù×÷µÄʱºò£¬Ã¿Ö´ÐÐÒ»´Î£¬¾Í»á´¥·¢Ò»´ÎÒ³ÃæµÄreflow£¬ÕâÊÇÒ»¸ö¾ßÓÐÏ൱¿ªÏúµÄÐÐΪ¡£Òò´Ëµ±ÎÒÃDZØÐëÖ´ÐÐһϵÁÐÕâÑùµÄ²Ù×÷µÄʱºò£¬¿ÉÒÔ²ÉÈ¡ÕâÑùµÄÓÅ»¯ÊֶΣ¬Ê×ÏÈ´´½¨Ò»¸ö½Úµã£¬ÔÚÕâ¸ö½ÚµãÉÏÖ´ÐйýËùÓÐ×Ó½ÚµãµÄappend²Ù×÷Ö®ºó£¬ÔÙ½«ÒÔÕâ¸ö½Úµã×÷Ϊ¸ù½ÚµãµÄ×ÓÊ÷Ò»´ÎÐÔµÄappend»òÕßreplaceµ½domÊ÷ÖУ¬Ö»´¥·¢Ò»´Îreflow£¬¾ÍÍê³ÉÁËÕû¸ö×ÓÊ÷µÄ¸üУ¬ÕâÑùµÄ¸üз½Ê½³ÆÖ®Îªdisconnected¡£

ÓëÖ®Ïà¶Ô£¬ÔÚ´´½¨½ÚµãÖ®ºó£¬Á¢¿Ì½«½Úµã²åÈëµ½domÊ÷ÖУ¬È»ºó¼ÌÐø½øÐÐ×Ó½ÚµãµÄ²Ù×÷£¬Ôò³ÆÖ®Îªconnected¡£

Go ahead to Preact

ÔÚ²ûÃ÷ÁËÕâ¸öǰÌáÖ®ºó£¬ÔÙÀ´¿´PreactµÄʵÏÖ·½Ê½£¬Disconnected or Connected£¬ÊÇÒ»×ùΧ³Ç¡£¾¡¹Ü×÷ÕßÉù³ÆPreactµÄäÖȾ·½Ê½ÊÇdisconnected£¬È»¶øÊÂʵµÄÕæÏàÊÇ£¬not always true¡£ ´ÓÒ»¸ö¼òµ¥µÄÇé¿ö˵Æð£¬textnodeµÄÖµ±»Ð޸ĻòÕß¾ÉµÄ½Úµã±»Ìæ»»³Étextnode¡£PreactËù×öµÄ¾ÍÊÇ´´½¨Ò»¸ötextnode»òÕßÐÞ¸Ä֮ǰtextnodeµÄnodeValue¡£ËäÈ»¾À½áÕâ¸ö³¡¾°ÊÇûÓÐÒâÒåµÄ£¬µ«ÊÇΪÁËÍêÕûµÄ½éÉÜdiffÁ÷³Ì£¬ÓбØÒªÏÈ˵Ã÷һϡ£ ½øÈëÖØµã¡£ÏÈ¿´µÚÒ»¸öÀý×Ó¡£ÎªÁË˵Ã÷ÎÊÌ⣬ÎÒÃÇÓÃÒ»¸öÉÔ΢¼«¶ËµãµÄÀý×Ó¡£

ÔÚÕâ¸öÀý×ÓÖпÉÒÔ¿´µ½£¬µ±ÊäÈëtextÖ®ºó£¬ÓÐÒ»¸ödiv×ÓÊ÷Ïòsection×ÓÊ÷µÄ¸üУ¬ÕâÀïΪÁËÃèÊöÒ»¸ö¼«¶ËÇé¿ö£¬¸üÐÂǰºóµÄ×Ó½ÚµãÊÇÒ»ÑùµÄ¡£

//ÀýÒ» placeholderËùÔÚ×ÓÊ÷Ö»Óиù½Úµã²»Í¬
import { h, Component } from 'preact';

export default class App extends Component {
constructor() {
super();
this.state = {
text: ''
}
}

handlechang = e => {
this.setState({
text: e.target.value
})
}

render({desc}, { text }) {
return (
<div>
<input value={text} onChange={this.handlechang}/>
{text ? <section key='placeholder'>
<h2>placeholder</h2>
</section>: <div key='placeholder'>
<h2>placeholder</h2>
</div>}
</div>
)
}
}

½ÓÏÂÀ´¿´Ò»ÏÂÕë¶ÔÕâÖÖ³¡¾°£¬diff²Ù×÷µÄÏêϸÁ÷³Ì¡£

//Ô­ÉúdomµÄidiffÂß¼­
let out = dom, //×¢ÊÍ1
nodeName = String(vnode.nodeName),
prevSvgMode = isSvgMode,
vchildren = vnode.children;

isSvgMode = nodeName==='svg' ? true : nodeName==='foreignObject' ? false : isSvgMode;

if (!dom) { //×¢ÊÍ2
out = createNode(nodeName, isSvgMode);
}
else if (!isNamedNode(dom, nodeName)) { //×¢ÊÍ3
out = createNode(nodeName, isSvgMode);
while (dom.firstChild) out.appendChild(dom.firstChild);
if (dom.parentNode) dom.parentNode.replaceChild(out, dom);
recollectNodeTree(dom);
}

//×Ó½ÚµãµÝ¹é
¡­¡­
else if (vchildren && vchildren.length || fc) {
innerDiffNode(out, vchildren, context, mountAll);
}
¡­¡­

ÎÞÂÛ²ÎÓëdiffµÄÔªËØÊÇ×Ô¶¨Òå×é¼þ»¹ÊÇÔ­Éúdom£¬¾­¹ý²ã²ã½â¹¹£¬×îÖÕ¶¼ÊÇÒÔdomµÄÐÎʽ½øÐбȽϡ£Òò´ËÎÒÃÇÖ»ÐèÒª¹Ø×¢Ô­ÉúdomµÄdiffÂß¼­¡£

Ê×ÏÈ¿´×¢ÊÍ1µÄλÖã¬dom±íʾdomÊ÷ÉϵĽڵ㣬Ҳ¾ÍÊÇÒª±»¸üеôµÄ½Úµã£¬vnode¾ÍÊÇ´ýäÖȾµÄÐéÄâ½Úµã¡£ÔÚÀýÒ»ÖУ¬diffµÄÆðµã¾ÍÊÇ×îÍâ²ãµÄdiv£¬Ò²¾ÍÊǵÚÒ»ÂÖµÄdom±äÁ¿£¬Òò´Ë×¢ÊÍ2£¬×¢ÊÍ3´¦µÄÅж¨¾ùΪfalse¡£Ö®ºó»á¶Ôout½ÚµãµÄ×Ó½ÚµãºÍ¶ÔÓ¦µÄvnodeµÄ×Ó½Úµã½øÐеݹéµÄdiff²Ù×÷¡£

ÄÇôÕâÀïÊ×ÏÈ˵Ã÷Á˵ÚÒ»´¦ÎÊÌ⣬äÖȾ²Ù×÷µÄÆðµãʼÖÕÊÇconnected״̬µÄ¡£

if (vlen) {
for (let i=0; i<vlen; i++) {
vchild = vchildren[i];
child = null;

let key = vchild.key;
// ÏàͬkeyֵƥÅä
if (key!=null) {
if (keyedLen && key in keyed) {
child = keyed[key];
keyed[key] = undefined;
keyedLen--;
}
}
// ÏàͬnodeNameÆ¥Åä
else if (!child && min<childrenLen) {
for (j=min; j<childrenLen; j++) {
c = children[j];
if (c && isSameNodeType(c, vchild)) {
child = c;
children[j] = undefined;
if (j===childrenLen-1) childrenLen--;
if (j===min) min++;
break;
}
}
}
// vnodeΪsection½Úµãʱ£¬domÊ÷ÖмÈÎÞͬkey½Úµã£¬Ò²ÎÞͬnodeName½Úµã£¬Òò´ËΪnull
child = idiff(child, vchild, context, mountAll);
¡­¡­

×Ó½ÚµãÖ®¼äµÄ¶ÔÓ¦¹ØÏµµÄÈ·Á¢ÒÀ¾Ý£¬ÒªÃ´keyÖµÏàͬ£¬ÒªÃ´nodeNameÏàͬ£¬¿ÉÒÔÖªµÀsectionºÍdivµÄ¹ØÏµ²¢²»Âú×ãÉÏÊöÁ½ÖÖÇé¿ö¡£Òò´Ëµ±ÔٴνøÈëidiff·½·¨µÄʱºò£¬ÔÚ×¢ÊÍ2µÄλÖã¬ÓÉÓÚdom²»´æÔÚ£¬»áн¨Ò»¸ösection½Úµã¸³¸øout£¬ÕâÑùÔٴνøÐÐ×ÓÔªËØdiffµÄʱºò£¬ÓÉÓÚoutÊÇÒ»¸öн¨½Úµã£¬²»°üº¬ÈκÎ×ÓÔªËØ£¬sectionµÄËùÓÐ×ÓÔªËØdiffµÄ¶ÔÏó¶¼ÊÇnull£¬Õâ¾ÍÒâζÕâsectionµÄËùÓÐ×ÓÔªËØ×îºó¶¼ÊDZ»Ð½¨³öÀ´µÄ£¨²»ÂÛÊÇ·ñÉèÖÃÁËkeyÖµ£©£¬¾¡¹ÜËüÃǺ;ɵÄdomÉϵĽڵãһģһÑù¡£¡£¡£ËùÒÔ×ܽáһϾÍÊÇÀýÒ»ÕâÖÖÇé¿ö£¬sectionËùÓеÄ×ӽڵ㶼ÊDZ»Ð½¨³öÀ´µÄ£¬¶ø²»ÊDZ»¸´Óõ쬵«ÊÇÕû¸ö²Ù×÷¹ý³ÌÊÇÔÚdisconnectedÇé¿öϽøÐеġ£

ÄÇôÈç¹û¸øÁ½Õß¼ÓÉÏÏàͬµÄkeyֵĨ£¿

// Àý¶þ£¬×é¼þ½á¹¹Ïàͬ£¬Î¨Ò»µÄÇø±ðÊÇplaceholderËùÔÚ×ÓÊ÷Ìí¼ÓÁËÏàͬµÄkeyÖµ
import { h, Component } from 'preact';

export default class App extends Component {
constructor() {
super();
this.state = {
text: ''
}
}

handlechang = e => {
this.setState({
text: e.target.value
})
}


render({desc}, { text }) {
return (
<div>
<input value={text} onChange={this.handlechang}/>
{text ? <section key='placeholder'>
<h2>placeholder</h2>
</section>: <div key='placeholder'>
<h2>placeholder</h2>
</div>}
</div>
)
}
}

ÒòΪÁ½Õß¾ßÓÐÏàͬµÄkeyÖµ£¬ËùÒÔÔÚvnodeÓëdomÈ·¶¨¶ÔÓ¦¹ØÏµÊ±¿ÉÒԳɹ¦µÄÅä¶Ô£¬½øÈëdiff»·½Ú¡£È»¶øÒ»¸öreplace²Ù×÷ÓÖÈúóÐøµÄËùÓвÙ×÷¶¼±ä³ÉÁËconnected¡£ºÃÏûÏ¢ÊÇÏàͬµÄ×ӽڵ㱻¸´ÓÃÁË¡£

// Ô­ÉúdomµÄdiffÂß¼­
// dom½Úµã£¬¼´div´æÔÚ£¬ÇÒÓëvnode½ÚµãÀàÐÍsection²»Í¬ÀàÐÍ
else if (!isNamedNode(dom, nodeName)) {
out = createNode(nodeName, isSvgMode);
while (dom.firstChild) out.appendChild(dom.firstChild);
if (dom.parentNode) dom.parentNode.replaceChild(out, dom);
recollectNodeTree(dom);
}

DocumentFragment

³ýÈ¥ÉÏÃæ½éÉܹýµÄdisconnected·½·¨£¬»¹¿ÉÒÔͨ¹ýDocumentFragment½«Ò»ÏµÁнڵãÒ»´ÎÐÔ²åÈëdom¡£DocumentFragment ½Úµã²åÈëÎĵµÊ÷ʱ£¬²åÈëµÄ²»ÊÇ DocumentFragment ×ÔÉí£¬¶øÊÇËüµÄËùÓÐ×ÓËï½Úµã¡£ÕâʹµÃ DocumentFragment ³ÉÁËÓÐÓõÄռλ·û£¬ÔÝʱ´æ·ÅÄÇЩһ´Î²åÈëÎĵµµÄ½Úµã¡£githubÉÏÒ²ÓÐÈËÏò×÷ÕßÌá³öÁËͬÑùµÄÎÊÌ⣬×÷Õß±íʾËûÔø¾­Ò²³¢ÊÔ¹ýÓÃDocumentFragmentµÄ·½Ê½ÊÔͼ¼õÉÙreflowµÄ´ÎÊý£¬È»¶ø×îÖյĽá¹ûÈ´ÁîÈËÒâÍâ¡£

ÉÏͼΪ×÷Õß±àдµÄ²âÊÔ°¸ÀýµÄÐÔÄܶԱÈͼ£¬ºá×ø±êΪOperation per second£¬ÊýÖµÔ½´ó´ú±íÖ´ÐÐЧÂÊÔ½¸ß¡£¿ÉÒÔ¿´³öÎÞÂÛconnected»¹ÊÇdisconnectedµÄÇé¿ö£¬DocumentFragementµÄ±íÏÖ¶¼¸ü²î¡£¾ßÌåÔ­Òò»¹Óдý¿¼¾¿¡£BenchMarkÔ­Á´½Ó¡£

5. »ØÊÕ»úÖÆ

¹Ø¼ü´Ê£º»ØÊÕ³Ø&Enhanced Mount

»ØÊÕ³Ø&Enhanced Mount

ÔÚ½«½Úµã´ÓdomÖÐÒÆ³ýʱ£¬²»»á½«½ÚµãÖ±½Óɾ³ý£¬¶øÊÇ»á¸ù¾Ý½ÚµãÀàÐÍ£¨×é¼þ or node£©£¬Ö´ÐÐһЩÇåÀíÂß¼­Ö®ºó£¬·Ö±ð´æÈëµ½Á½¸ö»ØÊÕ³ØÖС£ÔÚÿ´ÎÖ´ÐÐMount²Ù×÷µÄʱºò£¬´´½¨·½·¨»áÔÚ»ØÊÕ³ØÀïѰÕÒͬÀàÐͽڵ㣬һµ©ÕÒµ½ÕâÑùµÄͬÀà½Úµã£¬Ëü»á±»×÷Ϊ´ý¸üеIJÎÕսڵ㴫ÈëdiffËã·¨ÖУ¬ÕâÑùÔÙºóÐøµÄ±È½Ï¹ý³ÌÖУ¬À´×Ô»ØÊճصĽڵã»á±»×÷ΪԭÐͽøÐÐpatch¸ÄÔ죬²úÉúеĽڵ㡣Ï൱ÓÚ±äMountΪUpdate£¬´Ó¶ø±ÜÃâ´ÓÁã¹¹½¨µÄ¶îÍ⿪Ïú¡£

ÏÖʵµÄ½á¾ÖÍùÍùûÓÐͯ»°¹ÊʰãÃÀºÃ£¬»ØÊÕ»úÖÆ×îÖÕ»¹ÊdzöÏÖÁËÒâÍâ¡£°¸·¢ÏÖ³¡´«ËÍÃÅ£¬»ØÊÕ»úÖÆ»áÔÚijЩÇé¿öϵ¼Ö½ڵ㱻´íÎóµÄ¸´Óá­¡­ËùÒÔ£¬Èçͬ·¢Ñ×µÄÀ»Î²£¬¿ÉÄÜºÜ¿ì»ØÊÕ»úÖÆ¾Í»á´ÓÎÒÃǵÄÊÓÏßÀïÏûʧÁË¡£

 

 
   
2090 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

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

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

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