使用您已經擁有的HTML構建UI組件。
2KB GZPIPPPPICPENT和6KB縮小! ?
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組件? 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 ) ;你很好!
該庫設置了一種干淨,現代的方式,將Predended HTML轉變為UI組件。您可以通過使用此腳本中的某些約定來輕鬆實現一些數據結合,處理範圍,傳遞數據並創建組件。它本來可以成為具有一些反應風味(生命週期方法,道具和組件狀態)的刺激j的非常非常輕的替代方法。
DOMPONEN不會將客戶端渲染從框開出來,不會創建虛擬DOM,也不會diff dom(儘管它確實具有差異狀態和props)。這並不是要處理路由或整個應用程序狀態。它的目的是採用HTML片段(胸腺,軌道,哈巴狗,無論您使用的任何模板引擎),並以組件的形式創建可重複使用的功能。
在某些方面,Domponent類似於敲除:
與淘汰賽不同,domponent:
昏死
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" ) ) ;domponent
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/
待辦事項列表:https://codesandbox.io/embed/domponent-todo-with-with-undo-redo-sp3s2?fontsize=14
當地演示
git clone這個倉庫npm installnpm run build:html-dev或npm run build:html-prod npm install -- save domponent您可以通過導入此文件domponent/dist/domponent.es5.production.min.js來使用ES5版本
如果您不使用轉板器,建議使用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我們使用這個壞男孩將組件名稱與Init配置對像中的相應class匹配
示例:如果您的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選項。選項必須在a之後.課程方法之後。選項必須由逗號分開,
< 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對像中。
然後,您可以使用this.$refs.myElement操作中的Counter中的元素訪問該元素。
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 ) ;這在概念上與React的Setstate相似 - 儘管實現方式不同。
您可以在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,則可以為該值添加一個觀察者,並更新將容納新HTML的$refs節點。
watch ( ) {
return {
count : {
post ( newCount ) {
this . $refs . exclaimCount . innerHTML = `<div class="uppercase"> ${ newcount } !</div>` ;
}
}
}
}以下方法是您可以用來在其生命週期中各個點訪問組件的方法
| 生命週期法 | 情境 | 描述 |
|---|---|---|
| 連接 | 組件/指數 | 在圖書館啟動您的任何組件/指數之前,您都可以訪問其他方法 |
| 連接 | 組件/指數 | 將您的組件/指數連接起來,所有EventListener都到位 |
| 斷開連接 | 組件/指數 | 在刪除EventListeners並從內存中刪除組件/指數 |
| propswillupdate | 組件/指數 | 在組件中更新道具之前,沒有發生DOM突變 |
| propsdidupdate | 組件/指數 | 道具更新後,DOM已更改 |
| 州意外事件 | 成分 | 在當前組件或其任何受撫養人的道具的狀態發生變化之前 |
| 陳述 | 成分 | 帶有繼承道具的兒童組件已經完成了他們的操縱,狀態和道具已經改變 |
Component和Exponent類具有必須返回對象的watch方法。觀察者允許您在組件生命週期期間掛接特定state或props價值變化。這允許您的狀態邏輯被隔離,而不是將其全部與stateWillUpdate , stateDidUpdate , propsWillUpdate或propsDidUpdate結合在一起。這是為了在Vue.JS中密切模仿觀察者。注意:請勿命名您的state ,並props相同的條件。這是不好的習慣,會打破觀察者。
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 ?
因為它只是解釋或闡述了給出的數據……聽起來像組件。
將為組件或指數提供以下字段。
| 字段名稱 | 類型 | 使用權 | 情境 | 描述 |
|---|---|---|---|---|
| $應用 | 目的 | 民眾 | 組件/指數 | 整個Domponent應用程序 |
| $ b | 大批 | 私人的 | 組件/指數 | EventListener綁定用於內部用途 |
| $ d | 目的 | 私人的 | 成分 | 父母對孩子的參考 |
| $鍵 | 細繩 | 民眾 | 組件/指數 | 組件實例的唯一標識符 |
| $名稱 | 細繩 | 民眾 | 組件/指數 | 組件類型的名稱 |
| $ p | 目的 | 私人的 | 組件/指數 | 道具的內部集合及其DOM參考 |
| 道具 | 目的 | 民眾 | 組件/指數 | 通過的鍵/價值對傳遞 |
| $ root | 元素 | 民眾 | 組件/指數 | 組件的root dom節點 |
| $ s | 目的 | 私人的 | 成分 | 國家內部收集及其DOM參考 |
| 狀態 | 目的 | 民眾 | 成分 | 可以更新的數據對數據對 |
| $觀察者 | 目的 | 民眾 | 成分 | 存儲的變更功能及其各自的狀態和道具密鑰 |
Init功能?此功能創建應用程序並註冊所有組件。這是根據需要的參數進行config對象:
const config = {
selector : document . getElementById ( "root" ) ,
components : { Counter } ,
appCreated : callbackFunction
} ;
const App = new Init ( config ) ;然後,它公開以下方法:
以及以下對象:
您還可以排除配置的components對象,並創建一個無需任何組件的應用程序。
createComponent@params:
App . createComponent ( document . getElementById ( "added-html" ) , callback ) ; register@params
App . register ( NewComponent , callback ) ; deleteComponent@params:
data-key分配或通過this.$key App . deleteComponent ( "my-component-instance-key" , callback ) ; unregister@params:
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開發時,使用開發構建會從開發DOM(這個Guy->)中為您的控制台增加有用的錯誤和日誌嗎?
最簡單的方法是與WebPack別名:
resolve : argv . mode === 'development' ? {
alias : {
domponent : 'domponent/dist/domponent.development.js'
}
} : { } ,這樣,您的WebPack的開發構建將把Domponent的生產版本交換為在DOM的幫助下撒上的版本。
您可以為各種模板引擎編寫組件HTML,並將其作為部分/片段/引擎稱為“ HTML的塊”。
以下是您如何使用Domponent的一些示例。
注意:儘管標記中存在這些語法差異,但請記住,該組件只是JS類✌️
哈巴狗語法示例?
// 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 )胸腺語法示例?
// 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語法示例?即將推出...
鬍鬚語法示例?即將推出...
domponent [at] gmail [dot] com (請使用主題Domponent Support ,否則我們不會響應)@domponent