From 9227233d7ae07f915865f562fc6d834385bbc075 Mon Sep 17 00:00:00 2001 From: yutent Date: Fri, 11 Aug 2023 10:18:50 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4props=E5=AE=9A=E4=B9=89,=20?= =?UTF-8?q?=E5=A4=8D=E6=9D=82=E7=B1=BB=E5=9E=8B=E6=94=B9=E7=94=A8Proxy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/index.js | 98 +++++++++++++++++++++++++++++++++++----------------- 2 files changed, 67 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 6bfb6b7..62215ee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wkit", - "version": "1.9.7", + "version": "1.10.0", "type": "module", "description": "A library for building fast, lightweight web components.", "main": "dist/index.js", diff --git a/src/index.js b/src/index.js index bce5046..1a5b9e8 100644 --- a/src/index.js +++ b/src/index.js @@ -60,32 +60,6 @@ export class Component extends HTMLElement { 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() { if (this.hasOwnProperty('animation')) { let { type = 'fade', duration } = this.animation @@ -123,7 +97,8 @@ export class Component extends HTMLElement { options.attrName = hyphen(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 }) + for (let [prop, options] of this.constructor[__props__]) { + this.createProperty(prop, options) + } + 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() { // 这里重新赋值一次, 用于清除掉因为 observer 修正产生的变化 this[__changed_props__] = new Map() - // 初始化 props - this.constructor[__props__].forEach((options, prop) => { - this[prop] = this[prop] === void 0 ? options.default : this[prop] - }) // 若无定义props时, 手动执行一次渲染 if (this[__pending__] === false) { @@ -277,7 +311,7 @@ export class Component extends HTMLElement { } // 请求更新 - $requestUpdate(name, oldValue) { + $requestUpdate(name) { if (name !== void 0) { this[__changed_props__].set(name, this[name]) this.#prop2attr(name, this[name]) -- 2.40.1