단순성, 모듈성, 강력한 기능 및 성능에 중점을 둔 가상 DOM 라이브러리.
훌륭한 크로스 브라우저 테스트 도구에 대한 액세스를 제공해 주신 Browserstack에게 감사드립니다.
영어 | 简体中文 | 힌디 어
가상 Dom은 굉장합니다. 이를 통해 응용 프로그램의 견해를 상태의 함수로 표현할 수 있습니다. 그러나 기존 솔루션은 너무 부풀어 오르고 너무 느리고 기능이 부족했으며 API가 OOP에 편향되어 있거나 필요한 기능이 부족했습니다.
Snabbdom은 매우 간단하고 성능이 뛰어나며 확장 가능한 코어로 구성되어 있으며 ≈ 200 SLOC입니다. 사용자 지정 모듈을 통한 확장에 대한 풍부한 기능을 갖춘 모듈 식 아키텍처를 제공합니다. 핵심을 단순하게 유지하기 위해 모든 비 필수 기능이 모듈에 위임됩니다.
당신은 당신이 원하는대로 snabbdom을 만들 수 있습니다! 원하는 기능을 선택, 선택 및 사용자 정의하십시오. 또는 기본 확장을 사용하고 고성능, 작은 크기 및 아래에 나열된 모든 기능을 갖춘 가상 DOM 라이브러리를 얻을 수 있습니다.
h 기능.h 헬퍼와 함께 작동합니다 . import {
init ,
classModule ,
propsModule ,
styleModule ,
eventListenersModule ,
h
} from "snabbdom" ;
const patch = init ( [
// Init patch function with chosen modules
classModule , // makes it easy to toggle classes
propsModule , // for setting properties on DOM elements
styleModule , // handles styling on elements with support for animations
eventListenersModule // attaches event listeners
] ) ;
const container = document . getElementById ( "container" ) ;
const vnode = h (
"div#container.two.classes" ,
{ on : { click : ( ) => console . log ( "div clicked" ) } } ,
[
h ( "span" , { style : { fontWeight : "bold" } } , "This is bold" ) ,
" and this is just normal text" ,
h ( "a" , { props : { href : "/foo" } } , "I'll take you places!" )
]
) ;
// Patch into empty DOM element – this modifies the DOM as a side effect
patch ( container , vnode ) ;
const newVnode = h (
"div#container.two.classes" ,
{ on : { click : ( ) => console . log ( "updated div clicked" ) } } ,
[
h (
"span" ,
{ style : { fontWeight : "normal" , fontStyle : "italic" } } ,
"This is now italic type"
) ,
" and this is still just normal text" ,
h ( "a" , { props : { href : "/bar" } } , "I'll take you places!" )
]
) ;
// Second `patch` invocation
patch ( vnode , newVnode ) ; // Snabbdom efficiently updates the old view to the new state initpatchhfragment (실험)toVNodeinit 후크insert 후크remove 후크destroy 후크remove 시 속성을 설정하십시오destroy 에 속성을 설정하십시오Snabbdom의 핵심은 가장 중요한 기능 만 제공합니다. 여전히 빠르고 확장 가능하면서도 가능한 한 간단하게 설계되었습니다.
init 코어는 하나의 단일 함수 init 만 노출시킵니다. 이 init 모듈 목록을 가져 와서 지정된 모듈 세트를 사용하는 patch 함수를 반환합니다.
import { classModule , styleModule } from "snabbdom" ;
const patch = init ( [ classModule , styleModule ] ) ;patch init 가 반환 한 patch 함수는 두 가지 인수를합니다. 첫 번째는 현재보기를 나타내는 DOM 요소 또는 vnode입니다. 두 번째는 새로운 업데이트 된보기를 나타내는 vnode입니다.
부모가있는 DOM 요소가 전달되면 newVnode DOM 노드로 바뀌고 전달 된 요소는 생성 된 DOM 노드로 대체됩니다. 이전 vnode가 전달되면 Snabbdom은 새 vnode의 설명과 일치하도록 효율적으로 수정합니다.
전달 된 모든 vnode는 이전 호출에서 patch 로의 결과 Vnode 여야합니다. Snabbdom이 vnode에 정보를 저장하기 때문에 이것은 필요합니다. 이를 통해 더 간단하고 성능이 좋은 아키텍처를 구현할 수 있습니다. 이것은 또한 새로운 오래된 vnode 트리의 생성을 피합니다.
patch ( oldVnode , newVnode ) ; 마운트 포인트 요소에서 vnode 트리를 제거하기위한 API는 없지만, 거의 달성하는 한 가지 방법은 patch 과 같은 두 번째 인수로 주석 vnode를 제공하는 것입니다.
patch (
oldVnode ,
h ( "!" , {
hooks : {
post : ( ) => {
/* patch complete */
}
}
} )
) ;물론 마운트 지점에는 여전히 단일 주석 노드가 있습니다.
h h 사용하여 vnodes를 만드는 것이 좋습니다. 태그/선택기를 문자열, 선택적 데이터 객체 및 선택적 문자열 또는 어린이 배열로 허용합니다.
import { h } from "snabbdom" ;
const vnode = h ( "div#container" , { style : { color : "#000" } } , [
h ( "h1.primary-title" , "Headline" ) ,
h ( "p" , "A paragraph" )
] ) ;fragment (실험)주의 :이 기능은 현재 실험적이며 선택해야합니다. API는 주요 버전 범프없이 변경 될 수 있습니다.
const patch = init ( modules , undefined , {
experimental : {
fragments : true
}
} ) ;주어진 어린이를 포함하는 문서 조각으로 변환되는 가상 노드를 만듭니다.
import { fragment , h } from "snabbdom" ;
const vnode = fragment ( [ "I am" , h ( "span" , [ " a" , " fragment" ] ) ] ) ;toVNodeDOM 노드를 가상 노드로 변환합니다. 특히 기존의 서버 측 패치에 적합한 서버 측 패치에 적합합니다.
import {
init ,
styleModule ,
attributesModule ,
h ,
toVNode
} from "snabbdom" ;
const patch = init ( [
// Initialize a `patch` function with the modules used by `toVNode`
attributesModule // handles attributes from the DOM node
datasetModule , // handles `data-*` attributes from the DOM node
] ) ;
const newVNode = h ( "div" , { style : { color : "#000" } } , [
h ( "h1" , "Headline" ) ,
h ( "p" , "A paragraph" ) ,
h ( "img" , { attrs : { src : "sunrise.png" , alt : "morning sunrise" } } )
] ) ;
patch ( toVNode ( document . querySelector ( ".container" ) ) , newVNode ) ;후크는 DOM 노드의 수명주기에 연결하는 방법입니다. Snabbdom은 풍부한 고리를 제공합니다. 후크는 모듈에 의해 Snabbdom을 확장하기 위해, 가상 노드 수명의 원하는 지점에서 임의 코드를 실행하기위한 일반 코드로 사용됩니다.
| 이름 | 언제 트리거되었습니다 | 콜백에 대한 주장 |
|---|---|---|
pre | 패치 프로세스가 시작됩니다 | 없음 |
init | vnode가 추가되었습니다 | vnode |
create | vnode를 기반으로 DOM 요소가 작성되었습니다. | emptyVnode, vnode |
insert | 요소가 DOM에 삽입되었습니다 | vnode |
prepatch | 요소가 패치 될 예정입니다 | oldVnode, vnode |
update | 요소가 업데이트되고 있습니다 | oldVnode, vnode |
postpatch | 요소가 패치되었습니다 | oldVnode, vnode |
destroy | 요소가 직간접 적으로 제거됩니다 | vnode |
remove | 요소가 DOM에서 직접 제거됩니다 | vnode, removeCallback |
post | 패치 프로세스가 완료되었습니다 | 없음 |
모듈에 대해 다음 후크를 사용할 수 있습니다 : pre , create , update , destroy , remove , post .
다음 후크는 개별 요소의 hook 속성에서 사용할 수 있습니다 : init , create , insert , prepatch , update , postpatch , destroy , remove .
후크를 사용하려면 데이터 객체 인수의 hook 필드로 객체로 전달하십시오.
h ( "div.row" , {
key : movie . rank ,
hook : {
insert : ( vnode ) => {
movie . elmHeight = vnode . elm . offsetHeight ;
}
}
} ) ; init 후크이 후크는 새로운 가상 노드가 발견 된 패치 프로세스 중에 호출됩니다. Snabbdom이 어떤 식 으로든 노드를 처리하기 전에 후크가 호출됩니다. 즉, vnode를 기반으로 DOM 노드를 생성하기 전에.
insert 후크이 후크는 vnode의 dom 요소가 문서에 삽입 되고 나머지 패치 사이클이 완료되면 호출됩니다. 즉,이 후크에서 getBoundingClientRect를 안전하게 사용하는 것과 같이 DOM 측정을 수행 할 수 있으며, 삽입 된 요소의 위치에 영향을 줄 수있는 요소가 변경되지 않음을 알고 있습니다.
remove 후크 요소를 제거 할 수 있습니다. vnode가 DOM에서 제거되면 후크를 호출합니다. 처리 함수는 vnode와 콜백을 모두 수신합니다. 콜백으로 제거를 제어하고 지연시킬 수 있습니다. 후크가 사업을 수행하면 콜백을 호출해야하며 모든 remove 후크가 콜백을 호출 한 후에 만 요소가 제거됩니다.
후크는 요소가 부모로부터 제거 될 때만 트리거됩니다. 제거 된 요소의 자식이 아니라면. 이를 위해 destroy 후크를 참조하십시오.
destroy 후크이 후크는 DOM 요소가 DOM에서 제거되거나 부모가 DOM에서 제거되는 경우 가상 노드에서 호출됩니다.
이 후크와 remove 후크의 차이점을 보려면 예제를 고려하십시오.
const vnode1 = h ( "div" , [ h ( "div" , [ h ( "span" , "Hello" ) ] ) ] ) ;
const vnode2 = h ( "div" , [ ] ) ;
patch ( container , vnode1 ) ;
patch ( vnode1 , vnode2 ) ; 여기에서 destroy 내부 div 요소 와 포함하는 span 요소 모두에 대해 트리거됩니다. 반면, remove 부모로부터 분리되는 유일한 요소이기 때문에 div 요소에서만 트리거됩니다.
예를 들어, 요소를 제거 할 때 애니메이션을 트리거하여 remove 를 사용하여 destroy 후크를 사용하여 제거 된 요소의 어린이의 실종을 추가로 애니메이션 할 수 있습니다.
모듈은 글로벌 리스너를 후크에 등록하여 작동합니다. 모듈은 단순히 사전 매핑 후크 이름입니다.
const myModule = {
create : ( oldVnode , vnode ) => {
// invoked whenever a new virtual node is created
} ,
update : ( oldVnode , vnode ) => {
// invoked whenever a virtual node is updated
}
} ;이 메커니즘을 사용하면 Snabbdom의 동작을 쉽게 확대 할 수 있습니다. 데모를 위해 기본 모듈의 구현을 살펴보십시오.
이것은 핵심 모듈을 설명합니다. 모든 모듈은 선택 사항입니다. JSX 예제는이 라이브러리에서 제공하는 jsx Pragma를 사용하고 있다고 가정합니다.
클래스 모듈은 요소에서 클래스를 동적으로 전환하는 쉬운 방법을 제공합니다. class 데이터 속성의 객체를 기대합니다. 객체는 클래스 이름을 부울에 매핑하여 클래스가 vnode에 머물러야하는지 여부를 나타내는 부울에 매핑해야합니다.
h ( "a" , { class : { active : true , selected : false } } , "Toggle" ) ; JSX에서는 다음과 같은 class 사용할 수 있습니다.
< div class = { { foo : true , bar : true } } />
// Renders as: <div class="foo bar"></div>DOM 요소에서 속성을 설정할 수 있습니다.
h ( "a" , { props : { href : "/foo" } } , "Go to Foo" ) ; JSX에서는 다음과 같은 props 사용할 수 있습니다.
< input props = { { name : "foo" } } />
// Renders as: <input name="foo" /> with input.name === "foo"속성 만 설정할 수 있습니다. 제거되지 않았습니다. 브라우저가 사용자 정의 속성을 추가하고 삭제할 수 있지만이 모듈은 삭제를 시도하지 않습니다. 기본 DOM 특성을 제거 할 수 없기 때문에 이것은 의미가 있습니다. 또한 DOM에 값을 저장하거나 객체를 참조하기 위해 사용자 정의 속성을 사용하는 경우 대신 Data-* 속성을 사용하는 것을 고려하십시오. 아마도 데이터 세트 모듈을 통해.
소품과 동일하지만 DOM 요소의 속성 대신 속성을 설정합니다.
h ( "a" , { attrs : { href : "/foo" } } , "Go to Foo" ) ; JSX에서는 다음과 같은 attrs 사용할 수 있습니다.
< div attrs = { { "aria-label" : "I'm a div" } } />
// Renders as: <div aria-label="I'm a div"></div> setAttribute 사용하여 속성이 추가되고 업데이트됩니다. 이전에 추가/설정되었고 더 이상 attrs 객체에 존재하지 않는 속성의 경우 removeAttribute 사용하여 DOM 요소의 속성 목록에서 제거됩니다.
부울 속성 (예 : disabled , hidden , selected ...)의 경우, 의미는 속성 값 ( true 또는 false )에 의존하지 않지만 대신 DOM 요소의 속성 자체의 존재/부재에 따라 다릅니다. 해당 속성은 모듈에 의해 다르게 처리됩니다. 부울 속성이 거짓 값 ( 0 , -0 , null , false , NaN , undefined 또는 empty string ( "" ))으로 설정된 경우 DOM 요소의 속성 목록에서 속성이 제거됩니다.
DOM 요소에서 사용자 정의 데이터 속성 ( data-* )을 설정할 수 있습니다. 그런 다음 htmlelement.dataset 속성으로 액세스 할 수 있습니다.
h ( "button" , { dataset : { action : "reset" } } , "Reset" ) ; JSX에서는 다음과 같은 dataset 사용할 수 있습니다.
< div dataset = { { foo : "bar" } } />
// Renders as: <div data-foo="bar"></div>스타일 모듈은 HTML을 매끄럽고 매끄럽게 보이게하는 것입니다. 핵심으로 요소에 CSS 속성을 설정할 수 있습니다.
h (
"span" ,
{
style : {
border : "1px solid #bada55" ,
color : "#c0ffee" ,
fontWeight : "bold"
}
} ,
"Say my name, and every colour illuminates"
) ; JSX에서는 다음과 같은 style 사용할 수 있습니다.
< div
style = { {
border : "1px solid #bada55" ,
color : "#c0ffee" ,
fontWeight : "bold"
} }
/>
// Renders as: <div style="border: 1px solid #bada55; color: #c0ffee; font-weight: bold"></div> CSS 사용자 정의 속성 (일명 CSS 변수)이 지원되며, 접두사와 관련이 있어야합니다 --
h (
"div" ,
{
style : { "--warnColor" : "yellow" }
} ,
"Warning"
) ; 속성이 지연되는 것으로 지정할 수 있습니다. 이러한 특성이 변경 될 때마다 다음 프레임 이후까지 변경되지 않습니다.
h (
"span" ,
{
style : {
opacity : "0" ,
transition : "opacity 1s" ,
delayed : { opacity : "1" }
}
} ,
"Imma fade right in!"
) ;이를 통해 요소의 진입을 쉽게 선언 할 수 있습니다.
transition-property 의 all 가치는 지원되지 않습니다.
remove 시 속성을 설정하십시오 remove 속성에 설정된 스타일은 요소가 DOM에서 제거되면 적용됩니다. 적용 스타일은 CSS 전환으로 애니메이션해야합니다. 모든 스타일이 완료되면 애니메이션이 완료되면 요소가 DOM에서 제거됩니다.
h (
"span" ,
{
style : {
opacity : "1" ,
transition : "opacity 1s" ,
remove : { opacity : "0" }
}
} ,
"It's better to fade out than to burn away"
) ;이를 통해 요소 제거를 쉽게 선언 할 수 있습니다.
transition-property 의 all 가치는 지원되지 않습니다.
destroy 에 속성을 설정하십시오 h (
"span" ,
{
style : {
opacity : "1" ,
transition : "opacity 1s" ,
destroy : { opacity : "0" }
}
} ,
"It's better to fade out than to burn away"
) ; transition-property 의 all 가치는 지원되지 않습니다.
이벤트 리스너 모듈은 이벤트 리스너를 첨부하는 강력한 기능을 제공합니다.
듣고 싶은 이벤트의 이름에 해당하는 속성을 on 위해 객체에 객체를 제공하여 vnode의 이벤트에 함수를 첨부 할 수 있습니다. 이벤트가 발생하면 기능이 호출되며 그에 속하는 이벤트 객체로 전달됩니다.
function clickHandler ( ev ) {
console . log ( "got clicked" ) ;
}
h ( "div" , { on : { click : clickHandler } } ) ; JSX에서는 다음 on 사용할 수 있습니다.
< div on = { { click : clickHandler } } />SNABBDOM을 사용하면 렌즈간에 이벤트 핸들러를 교환 할 수 있습니다. 이것은 실제로 DOM에 첨부 된 이벤트 핸들러를 만지지 않고 발생합니다.
그러나이 모듈이 DOM에 대한 이벤트 처리기를 회복하는 데 사용하는 기술 때문에 Vnodes간에 이벤트 처리기를 공유 할 때주의해야합니다 . (일반적으로, 모듈이 주어진 데이터를 돌연변이 할 수 있기 때문에 vnodes간에 데이터를 공유하는 것은 작동하지 않습니다).
특히, 당신은 다음과 같은 일을해서는 안됩니다 .
// Does not work
const sharedHandler = {
change : ( e ) => {
console . log ( "you chose: " + e . target . value ) ;
}
} ;
h ( "div" , [
h ( "input" , {
props : { type : "radio" , name : "test" , value : "0" } ,
on : sharedHandler
} ) ,
h ( "input" , {
props : { type : "radio" , name : "test" , value : "1" } ,
on : sharedHandler
} ) ,
h ( "input" , {
props : { type : "radio" , name : "test" , value : "2" } ,
on : sharedHandler
} )
] ) ; 이러한 경우 많은 경우 배열 기반 처리기를 대신 사용할 수 있습니다 (위에서 설명). 또는 각 노드가 값 on 고유한지 확인하십시오.
// Works
const sharedHandler = ( e ) => {
console . log ( "you chose: " + e . target . value ) ;
} ;
h ( "div" , [
h ( "input" , {
props : { type : "radio" , name : "test" , value : "0" } ,
on : { change : sharedHandler }
} ) ,
h ( "input" , {
props : { type : "radio" , name : "test" , value : "1" } ,
on : { change : sharedHandler }
} ) ,
h ( "input" , {
props : { type : "radio" , name : "test" , value : "2" } ,
on : { change : sharedHandler }
} )
] ) ; SVG는 가상 노드를 생성하기 위해 h 기능을 사용할 때만 작동합니다. SVG 요소는 적절한 네임 스페이스로 자동으로 작성됩니다.
const vnode = h ( "div" , [
h ( "svg" , { attrs : { width : 100 , height : 100 } } , [
h ( "circle" , {
attrs : {
cx : 50 ,
cy : 50 ,
r : 40 ,
stroke : "green" ,
"stroke-width" : 4 ,
fill : "yellow"
}
} )
] )
] ) ;SVG 예제 및 SVG 회전식 예제도 참조하십시오.
특정 브라우저 (예 : IE <= 11)는 SVG 요소에서 classList 속성을 지원하지 않습니다. 클래스 모듈은 내부적으로 classList 사용하므로 클래스리스트 폴리 필드를 사용하지 않는 한이 경우 작동하지 않습니다. (PolyFill을 사용하지 않으려면 속성 모듈과 함께 class 속성을 사용할 수 있습니다).
thunk 함수는 선택기, 펑크를 식별하는 키, vnode를 반환하는 함수 및 가변 양의 상태 매개 변수를 가져옵니다. 호출되면 렌더링 함수는 상태 인수를받습니다.
thunk(selector, key, renderFn, [stateArguments])
renderFn renderFn 변경되거나 [stateArguments] 배열 길이 또는 그 요소가 변경된 경우에만 호출됩니다.
key 선택 사항입니다. selector Thunks 형제들 사이에서 독특하지 않은 경우 공급해야합니다. 이렇게하면 차이가 나올 때 항상 올바르게 일치합니다.
Thunks는 불변의 데이터를 처리 할 때 사용할 수있는 최적화 전략입니다.
숫자를 기반으로 가상 노드를 만들기위한 간단한 기능을 고려하십시오.
function numberView ( n ) {
return h ( "div" , "Number is: " + n ) ;
} 보기는 n 에만 의존합니다. 즉, n 변경되지 않으면 가상 DOM 노드를 생성하고 이전 vnode에 대한 패치가 낭비됩니다. 오버 헤드를 피하기 위해 thunk 도우미 기능을 사용할 수 있습니다.
function render ( state ) {
return thunk ( "num" , numberView , [ state . number ] ) ;
} 실제로 numberView 함수를 호출하는 대신 가상 트리에 더미 vnode 만 배치합니다. snabbdom이 이전 vnode에 대해이 더미 vnode를 패치하면 n 의 값을 비교합니다. n 변경되지 않으면 기존 vnode를 재사용합니다. 이것은 숫자보기와 Diff 프로세스를 완전히 재현하지 않습니다.
여기서보기 기능은 예제 일뿐입니다. 실제로 Thunks는 생성하는 데 상당한 계산 시간이 걸리는 복잡한 견해를 렌더링하는 경우에만 관련이 있습니다.
JSX 단편은 여전히 실험적이며 선택해야합니다. 자세한 내용은 fragment 섹션을 참조하십시오.
tsconfig.json 에 다음 옵션을 추가하십시오.
{
"compilerOptions" : {
"jsx" : " react " ,
"jsxFactory" : " jsx " ,
"jsxFragmentFactory" : " Fragment "
}
} 그런 다음 .tsx 파일 확장자를 사용하고 파일 상단에서 jsx 함수와 Fragment 기능을 가져 오십시오.
import { Fragment , jsx , VNode } from "snabbdom" ;
const node : VNode = (
< div >
< span > I was created with JSX </ span >
</ div >
) ;
const fragment : VNode = (
< >
< span > JSX fragments </ span >
are experimentally supported
</ >
) ;바벨 구성에 다음 옵션을 추가하십시오.
{
"plugins" : [
[
" @babel/plugin-transform-react-jsx " ,
{
"pragma" : " jsx " ,
"pragmaFrag" : " Fragment "
}
]
]
} 그런 다음 파일 상단에서 jsx 함수와 Fragment 기능을 가져옵니다.
import { Fragment , jsx } from "snabbdom" ;
const node = (
< div >
< span > I was created with JSX </ span >
</ div >
) ;
const fragment = (
< >
< span > JSX fragments </ span >
are experimentally supported
</ >
) ; 속성
sel 속성은 vnode의 html 요소를 지정합니다. 선택적으로 # 에 의해 접두사 인 id 각각 a로 접두사가있는 0 이상의 클래스를 지정합니다 . . 구문은 CSS 선택기에서 영감을 받았습니다. 몇 가지 예는 다음과 같습니다.
div#container.bar.baz - ID container 와 클래스 bar 및 baz 있는 div 요소.li - id 나 클래스가없는 li 요소.button.alert.primary - 두 클래스 alert 와 primary 있는 button 요소. 선택기는 정적 이어야합니다. 즉, 요소의 수명에 걸쳐 변경해서는 안됩니다. 동적 id 설정하려면 소품 모듈을 사용하고 동적 클래스를 설정하려면 클래스 모듈을 사용하십시오.
선택기는 정적이므로 Snabbdom은이를 Vnodes ID의 일부로 사용합니다. 예를 들어, 두 아이가 vnodes 인 경우
[ h ( "div#container.padding" , children1 ) , h ( "div.padding" , children2 ) ] ;패치됩니다
[ h ( "div#container.padding" , children2 ) , h ( "div.padding" , children1 ) ] ;그런 다음 Snabbdom은 선택기를 사용하여 vnodes를 식별하고 새로운 DOM 요소를 만드는 대신 DOM 트리에서 다시 주문합니다. 이러한 선택기를 사용하면 많은 경우 키를 지정할 필요가 없습니다.
가상 노드의 .data 속성은 모듈이 생성 될 때 실제 DOM 요소에 액세스하고 조작 할 수있는 정보를 추가 할 수있는 장소입니다. 스타일, CSS 클래스, 속성 등을 추가하십시오.
데이터 객체는 h() 에 대한 (옵션) 두 번째 매개 변수입니다.
예를 들어 h('div', {props: {className: 'container'}}, [...]) 가상 노드를 생성합니다.
( {
props : {
className : "container"
}
} ) ; .data 객체로.
가상 노드의 .children 속성은 생성 중에 h() 에 대한 세 번째 (선택적) 매개 변수입니다. .children 단순히 생성시 부모 dom 노드의 자녀로 추가되어야하는 가상 노드의 배열입니다.
예를 들어 h('div', {}, [ h('h1', {}, 'Hello, World') ])
[
{
sel : "h1" ,
data : { } ,
children : undefined ,
text : "Hello, World" ,
elm : Element ,
key : undefined
}
] ; .children 재산으로.
.text 속성은 텍스트를 소유 한 단일 자식만으로 가상 노드가 생성 될 때 생성되며 document.createTextNode() 만 필요합니다.
예를 들면 h('h1', {}, 'Hello') Hello .text .
가상 노드의 .elm 속성은 SNABBDOM에 의해 생성 된 실제 DOM 노드에 대한 포인터입니다. 이 속성은 후크 및 모듈에서 계산하는 데 매우 유용합니다.
.key 속성은 .data 객체 내부에 키가 제공 될 때 생성됩니다. .key 속성은 불필요한 경우 이전에 존재했던 DOM 노드에 대한 포인터를 유지하는 데 사용됩니다. 이것은 목록 재정렬과 같은 것들에 매우 유용합니다. 키는 객체 내부의 키/값 쌍으로 내부적으로 저장되므로 적절한 조회를 허용하려면 문자열 또는 숫자 여야합니다. 여기서 .key 는 키이고 값은 .elm 속성입니다.
제공된 경우 .key 속성은 형제 요소 중에서 고유해야합니다.
예를 들어, h('div', {key: 1}, []) 값이 1 인 .key 속성의 가상 노드 객체를 만듭니다.
Snabbdom은 저수준 가상 DOM 라이브러리입니다. 응용 프로그램을 구조화하는 방법과 관련하여 무시되지 않습니다.
다음은 SNABBDOM을 사용한 응용 프로그램을 구축하는 방법입니다.
Snabbdom을 사용하여 다른 방식으로 응용 프로그램을 구축하는 경우 공유하십시오.
Snabbdom과 관련된 패키지에는 snabbdom 키워드가 태그되고 NPM에 게시되어야합니다. 쿼리 문자열 keywords:snabbdom 사용하여 찾을 수 있습니다.
Uncaught NotFoundError: Failed to execute 'insertBefore' on 'Node':
The node before which the new node is to be inserted is not a child of this node.
이 오류의 이유는 패치 간의 vnodes를 재사용하기 때문입니다 (코드 예제 참조), SNABBDOM은 가상 DOM 노드 내부의 실제 DOM 노드를 성능 향상으로 전달하므로 패치 간 노드를 재사용하는 것이 지원되지 않습니다.
const sharedNode = h ( "div" , { } , "Selected" ) ;
const vnode1 = h ( "div" , [
h ( "div" , { } , [ "One" ] ) ,
h ( "div" , { } , [ "Two" ] ) ,
h ( "div" , { } , [ sharedNode ] )
] ) ;
const vnode2 = h ( "div" , [
h ( "div" , { } , [ "One" ] ) ,
h ( "div" , { } , [ sharedNode ] ) ,
h ( "div" , { } , [ "Three" ] )
] ) ;
patch ( container , vnode1 ) ;
patch ( vnode1 , vnode2 ) ;객체의 얕은 사본을 만들어이 문제를 해결할 수 있습니다 (여기서는 객체 스프레드 구문 포함) :
const vnode2 = h ( "div" , [
h ( "div" , { } , [ "One" ] ) ,
h ( "div" , { } , [ { ... sharedNode } ] ) ,
h ( "div" , { } , [ "Three" ] )
] ) ;또 다른 솔루션은 공장 기능에서 공유 vnodes를 래핑하는 것입니다.
const sharedNode = ( ) => h ( "div" , { } , "Selected" ) ;
const vnode1 = h ( "div" , [
h ( "div" , { } , [ "One" ] ) ,
h ( "div" , { } , [ "Two" ] ) ,
h ( "div" , { } , [ sharedNode ( ) ] )
] ) ; 풀 요청은 커뮤니티가 피드백을 제공하기 위해 며칠 동안의 기회가 제공 된 후에 합병되어야합니다.