Refactor CustomElement implementation: update interface for onMount and onUnmount, enhance setState logic, and rename class to CustomElementImpl
This commit is contained in:
parent
cbd2c67d2d
commit
0aee6488d2
45
src/main.ts
45
src/main.ts
|
@ -1,8 +1,12 @@
|
||||||
|
interface CustomElement extends HTMLElement {
|
||||||
|
setState(key_path: string, value: any): void
|
||||||
|
}
|
||||||
|
|
||||||
interface ComponentOptions {
|
interface ComponentOptions {
|
||||||
tag: string
|
tag: string
|
||||||
template: string
|
template: string
|
||||||
style?: string
|
style?: string
|
||||||
onMount?: () => void
|
onMount?: (this: CustomElement) => void
|
||||||
onUnmount?: () => void
|
onUnmount?: () => void
|
||||||
onAttributeChanged?: (attrName: string, oldValue: string, newValue: string) => void
|
onAttributeChanged?: (attrName: string, oldValue: string, newValue: string) => void
|
||||||
states?: Record<string, any>
|
states?: Record<string, any>
|
||||||
|
@ -13,7 +17,7 @@ export default (options: ComponentOptions) => {
|
||||||
const componentRegistry = new Map()
|
const componentRegistry = new Map()
|
||||||
componentRegistry.set(tag, options)
|
componentRegistry.set(tag, options)
|
||||||
|
|
||||||
class CustomElement extends HTMLElement {
|
class CustomElementImpl extends HTMLElement {
|
||||||
private _states: Record<string, any> = {}
|
private _states: Record<string, any> = {}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -22,7 +26,20 @@ export default (options: ComponentOptions) => {
|
||||||
// copy state from options
|
// copy state from options
|
||||||
this._states = new Proxy({ ...(states || {}) }, {
|
this._states = new Proxy({ ...(states || {}) }, {
|
||||||
set: (target: Record<string, any>, prop: string, value: any) => {
|
set: (target: Record<string, any>, prop: string, value: any) => {
|
||||||
target[prop] = value
|
const valueRoute = prop.split('.')
|
||||||
|
let currentTarget = target
|
||||||
|
for (let i in valueRoute) {
|
||||||
|
const key = valueRoute[i]
|
||||||
|
if (parseInt(i) === valueRoute.length - 1) {
|
||||||
|
currentTarget[key] = value
|
||||||
|
} else {
|
||||||
|
if (!currentTarget[key]) {
|
||||||
|
currentTarget[key] = {}
|
||||||
|
}
|
||||||
|
currentTarget = currentTarget[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`State updated: ${JSON.stringify(this._states)}`)
|
||||||
// TODO: trigger dom updates
|
// TODO: trigger dom updates
|
||||||
// TODO: trigger state update events
|
// TODO: trigger state update events
|
||||||
return true
|
return true
|
||||||
|
@ -62,11 +79,11 @@ export default (options: ComponentOptions) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
if (onMount) onMount()
|
if (onMount) onMount.call(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
if (onUnmount) onUnmount()
|
if (onUnmount) onUnmount.call(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
static get observedAttributes() {
|
static get observedAttributes() {
|
||||||
|
@ -76,7 +93,23 @@ export default (options: ComponentOptions) => {
|
||||||
attributeChangedCallback(attrName: string, oldValue: string, newValue: string) {
|
attributeChangedCallback(attrName: string, oldValue: string, newValue: string) {
|
||||||
if (onAttributeChanged) onAttributeChanged(attrName, oldValue, newValue)
|
if (onAttributeChanged) onAttributeChanged(attrName, oldValue, newValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// state manager
|
||||||
|
setState(key_path: string, value: any) {
|
||||||
|
const valueRoute = key_path.split('.')
|
||||||
|
let currentTarget = this._states
|
||||||
|
for (let i in valueRoute) {
|
||||||
|
const key = valueRoute[i]
|
||||||
|
if (parseInt(i) === valueRoute.length - 1) {
|
||||||
|
currentTarget[key] = value
|
||||||
|
} else {
|
||||||
|
if (!currentTarget[key]) currentTarget[key] = {}
|
||||||
|
currentTarget = currentTarget[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`State updated: ${this._states}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define(tag, CustomElement)
|
customElements.define(tag, CustomElementImpl)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user