Bangun komponen UI dengan HTML yang sudah Anda miliki.
2KB Gzipped dan 6KB Minified! ?
data ke dalam HTML yang ada < 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 ) ;Dan Anda baik -baik saja !!
Perpustakaan ini mengatur cara yang bersih dan modern untuk mengubah HTML prahender menjadi komponen UI. Anda dapat dengan mudah menerapkan beberapa pengikatan data, menangani ruang lingkup, melewati data, dan membuat komponen dengan menggunakan beberapa konvensi dalam skrip ini. Ini dimaksudkan untuk menjadi alternatif yang sangat ringan untuk stimulus dengan sedikit rasa bereaksi (metode siklus hidup, alat peraga dan status komponen).
Domponent tidak menangani rendering sisi klien di luar kotak, tidak membuat DOM virtual, tidak berbeda DOM (meskipun tidak ada status berbeda dan alat peraga). Ini tidak dimaksudkan untuk menangani routing atau seluruh status aplikasi. Ini dimaksudkan untuk mengambil fragmen HTML (thymeleaf, rel, pesek, mesin templat apa pun yang Anda gunakan) dan buat fungsionalitas yang dapat digunakan kembali dalam bentuk komponen.
Domponent mirip dengan KO dalam beberapa hal:
Tidak seperti knockoutjs, domponent:
Pukulan knockout
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" ) ) ;Domponen
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/
Daftar TODO: https://codesandbox.io/embed/domponent-todo-with-undo-redo-sp3s2?fontsize=14
Demo lokal
git clone repo ininpm installnpm run build:html-dev atau npm run build:html-prod npm install -- save domponent Anda dapat menggunakan versi ES5 dengan mengimpor file ini domponent/dist/domponent.es5.production.min.js
Jika Anda tidak menggunakan transpiler, disarankan untuk menggunakan ES5 UMD. Jadi inilah tautan 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 > Catatan: Gunakan sebanyak atau sesedikit perpustakaan ini seperti yang Anda inginkan. Anda dapat menggunakan ini hanya untuk data-component , data-ref dan data-ref-array dan membuat pilihan DOM Anda jauh lebih mudah. Anda dapat membuat komponen stateless dengan kelas Exponent . Langit adalah batasnya. Pada intinya, DOMPONENT adalah seperangkat kelas utilitas untuk HTML Anda.
data-component Kami menggunakan bocah nakal ini untuk mencocokkan nama komponen dengan class yang sesuai di objek konfigurasi Init
Contoh: Jika HTML Anda adalah data-component="Counter" | Anda harus memiliki komponen di konfigurasi Anda yang disebut Counter
data-bind Mengikat state atau props dengan textContent dari suatu elemen terlebih dahulu Anda menentukan jika Anda ingin mengikat state atau props data-bind="state:Counter.count" atau data-bind="props:Counter.count" Props : counter.
data-actionMengikat acara DOM dengan metode komponen. Pertimbangkan yang berikut:
< button data-action =" click->Counter.increment " >
+1
</ button > Setengah kiri dari : mewakili string literal untuk acara DOM untuk mendengarkan. Setengah kanan sesuai dengan metode komponen
Catatan: Anda dapat menambahkan beberapa pendengar dengan pipa | contoh:
< button data-action =" click->Counter.increment|mouseover->Counter.anotherMethod " >
+1
</ button > Anda dapat melewati opsi eventListener juga. Opsi harus setelah a . setelah metode kelas. Opsi harus dipisahkan oleh koma , .
< button
data-action =" click->Counter.increment.passive,capture|mouseover->Counter.anotherMethod.once,passive "
>
+1
</ button > data-state Jika Anda ingin instantiate komponen Anda dengan keadaan tertentu dalam memori, Anda harus melampirkan atribut data-state ke elemen root dari contoh komponen:
<div data-component="Counter" data-state='{"count":24, "isEven": true}'>
...
</div>
Itu benar. data-state mengambil objek JSON yang valid.
data-ref Jika Anda perlu referensi elemen DOM, Anda dapat menggunakan data-ref seperti:
< div data-ref =" Counter.myElement " > </ div > Anda perlu mengawali komponen mana elemen itu aktif. Ini kemudian disimpan dalam objek komponen $refs .
Anda kemudian dapat mengakses elemen di Counter menggunakan this.$refs.myElement dalam instance komponen.
data-ref-arrayAnda dapat membuat serangkaian elemen dalam komponen Anda dengan cara ini:
< div data-ref-array =" Counter.elements " > </ div >
< div data-ref-array =" Counter.elements " > </ div > Ini kemudian disimpan dalam objek komponen $refs . Anda dapat mengakses array elemen dalam komponen Anda dengan this.$refs.elements .
data-key Ini benar -benar opsional. Ini adalah string unik untuk setiap instance komponen.
Ini digunakan secara internal untuk mengikat alat peraga. Oleh karena itu Anda harus mengetahui $key dari komponen tempat Anda menerima alat peraga.
< div data-component =" Counter " data-key =" aUniqueKey " >
...
</ div >Katakanlah Anda mengulangi ini dalam bahasa templating Anda. Anda harus memastikan kunci Anda unik.
# for (let i=0; i < 10 ; i++){
< div data-component =" Counter " key =" `aUniqueKey${i}` " > ... </ div >
} Jika Anda tidak menggunakan atribut ini, kunci unik akan ditetapkan untuk setiap instance komponen secara otomatis. Itu dapat diakses melalui this.$key
data-props Anda dapat berbagi keadaan dari komponen induk sebagai props dalam komponen anak. Markup akan terlihat seperti ini
< div data-component =" Counter " key =" parentCounter " >
< div
data-props =" myAwesomeProp<-parentCounter:ofFive "
data-component =" DisplayAnything "
> </ div >
</ div > Sisi kiri panah <- adalah nama prop di komponen DisplayAnything . Sisi kanan panah adalah $key dari komponen induk, usus besar : dan nama bagian state untuk diwariskan.
Anda kemudian dapat menggunakan metode siklus hidup propsWillUpdate dan propsDidUpdate untuk membuat perubahan dalam komponen anak Anda.
Component ?Mari kita lanjutkan dengan Counter. JS minimum yang diperlukan untuk membuat komponen di bawah ini:
class Counter extends Component {
constructor ( conf ) {
super ( conf ) ;
}
} super menambahkan metode dan sifat dasar yang dibutuhkan komponen Anda.
Jangan bermutasi secara langsung. Sebut this.setState
setState ( stateObject , callbackFunction ) ;Ini serupa dalam konsep dengan SetState React - meskipun diimplementasikan secara berbeda.
Anda dapat menambahkan status default ke komponen JS Anda dan mengesampingkannya di 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"}"
Bidang negara bagian di atas akan mengesampingkan bidang negara JS default.
Ikatan nilai dari setState akan selalu ke textContent . Jika Anda ingin menggunakan status/alat peraga untuk membuat HTML, Anda dapat menambahkan pengamat untuk nilai itu dan memperbarui simpul $refs yang akan menampung HTML baru.
watch ( ) {
return {
count : {
post ( newCount ) {
this . $refs . exclaimCount . innerHTML = `<div class="uppercase"> ${ newcount } !</div>` ;
}
}
}
}Berikut ini adalah metode yang dapat Anda gunakan untuk mengakses komponen di berbagai titik dalam siklus hidup mereka
| Metode siklus hidup | Konteks | Keterangan |
|---|---|---|
| menghubungkan | Komponen/eksponen | Sebelum perpustakaan kabel salah satu komponen/eksponen Anda dan Anda memiliki akses ke metode lain |
| terhubung | Komponen/eksponen | Setelah komponen/eksponen Anda terhubung dan semua EventListeners ada di tempatnya |
| memutuskan hubungan | Komponen/eksponen | Sebelum menghapus EventListeners dan menghapus komponen/eksponen dari memori |
| Propswillupdate | Komponen/eksponen | Sebelum alat peraga diperbarui dalam komponen Anda, tidak ada mutasi DOM yang terjadi |
| Propsdidupdate | Komponen/eksponen | Setelah alat peraga diperbarui dan DOM telah berubah |
| statewillupdate | Komponen | Sebelum keadaan komponen saat ini atau alat peraga tanggungannya telah berubah |
| dinyatakan diM - | Komponen | Komponen anak dengan alat peraga yang diwarisi telah melakukan manipulasi DOM dan negara bagian dan alat peraga telah berubah |
Kelas Component dan Exponent memiliki metode watch yang harus mengembalikan objek. Pengamat memungkinkan Anda untuk menghubungkan ke state tertentu atau perubahan nilai props selama hidup komponen. Hal ini memungkinkan logika negara Anda untuk diisolasi alih -alih menggumpal semuanya dengan stateWillUpdate , stateDidUpdate , propsWillUpdate atau propsDidUpdate . Ini dimaksudkan untuk meniru pengamat di Vue.JS Catatan : Jangan beri nama state Anda dan props yang sama. Ini adalah praktik yang buruk dan akan menghancurkan pengamat.
watch ( ) {
return {
myField : {
pre ( newValue , oldValue ) {
// my logic
} ,
post ( newValue ) {
// my logic
}
}
}
} Anda dapat melihat bidang negara yang ditonton di objek komponen $watchers .
Perpanjang kelas Exponent untuk membuat komponen dengan hanya props ini sedikit lebih ringan dari Component . Lebih cepat untuk dipenuhi dan mengambil lebih sedikit ingatan.
import { Exponent } from 'domponent'
class StatelessThing extends Exponent{
constructor(conf){
super(conf);
}
}
Anda kemudian hanya akan memiliki akses ke:
propsWillUpdatepropsDidUpdate Mengapa Exponent ??
Karena itu hanya menafsirkan atau menguraikan data yang diberikan ... dan kedengarannya seperti komponen.
Komponen atau eksponen akan diberikan bidang berikut.
| Nama Lapangan | Jenis | Mengakses | Konteks | Keterangan |
|---|---|---|---|---|
| $ Aplikasi | obyek | publik | Komponen/eksponen | Seluruh aplikasi domponen |
| $ b | array | pribadi | Komponen/eksponen | Binding EventListener untuk penggunaan internal |
| $ d | obyek | pribadi | Komponen | Komponen orang tua merujuk pada anak -anaknya |
| $ key | rangkaian | publik | Komponen/eksponen | Pengidentifikasi unik untuk instance komponen |
| $ name | rangkaian | publik | Komponen/eksponen | Nama jenis komponen |
| $ p | obyek | pribadi | Komponen/eksponen | Koleksi internal alat peraga dan referensi DOM -nya |
| alat peraga | obyek | publik | Komponen/eksponen | Kunci/nilai pasangan data yang dilewati |
| $ root | elemen | publik | Komponen/eksponen | Simpul dom root dari komponen |
| $ s | obyek | pribadi | Komponen | Koleksi internal negara dan referensi DOM -nya |
| negara | obyek | publik | Komponen | Kunci/nilai pasangan data yang dapat diperbarui |
| $ Watcher | obyek | publik | Komponen | Fungsi perubahan yang disimpan dan status masing -masing dan kunci prop mereka |
Init ? Fungsi ini membuat aplikasi dan mendaftarkan semua komponen. Ini mengambil objek config sebagai argumen yang diperlukan:
const config = {
selector : document . getElementById ( "root" ) ,
components : { Counter } ,
appCreated : callbackFunction
} ;
const App = new Init ( config ) ;Itu kemudian memperlihatkan metode berikut:
Dan benda -benda berikut:
Anda juga dapat mengecualikan objek components konfigurasi dan membuat aplikasi tanpa komponen apa pun untuk memulai.
createComponent@params:
App . createComponent ( document . getElementById ( "added-html" ) , callback ) ; register@params
App . register ( NewComponent , callback ) ; deleteComponent@params:
data-key atau diakses di dalam komponen melalui this.$key App . deleteComponent ( "my-component-instance-key" , callback ) ; unregister@params:
App . unregister ( "NewComponent" , callback ) ; Untuk menghindari data- atribut yang berbenturan dengan pemilih lain, pustaka, dll. Anda dapat mengganti nama atribut default di objek konfigurasi aplikasi:
Init ( {
selector : getElementById ( 'root),
components : { Counter } ,
dataAttributes : {
component : 'mynamespace-component' ,
state : 'cool-state' ,
}
} ) ;Ini berarti bahwa HTML Anda akan terlihat seperti ini:
< div data-mynamespace-component =" Counter " data-cool-state =' {"count":12} ' >
...
</ div >Anda secara opsional dapat menyesuaikan sintaks yang Anda gunakan di HTML Anda. Item berikut dapat disesuaikan.
INHERITS_FROM: '<-',
FROM_COMPONENT: '.',
KEY_VALUE: ':',
MULTIPLE_VALUES: "|",
METHOD_CALL: "->",
LIST: ","
Ini berarti bahwa dalam konfigurasi Anda, Anda dapat menambahkan:
{
customSyntax : {
LIST : "!" ,
METHOD_CALL : "#"
}
}Dan HTML Anda dapat menggunakan ini!
Saat berkembang dengan domponent, menggunakan pembangunan pengembangan menambah kesalahan dan log yang bermanfaat ke konsol Anda dari DOM pengembangan (orang ini->)?
Cara termudah untuk menggunakan ini adalah dengan alias webpack:
resolve : argv . mode === 'development' ? {
alias : {
domponent : 'domponent/dist/domponent.development.js'
}
} : { } ,Dengan cara ini pembangunan webpack Anda akan menukar versi produksi DOMPONENT untuk versi yang ditaburkan dengan bantuan dari DOM.
Anda dapat menulis komponen HTML Anda untuk berbagai mesin templating dan memasukkannya sebagai parsial/fragmen/apa pun yang disebut mesin Anda sebagai "potongan HTML".
Berikut adalah beberapa contoh bagaimana Anda dapat menggunakan domponen.
Catatan: Terlepas dari perbedaan sintaks ini dalam markup, ingatlah bahwa komponennya hanyalah kelas JS ✌️
Contoh Sintaks Pug ?
// 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 )Contoh sintaks 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) " />Contoh sintaksis pisau cukur ⚔️ Segera hadir ...
Contoh Sintaks Ruby on Rails ? segera hadir...
Contoh sintaks kumis ? segera hadir...
domponent [at] gmail [dot] com ( Silakan gunakan Domponent Support subjek atau kami tidak akan merespons )@domponent