محرك قالب DOM الظاهري (512 بايت) للمشاريع المدمجة
| أي / الحافة | Firefox | الكروم | سفاري | الأوبرا | IOS Safari | Chrome لنظام Android |
|---|---|---|---|---|---|---|
| الحافة 14+ | 45+ | 49+ | 10+ | 37+ | 10.2+ | 55+ |
يتقترض . بعض المفاهيم من React.js (مثل المكونات القابلة لإعادة الاستخدام و DOM الافتراضية) ويحاول تكرارها مع أصغر البصمة الممكنة ، واستغلال ميزات ES6 JavaScript.
لماذا؟ لأنه مع مثل هذه المكتبة ، يمكنك إنشاء واجهة المستخدم الرسومية القوية في بيئات فضاء ضيقة ، مثل أجهزة إنترنت الأشياء ، حيث إن توفير بايت إضافي مهم فعليًا!
Tiny حسب التصميم : لا ينبغي أن تتجاوز المكتبة أبداً البايت 512 في الحجم. لا يهدف الهدف إلى وجود محرك قالب آخر ، ولكن الحصول على أكبر عدد ممكن من الميزات في 512 بايت. إذا كانت هناك حاجة إلى ميزة جديدة ، فيجب أن يتم تقليل النطاق الآخر.
تم تصميمها للمستقبل : تستغل المكتبة بشكل كبير مواصفات ES6 ، مما يعني أنها غير مدعومة من المتصفحات القديمة. يتم دعمها حاليًا من قبل 90 ٪ من المتصفحات في السوق ، ولكنها تتوقع أن يكون هذا قريبًا من 100 ٪ خلال العام المقبل.
التصريح : صف HTML DOM بطريقة طبيعية منظمة ، مما يساعدك على إنشاء واجهات مستخدم قوية وقابلة للقراءة.
الموجهة نحو المكون : تمامًا مثل React.js ، يعزز .dom استخدام المكونات الوظيفية.
مسرعات "اكتب أقل" : تم تصميم API المكتبة خصيصًا للحصول على أسماء وظائف قصيرة وأسارع ، مما يتيح لك وصف وجهات نظرك مع كود أقل.
.dom هل تستخدم .dom في مشروعك؟ مفترق هذا المستودع وإضافة لك على القائمة!
للحصول على الحد الأدنى للبصمة ، قم بتضمين dotdom.min.js.gz (512b) لمشروعك.
< script src =" dotdom.min.js.gz " />بدلاً من ذلك ، يمكنك فقط تضمين الإصدار المصغر من المكتبة مباشرة قبل البرنامج النصي. فقط نسخ الصغار الكود المصقول.
إذا كنت تعرف بالفعل React.js ، يمكن أن تساعدك الأمثلة التالية على فهم كيفية ارتباط Primitives Primitives بالرد.
تقديم بنية دوم بسيطة للغاية.
| رد فعل | .dom |
|---|---|
ReactDOM . render (
React . createElement ( 'div' , null , 'Hello world' ) ,
document . body
) ; | R (
H ( 'div' , 'Hello world' ) ,
document . body
) |
إنشاء مكون يمكنك تمرير الخصائص عليه.
| رد فعل | .dom |
|---|---|
function Hello ( props ) {
return React . createElement (
'div' , null , `Hello ${ props . toWhat } `
) ;
}
ReactDOM . render (
React . createElement (
Hello , { toWhat : 'World' } , null
) ,
document . body
) ; | function Hello ( props ) {
return H ( 'div' , `Hello ${ props . toWhat } ` ) ;
}
R (
H ( Hello , { toWhat : 'World' } ) ,
document . body
) |
إنشاء مكونات يمكنها الحفاظ على حالتها الخاصة.
| رد فعل | .dom |
|---|---|
class Clickable extends React . Component {
constructor ( ) {
super ( ... arguments ) ;
this . state = {
clicks : 0
} ;
}
render ( ) {
const { clicks } = this . state ;
return React . createElement (
'button' , {
onClick ( ) {
this . setState ( { clicks : clicks + 1 } )
}
} , `Clicked ${ clicks } times`
) ;
}
}
ReactDOM . render (
React . createElement ( 'div' , null ,
React . createElement ( Clickable , null , null ) ,
React . createElement ( Clickable , null , null )
) ,
document . body
) ; | function Clickable ( props , state , setState ) {
const { clicks = 0 } = state ;
return H ( 'button' ,
{
onclick ( ) {
setState ( { clicks : clicks + 1 } )
}
} ,
`Clicked ${ clicks } times`
) ;
}
R (
H ( 'div' ,
H ( Clickable ) ,
H ( Clickable )
) ,
document . body
) |
يمكن للمكون أيضًا الاشتراك في أحداث دورة الحياة:
| رد فعل | .dom |
|---|---|
class WithLifeCycle extends React . Component {
constructor ( ) {
super ( ... arguments ) ;
this . state = {
mounted : "no"
} ;
}
componentDidMount ( ) {
this . setState ( { mounted : "yes" } )
}
render ( ) {
const { mounted } = this . state ;
return React . createElement (
'div' , null , `mounted = ${ mounted } `
) ;
}
}
ReactDOM . render (
React . createElement ( 'div' , null ,
React . createElement ( WithLifeCycle , null , null ) ,
) ,
document . body
) ; | function WithLifeCycle ( props , state , setState , hooks ) {
const { mounted = "no" } = state ;
hooks . m . push ( ( ) => {
setState ( { mounted : "yes" } )
} ) ;
return H ( 'div' ,
`mounted = ${ mounted } `
) ;
}
R (
H ( 'div' , H ( WithLifeCycle ) ) ,
document . body
) |
التحديثات الرئيسية هي ميزة تسوية مفيدة من React تمكن محرك التقديم من اتخاذ قرارات ذكية حول العناصر التي يتم تحديثها.
هناك حالة مفيدة بشكل خاص هي عندما تقوم بتقديم قائمة ديناميكية من العناصر. نظرًا لأن محرك العرض لا يفهم العنصر الذي تغير ، فقد انتهى الأمر بتحديثات خاطئة.
لحل هذه المشكلة ، تستخدم محركات VDOM خاصية key تحدد عنصرًا فريدًا في الشجرة. ومع ذلك ، يحلها ، من خلال الحفاظ على نسخة من حالة العنصر في مثيل عنصر VDOM نفسه.
هذا يعني أنك لا تحتاج إلى أي خاصية key ، فقط تأكد من إرجاع نفس مثيل VDOM كما كان من قبل.
إذا كنت تقوم بإنشاء عناصر ديناميكية (على سبيل المثال ، مجموعة من عناصر VDOM) ، فقد تواجه .DOMD مشكلة في اكتشاف ترتيب التحديث الصحيح.
| رد فعل | .dom |
|---|---|
class Clickable extends React . Component {
constructor ( ) {
super ( ... arguments ) ;
this . state = {
clicks : 0
} ;
}
render ( ) {
const { clicks } = this . state ;
const { ket } = this . props ;
return React . createElement (
'button' , {
onClick ( ) {
this . setState ( { clicks : clicks + 1 } )
}
} , `clicks= ${ clicks } , key= ${ key } `
) ;
}
}
const list = [ "first" , "second" , "third" ] ;
const components = list . map ( key =>
React . createElement ( Clickable , { key } , null ) ;
ReactDOM . render (
React . createElement ( 'div' , null ,
components
) ,
document . body
) ; | function Clickable ( props , state , setState ) {
const { clicks = 0 } = state ;
const { key } = props ;
return H ( 'button' ,
{
onclick ( ) {
setState ( { clicks : clicks + 1 } )
}
} ,
`clicks= ${ clicks } , key= ${ key } `
) ;
}
const list = [ "first" , "second" , "third" ] ;
const components = list . map ( key =>
H ( Clickable , { key } ) ;
R (
H ( 'div' , components ) ,
document . body
) |
لاحظ أن الحل أعلاه سيقوم بتحديث المكونات الحكومية بشكل صحيح ، حتى لو كان ترتيبها قد تغير. ومع ذلك ، إذا كنت تريد الوظائف الكاملة التي تشبه الرد والتي تقوم بتحديث المفاتيح الفردية ، فيمكنك استخدام المكون الإضافي Keyed .
function Container ( props , state ) {
const { components } = props ;
// The function `K` accepts the component state and an array of components that
// contain the `key` property, and returns the same array of components, with their
// state correctly manipulated.
return H ( "div" , K ( state , components ) ) ;
} يمكنك إنشاء عقد VDOM RAW (غير التوفيق) (على سبيل المثال. التي تحمل محتوى HTML تعسفيًا) عن طريق تعيين خاصية .r لكائن الخطافات بأي قيمة الحقيقة.
سيؤدي ذلك إلى تعطيل المزيد من المصالحة للعقد الفرعية ، وبالتالي الحفاظ على محتوياتك سليمة.
function Description ( props , state , setState , hooks ) {
const { html } = props ;
hooks . r = 1 ; // Enable raw mode
return H ( 'div' , {
innerHTML : html
} )
} R( VNode, DOMElement ) R ( H ( 'div' , 'Hello' ) , document . body )يعرض شجرة vnode المعطى إلى عنصر DOM المعطى. لن تحدث تحديثات أخرى من المكونات الحكومية إلا على أطفالهم المباشرين.
H( tagName | function, [properties], [children ...]) H ( 'tag' )
H ( 'tag' , { prop : "value" } )
H ( 'tag' , H ( 'child' ) )
H ( 'tag' , { prop : "value" } , H ( 'child' ) )
H ( Component , { prop : "value" } )يخلق عنصر vnode. إذا تم تمرير سلسلة كوسيطة أولى ، فسيقوم بإنشاء عنصر HTML. إذا تم إعطاء وظيفة ، فسيقوم بإنشاء مكون دولة.
الخصائص والأطفال اختياريين ويمكن حذفها.
بدلاً من اسم العلامة ، يمكنك توفير وظيفة تقوم بإرجاع DOM الظاهري وفقًا لبعض المنطق ذي المستوى الأعلى. هذه الوظيفة لها التوقيع التالي:
const Component = ( props , state , setState , hooks ) {
// Return your Virtual DOM
return div ( ... )
} تحتوي خاصية props على كائن الخصائص كما هو موضح عند إنشاء المكون.
تتم تهيئة state إلى كائن فارغ {} ويتم تحديثه عن طريق استدعاء طريقة setState({ newState }) . سيؤدي هذا الأخير أيضًا إلى تحديث للمكون وأطفاله.
يمكنك أيضًا تعيين خصائص لكائن state مباشرة إذا كنت لا ترغب في التسبب في تحديث.
يمكن استخدام كائن hooks عندما ترغب في تسجيل معالجات على طرق دورة حياة المكون.
على غرار React ، فإن مكونات .dom لها دورة حياة:
للوصول إلى أساليب دورة الحياة ، تحتاج إلى استخدام الوسيطة الرابعة في وظيفة المكون. وبشكل أكثر تحديدًا ، يجب عليك دفع وظيفة المناولة في أي من الحقول التالية:
const Component = ( props , state , setState , hooks ) {
hooks . m . push ( ( domElement ) => {
// '.m' is called when the component is mounted
} ) ;
hooks . u . push ( ( ) => {
// `.u` is called when the component is unmounted
} ) ;
hooks . d . push ( ( domElement , previousDomElement ) => {
// `.d` is called when the component is updated
} ) ;
...
}tag( [properties], [children ...] ) const { div , span , a } = H ;
div ( 'hello' , span ( 'world' ) )
div ( 'click' , a ( { href : '#' } , 'Here' ) , 'to continue' ) يمكن استخراج وظيفة الاختزال كخاصية من وظيفة H تتصرف مثل هذه الاختزال تمامًا مثل H ، ولكن مع اسم العلامة المملوءة بالفعل.
يوصى باستخدام مهمة تفكيك في بداية البرنامج النصي الخاص بك من أجل مساعدة جافا سكريبت المصغرة على تحسين النتيجة:
const {div, span, a, button} = H;
tag.class( [properties], [children ...] ) const { h1 , span , p } = H ;
h1 . short ( 'short header' , span . strong ( 'strong text' ) )
button . primary ( { onclick : handleClick } , 'Primary Action' )
p . bold . italic ( twitterPost ) بدلاً من توفير className كقرة ، يمكنك استخدام اختصار .className مع طرق علامات الاختزال.
هذا هو نفسه استدعاء div({className: 'className'}) وواجهة الوظيفة هي نفسها كما هو مذكور أعلاه.
ملاحظة: يمكنك إضافة أكثر من فئة واحدة عن طريق تسلسل أكثر من واحد .class إلى العلامة. على سبيل المثال: div.foo.bar هو نفسه div({className: 'foo bar'}) .
نظرًا لأن تركيز المشروع هو الحجم الصغير ، فإنه يفتقر إلى فحوصات التعقل. هذا يجعل الأمر عرضة للأخطاء. كن حذرًا جدًا مع التحذيرات التالية:
لا يمكنك تشغيل تحديث مع إزالة خاصية. يجب عليك تعيين الخاصية الجديدة على قيمة فارغة بدلاً من ذلك. على سبيل المثال:
// Wrong
R ( div ( { className : 'foo' } ) , document . body ) ;
R ( div ( { } ) , document . body ) ;
// Correct
R ( div ( { className : 'foo' } ) , document . body ) ;
R ( div ( { className : '' } ) , document . body ) ; يجب ألا تستخدم خاصية تسمى $ في مكوناتك. القيام بذلك ، سيجعل كائن الخاصية يعتبر عقدة DOM افتراضية وسيؤدي إلى نتائج غير متوقعة.
// *NEVER* do this!
R ( H ( MyComponent , { $ : 'Foo' } ) , document . body ) K(state, components)في
plugin-keyed.min.js
يضمن مزامنة حالة المكونات في القائمة ، وفقًا لممتلكاتها key . يمكّنك ذلك من إجراء تحديثات مفتاح تشبه رد الفعل مثل ذلك:
function ValueRenderer ( ... ) {
...
}
function MyComponent ( props , state ) {
const { values } = props ;
const components = values . map ( value => {
H ( ValueRenderer , {
key : value ,
value : value
} ) ;
} )
// Synchronize state of components, based on their key
return H ( 'div' , K ( state , components ) )
} هل أنت مهتم بالمساهمة في .dom ؟ أنت أكثر من موضع ترحيب! فقط تأكد من اتباع الإرشادات:
npm install
npm test && npm run build && ls -l dotdom.min.js.gz
إذا تمرير الاختبارات وحجم dotdom.min.js.gz أصغر من أو يساوي 512 بايت ، قم بإنشاء طلب سحب. بخلاف ذلك ، قلل من نطاقك أو التفكير في تطبيق آخر من أجل إعادته إلى 512 بايت.
تأكد من التعليق بشكل صحيح على رمزك ، حيث من المحتمل أن تضطر إلى القيام ببعض اختراق JavaScript المتطرف. Gudeliens هي ما يلي:
/**
* Functions are commented as JSDoc blocks
*
* @param {VNode|Array<VNode>} vnodes - The node on an array of nodes to render
* ...
*/
global . R = render = (
vnodes , // Flat-code comments start on column 70 and
dom , // wrap after column 120.
/* Logical separations can be commented like this */
...مرخصة بموجب ترخيص Apache ، الإصدار 2.0