使用您已经拥有的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