diff --git a/src/constants.js b/src/constants.js index d33d830..29a2aee 100644 --- a/src/constants.js +++ b/src/constants.js @@ -35,6 +35,8 @@ const boolMap = Object.create(null) export { boolMap } +export const KEEP_ALIVE = 'keep-alive' // hyphen +export const KEEP_ALIVE_C = 'keepAlive' // camelize export const WC_PART = Symbol('wc_path') export const NOTHING = Symbol('wc-nothing') export const __finalized__ = Symbol('finalized') diff --git a/src/index.js b/src/index.js index 6931504..ae8c6f4 100644 --- a/src/index.js +++ b/src/index.js @@ -7,6 +7,8 @@ import { fixedValue, parsePropsDeclaration, boolMap, + KEEP_ALIVE, + KEEP_ALIVE_C, __finalized__, __props__, __changed_props__, @@ -57,7 +59,7 @@ export class Component extends HTMLElement { this[__props__].forEach((options, prop) => { list.push(options.attrName) }) - return list.concat(this.watches || []) + return list.concat(this.watches || [], KEEP_ALIVE) } static parseAnim() { @@ -96,6 +98,10 @@ export class Component extends HTMLElement { if (this.hasOwnProperty('props')) { for (let k in this.props) { + // 保留关键字, 直接跳过 + if (k === KEEP_ALIVE || k === KEEP_ALIVE_C) { + continue + } let options = parsePropsDeclaration(this.props[k]) let attrName = k.toLowerCase() @@ -121,6 +127,8 @@ export class Component extends HTMLElement { } } + keepAlive = false + constructor() { super() this[__pending__] = false @@ -159,16 +167,16 @@ export class Component extends HTMLElement { let descriptor if (options.type === Array || options.type === Object) { - let proxyValue = this.#createProxy(name, options) + let proxyValue = this.#createProxy(null, options, name) descriptor = { get() { return proxyValue }, set(value) { proxyValue = this.#createProxy( - name, + fixedValue(value, options), options, - fixedValue(value, options) + name ) this.$requestUpdate(name) }, @@ -199,13 +207,13 @@ export class Component extends HTMLElement { Object.defineProperty(this, name, descriptor) } - #createProxy(name, options, newValue) { - return new Proxy(newValue || options.default, { + #createProxy(obj, options = {}, key) { + return new Proxy(obj || options.default, { get: (target, prop, receiver) => { let value = Reflect.get(target, prop, receiver) // 当访问的值是对象时,需要对这个对象也进行代理 if (typeof value === 'object') { - return this.#createProxy(value) + return this.#createProxy(value, {}, key) } return value }, @@ -214,9 +222,10 @@ export class Component extends HTMLElement { return true } let oldValue = target[prop] - Reflect.set(target, key, value, receiver) + Reflect.set(target, prop, value, receiver) + + this.$requestUpdate(key) - this.$requestUpdate(name) if (options.observer) { options.observer.call(this, value, oldValue) } @@ -249,28 +258,36 @@ export class Component extends HTMLElement { } disconnectedCallback() { - this[__children__]?.setConnected(false) + if (this.keepAlive) { + this.deactivated() + } else { + this[__children__]?.setConnected(false) - if (!document.body?.contains(this)) { - let $events = this.$events - if ($events) { - for (let name in $events) { - for (let it of $events[name]) { - unbind(it.el, name, it.listener, it.options) + if (!document.body?.contains(this)) { + let $events = this.$events + if ($events) { + for (let name in $events) { + for (let it of $events[name]) { + unbind(it.el, name, it.listener, it.options) + } } } + if (window.wkitd && this.$store) { + window.wkitd.deassign(this) + } } - if (window.wkitd && this.$store) { - window.wkitd.deassign(this) - } + this.unmounted() } - this.unmounted() } // 监听属性变化 attributeChangedCallback(name, old, val) { if (old === val) { return } + if (name === KEEP_ALIVE) { + this.keepAlive = val !== null + return + } this.#attr2prop(name, val, old) } @@ -368,7 +385,7 @@ export class Component extends HTMLElement { if (this.$animate?.immediate) { this.$animate() } - if (this.__keep_alive__) { + if (this.keepAlive) { nextTick(_ => this.activated()) } nextTick(_ => this.mounted())