بناء مكونات واجهة المستخدم مع HTML لديك بالفعل.
2 كيلو بايت GZIDED و 6 كيلو بايت مُعزلة! ؟
data في HTML الموجودة لديك < div data-component =" Counter " >
< p data-bind =" state:Counter.count " > 0 </ p >
< button data-action =" click->Counter.decrement " >
-1
</ button >
< button data-action =" click->Counter.increment " >
+1
</ button >
</ div >class JavaScript؟ import { Component } from "domponent" ;
export default class Counter extends Component {
constructor ( el ) {
super ( el ) ;
}
increment ( ) {
this . setState ( { count : this . state . count + 1 } ) ;
}
decrement ( ) {
this . setState ( { count : this . state . count - 1 } ) ;
}
} import { Init } from "domponent" ;
import Counter from "./Counter.js" ;
const config = {
selector : document . getElementById ( "root" ) ,
components : {
Counter
} ,
appCreated : callbackFunction
} ;
new Init ( config ) ;وأنت بخير للذهاب !!
تقوم هذه المكتبة بإعداد طريقة نظيفة وحديثة لتحويل HTML المسبق إلى مكونات واجهة المستخدم. يمكنك بسهولة تنفيذ بعض ربط البيانات ، والتعامل مع نطاق ، ونقل البيانات حولها ، وإنشاء مكونات باستخدام بعض الاتفاقيات في هذا البرنامج النصي. من المفترض أن يكون بديلاً خفيف الوزن للغاية للحافز مع القليل من نكهة الرد (طرق دورة الحياة ، الدعائم وحالة المكون).
لا يتعامل Domponent مع تقديم عرض من جانب العميل خارج المربع ، ولا ينشئ DOM الظاهري ، ولا يختلف عن DOM (على الرغم من أنه يفعل حالة فرق ودعائم). ليس المقصود التعامل مع التوجيه أو حالة التطبيق بأكملها. من المفترض أن تأخذ شظايا HTML (Thymeleaf ، Rails ، Pug ، أيا كان محرك القالب الذي تستخدمه) وإنشاء وظائف قابلة لإعادة الاستخدام في شكل مكونات.
المكون يشبه خروج المغلوب في بعض النواحي:
على عكس Knockoutjs ، مكون:
قصا
HTML
< p > First name: < input data-bind =" value: firstName " /> </ p >
< p > Last name: < input data-bind =" value: lastName " /> </ p >
< h2 > Hello, < span data-bind =" text: fullName " > </ span > ! </ h2 >JS
var ViewModel = function ( first , last ) {
this . firstName = ko . observable ( first ) ;
this . lastName = ko . observable ( last ) ;
this . fullName = ko . pureComputed ( function ( ) {
return ` ${ this . firstName ( ) } ${ this . lastName ( ) } ` ;
} , this ) ;
} ;
ko . applyBindings ( new ViewModel ( "Planet" , "Earth" ) ) ;مكون
HTML
< div data-component =" Hello " data-state =" { " firstName ": "Planet", "lastName": "Earth"}" >
< p > First name: < input data-action =" input->Hello.setFirstName " /> </ p >
< p > Last name: < input data-action =" input->Hello.setLastName " /> </ p >
< h2 > Hello, < span data-bind =" state:Hello.fullName " > </ span > ! </ h2 >
</ div >JS
import { Component } from "domponent" ;
export default class Hello extends Component {
constructor ( conf ) {
super ( conf ) ;
}
setFirstName ( event ) {
this . setState ( { firstName : event . target . value } , ( ) => {
this . setFullName ( ) ;
} ) ;
}
setLastName ( event ) {
this . setState ( { lastName : event . target . value } , ( ) => {
this . setFullName ( ) ;
} ) ;
}
setFullName ( ) {
this . setState ( {
fullName : ` ${ this . state . firstName } ${ this . state . lastName } `
} ) ;
}
}https://tamb.github.io/domponent/
قائمة TODO: https://codesandbox.io/embed/domponent-todo-with-undo-redo-sp3s2؟fontsize=14
العرض التوضيحي المحلي
git clone هذا الريبوnpm installnpm run build:html-dev أو npm run build:html-prod npm install -- save domponent يمكنك استخدام إصدار ES5 عن طريق استيراد هذا الملف domponent/dist/domponent.es5.production.min.js
إذا كنت لا تستخدم جهاز Transpiler ، فمن المستحسن استخدام ES5 UMD. إذن هذا هو رابط JSDelvr:
// production
< script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/domponent@VERSION/dist/domponent.es5.production.min.js" defer > </ script >
// development
< script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/domponent@VERSION/dist/domponent.es5.development.min.js" defer > < / script > ملاحظة: استخدم الكثير أو القليل من هذه المكتبة كما تريد. يمكنك استخدام هذا فقط لسمات data-component data-ref و data-ref-array وجعل اختيار DOM أسهل كثيرًا. يمكنك عمل مكونات عديمة الجنسية مع فئة Exponent . السماء هي الحد. في جوهرها ، DOMPONENT هي مجموعة من فئات الأداة المساعدة لـ HTML.
data-component نستخدم هذا الفتى الشرير لمطابقة اسم المكون مع class المقابلة في كائن تكوين Init
مثال: إذا كان HTML الخاص بك هو data-component="Counter" | يجب أن يكون لديك مكون في التكوين الخاص بك يسمى Counter
data-bind يربط state أو props إلى textContent لعنصر ما أولاً : تحدد ما إذا كنت تريد ربط state أو props data-bind="state:Counter.count" data-bind="props:Counter.count"
data-actionيربط حدث DOM مع طريقة مكون. النظر في ما يلي:
< button data-action =" click->Counter.increment " >
+1
</ button > النصف الأيسر من : يمثل السلسلة الحرفية لحدث DOM للاستماع إليه. النصف الأيمن يتوافق مع طريقة المكون
ملاحظة: يمكنك إضافة مستمعين متعددين مع أنبوب | مثال:
< button data-action =" click->Counter.increment|mouseover->Counter.anotherMethod " >
+1
</ button > يمكنك تمرير خيارات eventListener أيضًا. يجب أن تكون الخيارات بعد أ . بعد طريقة الفصل. يجب فصل الخيارات بفاصلة , .
< button
data-action =" click->Counter.increment.passive,capture|mouseover->Counter.anotherMethod.once,passive "
>
+1
</ button > data-state إذا كنت ترغب في إنشاء إنشاء مكونك مع حالة معينة في الذاكرة ، فيجب عليك إرفاق سمة data-state بعنصر الجذر في مثال المكون:
<div data-component="Counter" data-state='{"count":24, "isEven": true}'>
...
</div>
هذا صحيح. تأخذ data-state أي كائن JSON صالح.
data-ref إذا كنت بحاجة إلى الرجوع إلى عناصر DOM ، فيمكنك استخدام data-ref مثل ذلك:
< div data-ref =" Counter.myElement " > </ div > تحتاج إلى مقدمة المكون الذي يعمل عليه العنصر. ثم يتم تخزينه في كائن المكونات $refs .
يمكنك بعد ذلك الوصول إلى العنصر في Counter باستخدام this.$refs.myElement ضمن مثيل المكون.
data-ref-arrayيمكنك إنشاء مجموعة من العناصر في مكونك بهذه الطريقة:
< div data-ref-array =" Counter.elements " > </ div >
< div data-ref-array =" Counter.elements " > </ div > ثم يتم تخزينه في كائن المكونات $refs . يمكنك الوصول إلى مجموعة العناصر الموجودة في مكونك this.$refs.elements .
data-key هذا اختياري تماما. إنها سلسلة فريدة لكل مثيل مكون.
يستخدم هذا داخليًا لربط الدعائم. لذلك يجب أن تعرف $key للمكون الذي تتلقى الدعائم منه.
< div data-component =" Counter " data-key =" aUniqueKey " >
...
</ div >دعنا نقول أنك تحلق على هذا في لغة التحول الخاصة بك. يجب عليك التأكد من أن مفاتيحك فريدة من نوعها.
# for (let i=0; i < 10 ; i++){
< div data-component =" Counter " key =" `aUniqueKey${i}` " > ... </ div >
} إذا لم تستخدم هذه السمة ، فسيتم تعيين مفتاح فريد لكل مثيل مكون تلقائيًا. يمكن الوصول إليه عبر this.$key
data-props يمكنك مشاركة الحالة من مكون الوالدين props في مكون الطفل. سوف تبدو العلامات هكذا
< div data-component =" Counter " key =" parentCounter " >
< div
data-props =" myAwesomeProp<-parentCounter:ofFive "
data-component =" DisplayAnything "
> </ div >
</ div > الجانب الأيسر من السهم <- هو اسم الدعامة في مكون DisplayAnything . الجانب الأيمن من السهم هو $key للمكون الأصل ، والقولون : واسم قطعة state للوراثة.
يمكنك بعد ذلك استخدام طرق دورة الحياة propsWillUpdate و propsDidUpdate لإجراء تغييرات داخل مكون طفلك.
Component ؟دعنا نستمر مع العداد. الحد الأدنى ل JS اللازم لإنشاء مكون أدناه:
class Counter extends Component {
constructor ( conf ) {
super ( conf ) ;
}
} يضيف super أساليب الأساس والخصائص التي يحتاجها المكون.
لا تحفر الدولة مباشرة. استدعاء this.setState
setState ( stateObject , callbackFunction ) ;هذا مشابه في مفهوم setState React - على الرغم من أنه يتم تنفيذه بشكل مختلف.
يمكنك إضافة حالات افتراضية إلى مكون JS الخاص بك وتجاوزها في DOM
export default class Counter extends Component {
constructor ( conf ) {
super ( conf ) ;
this . state = {
count : parseInt ( this . state . count ) || 0 ,
isEven : this . state . count
? this . state . count % 2 === 0
? true
: false
: true ,
stateFieldFromDOM : this . state . stateFieldFromDOM || "default cat" ,
stateFieldDefault : "default iPhone 11"
} ;
this . setState ( this . state ) ;
} <div data-component="Counter" data-state="{"count": 4, "isEven":true, "stateFieldFromDOM": "some value here"}"
ستجاوز حقول الدولة المذكورة أعلاه حقول ولاية JS الافتراضية.
سيكون ربط القيمة من setState دائمًا إلى textContent . إذا كنت ترغب في استخدام الحالة/الدعائم لتقديم HTML ، فيمكنك إضافة مراقب لتلك القيمة وتحديث عقدة $refs التي ستضم HTML الجديد.
watch ( ) {
return {
count : {
post ( newCount ) {
this . $refs . exclaimCount . innerHTML = `<div class="uppercase"> ${ newcount } !</div>` ;
}
}
}
}فيما يلي الطرق التي يمكنك استخدامها للوصول إلى المكونات في نقاط مختلفة في دورة حياتهم
| طريقة دورة الحياة | سياق | وصف |
|---|---|---|
| الاتصال | مكون/الأسس | قبل أن تقوم المكتبة بتوصيل أي من المكون/الأساسي الخاص بك ولديك الوصول إلى طرق أخرى |
| متصل | مكون/الأسس | بعد أن يتم توصيل المكون/الأساسي وجميع قائمة الأحداث في مكانها |
| فصل | مكون/الأسس | قبل إزالة eventlisteners وحذف المكون/الأسس من الذاكرة |
| propswillupdate | مكون/الأسس | قبل تحديث الدعائم داخل المكون الخاص بك ، لم تحدث أي طفرات DOM |
| propsdidupdate | مكون/الأسس | بعد تحديث الدعائم وتغيرت DOM |
| StateWillUpdate | عنصر | قبل أن تتغير حالة المكون الحالي أو أي من الدعائم المعالين |
| statedidupdate | عنصر | قامت مكونات الطفل ذات الدعائم الموروثة بإجراء معالجة DOM الخاصة بهم وتغيرت حالتها والدعائم |
تحتوي فئات Component Exponent على طريقة watch يجب إرجاع كائن. يتيح لك المراقبون ربط تغييرات قيمة state أو props محددة أثناء حياة المكون. يتيح ذلك عزل منطق الدولة الخاص بك بدلاً من تجميع كل شيء مع stateWillUpdate أو stateDidUpdate أو propsWillUpdate أو propsDidUpdate . هذا يهدف إلى تقليد المراقبين عن كثب في Vue.JS ملاحظة : لا تسمي state و props Fields. هذه ممارسة سيئة وسوف يكسر المراقبين.
watch ( ) {
return {
myField : {
pre ( newValue , oldValue ) {
// my logic
} ,
post ( newValue ) {
// my logic
}
}
}
} يمكنك عرض حقول الحالة المراقبة الخاصة بك في كائن $watchers .
قم بتوسيع فئة Exponent لإنشاء مكون مع props فقط ، فهذا أخف قليلاً من Component . أسرع في توصيل وتناول ذاكرة أقل.
import { Exponent } from 'domponent'
class StatelessThing extends Exponent{
constructor(conf){
super(conf);
}
}
سيكون لديك فقط الوصول إلى:
propsWillUpdatepropsDidUpdate لماذا Exponent ؟؟
لأنه ببساطة يفسر أو يوضح البيانات التي يتم تقديمها ... ويبدو أنها مكون.
سيتم منح المكونات أو الأسس الحقول التالية.
| اسم الحقل | يكتب | وصول | سياق | وصف |
|---|---|---|---|---|
| تطبيق $ | هدف | عام | مكون/الأسس | تطبيق المكون بأكمله |
| $ ب | صفيف | خاص | مكون/الأسس | روابط EventListener للاستخدام الداخلي |
| $ د | هدف | خاص | عنصر | مكونات الوالدين تشير إلى أطفالها |
| مفتاح $ | خيط | عام | مكون/الأسس | معرف فريد لمثيل المكون |
| اسم $ | خيط | عام | مكون/الأسس | اسم نوع المكون |
| $ p | هدف | خاص | مكون/الأسس | مجموعة داخلية من الدعائم ومراجعها DOM |
| الدعائم | هدف | عام | مكون/الأسس | تم تمرير أزواج المفاتيح/القيمة من البيانات |
| جذر $ | عنصر | عام | مكون/الأسس | عقدة DOM الجذر للمكون |
| $ s | هدف | خاص | عنصر | مجموعة داخلية من الحالة ومراجعها DOM |
| ولاية | هدف | عام | عنصر | أزواج المفاتيح/القيمة من البيانات التي يمكن تحديثها |
| مراقبون $ | هدف | عام | عنصر | وظائف التغيير المخزنة ومفتاح الحالة والمفتاح الخاص بالولاية |
Init ؟ هذه الوظيفة تنشئ التطبيق وتسجيل جميع المكونات. هذا يأخذ كائن config كما هو مطلوب الوسيطة:
const config = {
selector : document . getElementById ( "root" ) ,
components : { Counter } ,
appCreated : callbackFunction
} ;
const App = new Init ( config ) ;ثم يكشف الطرق التالية:
والكائنات التالية:
يمكنك أيضًا استبعاد كائن components للتكوين وإنشاء تطبيق بدون أي مكونات لتبدأ.
createComponentparams:
App . createComponent ( document . getElementById ( "added-html" ) , callback ) ; registerparams
App . register ( NewComponent , callback ) ; deleteComponentparams:
data-key أو الوصول إليه داخل المكون عبر this.$key App . deleteComponent ( "my-component-instance-key" , callback ) ; unregisterparams:
App . unregister ( "NewComponent" , callback ) ; لتجنب تصادم سمات data- مع المحددات والمكتبات الأخرى ، إلخ. يمكنك تجاوز أسماء السمات الافتراضية في كائن تكوين التطبيق:
Init ( {
selector : getElementById ( 'root),
components : { Counter } ,
dataAttributes : {
component : 'mynamespace-component' ,
state : 'cool-state' ,
}
} ) ;هذا يعني أن HTML الخاص بك سيبدو هكذا:
< div data-mynamespace-component =" Counter " data-cool-state =' {"count":12} ' >
...
</ div >يمكنك اختياريا تخصيص بناء الجملة الذي تستخدمه في HTML الخاص بك. يمكن تخصيص العناصر التالية.
INHERITS_FROM: '<-',
FROM_COMPONENT: '.',
KEY_VALUE: ':',
MULTIPLE_VALUES: "|",
METHOD_CALL: "->",
LIST: ","
هذا يعني أنه في التكوين الخاص بك يمكنك إضافة:
{
customSyntax : {
LIST : "!" ,
METHOD_CALL : "#"
}
}ويمكن لك HTML استخدام هذا!
عند التطوير مع Domponent ، يضيف استخدام Build Development أخطاء وسجلات مفيدة إلى وحدة التحكم الخاصة بك من Development DOM (هذا الرجل>)؟
أسهل طريقة لاستخدام هذا هو مع الاسم المستعار على WebPack:
resolve : argv . mode === 'development' ? {
alias : {
domponent : 'domponent/dist/domponent.development.js'
}
} : { } ,وبهذه الطريقة ، سيقوم بناء تطوير WebPack بتبديل إصدار الإنتاج من Domponent للإصدار الذي تم رشه بمساعدة DOM.
يمكنك كتابة المكون HTML لمحركات التقلبات المختلفة وإدراجها كجزء/شظايا/مهما كان محركك يشير إلى "قطع HTML".
فيما يلي بعض الأمثلة على كيفية استخدام المكون.
ملاحظة: على الرغم من هذه الاختلافات في بناء الجملة في الترميز ، تذكر أن المكون هو ببساطة فئة JS ✌
PUG SYNTAX مثال ؟
// counter.pug
mixin counter ( count )
div ( data - component = "Counter" data - state = `
{
"count": count,
"isEven": count % 2 === 0
}
` )
p ( data - bind = "state:Counter.count" ) # { count }
button ( data - action = "click->Counter.increment" ) + 1
button ( data - action = "click->Counter.decrement" ) - 1
// usage
+ counter ( 101119 )
+ counter ( 61316 )مثال بناء الجملة Thymeleaf ؟
// counter.html
< div
data-component =" Counter "
th:fragment =" Counter "
th:data-state =' |{"count":${count}, "isEven": ${count % 2 == 0}}| '
>
< p data-bind =" state:Counter.count " th:text =" ${count} " > </ p >
< button data-action =" click->Counter.increment " >
+1
</ button >
< button data-action =" click->Counter.decrement " >
-1
</ button >
</ div >
// usage
< th:block th:replace =" ./counter.html :: Counter(count: 1289) " />
< th:block th:replace =" ./counter.html :: Counter(count: 491) " />مثال بناء جملة الحلاقة ⚔ قريبا ...
Ruby on Rails Syntax مثال ؟ قريباً...
مثال على بناء جملة الشارب ؟ قريباً...
domponent [at] gmail [dot] com ( يرجى استخدام Domponent Support للموضوع أو لن نرد )@domponent