调整props定义, 复杂类型改用Proxy

pull/1/head
yutent 2023-08-11 10:18:50 +08:00
parent aca6d75553
commit 9227233d7a
2 changed files with 67 additions and 33 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "wkit", "name": "wkit",
"version": "1.9.7", "version": "1.10.0",
"type": "module", "type": "module",
"description": "A library for building fast, lightweight web components.", "description": "A library for building fast, lightweight web components.",
"main": "dist/index.js", "main": "dist/index.js",

View File

@ -60,32 +60,6 @@ export class Component extends HTMLElement {
return list return list
} }
static createProperty(name, options) {
let key = Symbol(name)
let descriptor = {
get() {
return this[key]
},
set(value) {
let oldValue = this[key]
value = fixedValue(value, options)
if (oldValue === value) {
return
}
this[key] = value
this.$requestUpdate(name, oldValue)
if (options.observer) {
options.observer.call(this, value, oldValue)
}
},
enumerable: false
}
this[__props__].set(name, options)
Object.defineProperty(this.prototype, name, descriptor)
}
static parseAnim() { static parseAnim() {
if (this.hasOwnProperty('animation')) { if (this.hasOwnProperty('animation')) {
let { type = 'fade', duration } = this.animation let { type = 'fade', duration } = this.animation
@ -123,7 +97,8 @@ export class Component extends HTMLElement {
options.attrName = hyphen(k) options.attrName = hyphen(k)
k = camelize(k) k = camelize(k)
} }
this.createProperty(k, options) this[__props__].set(k, options)
// this.createProperty(k, options)
} }
} }
@ -156,16 +131,75 @@ export class Component extends HTMLElement {
enumerable: false enumerable: false
}) })
for (let [prop, options] of this.constructor[__props__]) {
this.createProperty(prop, options)
}
this.created() this.created()
} }
createProperty(name, options) {
let key = Symbol(name)
let descriptor
if (options.type === Array || options.type === Object) {
let proxyValue = this.#createProxy(name, options)
descriptor = {
get() {
return proxyValue
},
set(value) {
proxyValue = this.#createProxy(name, options, value)
this.$requestUpdate(name)
},
enumerable: false
}
} else {
descriptor = {
get() {
return this[key]
},
set(value) {
let oldValue = this[key]
value = fixedValue(value, options)
if (oldValue === value) {
return
}
this[key] = value
this.$requestUpdate(name)
if (options.observer) {
options.observer.call(this, value, oldValue)
}
},
enumerable: false
}
this[key] = options.default
}
Object.defineProperty(this, name, descriptor)
}
#createProxy(name, options, newValue) {
return new Proxy(newValue || options.default, {
set: (target, prop, value) => {
if (prop === 'length' && options.type === Array) {
return true
}
let oldValue = target[prop]
target[prop] = value
this.$requestUpdate(name)
if (options.observer) {
options.observer.call(this, value, oldValue)
}
return true
}
})
}
#init() { #init() {
// 这里重新赋值一次, 用于清除掉因为 observer 修正产生的变化 // 这里重新赋值一次, 用于清除掉因为 observer 修正产生的变化
this[__changed_props__] = new Map() this[__changed_props__] = new Map()
// 初始化 props
this.constructor[__props__].forEach((options, prop) => {
this[prop] = this[prop] === void 0 ? options.default : this[prop]
})
// 若无定义props时, 手动执行一次渲染 // 若无定义props时, 手动执行一次渲染
if (this[__pending__] === false) { if (this[__pending__] === false) {
@ -277,7 +311,7 @@ export class Component extends HTMLElement {
} }
// 请求更新 // 请求更新
$requestUpdate(name, oldValue) { $requestUpdate(name) {
if (name !== void 0) { if (name !== void 0) {
this[__changed_props__].set(name, this[name]) this[__changed_props__].set(name, this[name])
this.#prop2attr(name, this[name]) this.#prop2attr(name, this[name])