修复复杂类型属性的监听;调整keepAlive设定

master
yutent 2023-09-19 11:53:10 +08:00
parent eebe3c63fc
commit cf344bcd4b
2 changed files with 40 additions and 21 deletions

View File

@ -35,6 +35,8 @@ const boolMap = Object.create(null)
export { boolMap } 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 WC_PART = Symbol('wc_path')
export const NOTHING = Symbol('wc-nothing') export const NOTHING = Symbol('wc-nothing')
export const __finalized__ = Symbol('finalized') export const __finalized__ = Symbol('finalized')

View File

@ -7,6 +7,8 @@ import {
fixedValue, fixedValue,
parsePropsDeclaration, parsePropsDeclaration,
boolMap, boolMap,
KEEP_ALIVE,
KEEP_ALIVE_C,
__finalized__, __finalized__,
__props__, __props__,
__changed_props__, __changed_props__,
@ -57,7 +59,7 @@ export class Component extends HTMLElement {
this[__props__].forEach((options, prop) => { this[__props__].forEach((options, prop) => {
list.push(options.attrName) list.push(options.attrName)
}) })
return list.concat(this.watches || []) return list.concat(this.watches || [], KEEP_ALIVE)
} }
static parseAnim() { static parseAnim() {
@ -96,6 +98,10 @@ export class Component extends HTMLElement {
if (this.hasOwnProperty('props')) { if (this.hasOwnProperty('props')) {
for (let k in this.props) { for (let k in this.props) {
// 保留关键字, 直接跳过
if (k === KEEP_ALIVE || k === KEEP_ALIVE_C) {
continue
}
let options = parsePropsDeclaration(this.props[k]) let options = parsePropsDeclaration(this.props[k])
let attrName = k.toLowerCase() let attrName = k.toLowerCase()
@ -121,6 +127,8 @@ export class Component extends HTMLElement {
} }
} }
keepAlive = false
constructor() { constructor() {
super() super()
this[__pending__] = false this[__pending__] = false
@ -159,16 +167,16 @@ export class Component extends HTMLElement {
let descriptor let descriptor
if (options.type === Array || options.type === Object) { if (options.type === Array || options.type === Object) {
let proxyValue = this.#createProxy(name, options) let proxyValue = this.#createProxy(null, options, name)
descriptor = { descriptor = {
get() { get() {
return proxyValue return proxyValue
}, },
set(value) { set(value) {
proxyValue = this.#createProxy( proxyValue = this.#createProxy(
name, fixedValue(value, options),
options, options,
fixedValue(value, options) name
) )
this.$requestUpdate(name) this.$requestUpdate(name)
}, },
@ -199,13 +207,13 @@ export class Component extends HTMLElement {
Object.defineProperty(this, name, descriptor) Object.defineProperty(this, name, descriptor)
} }
#createProxy(name, options, newValue) { #createProxy(obj, options = {}, key) {
return new Proxy(newValue || options.default, { return new Proxy(obj || options.default, {
get: (target, prop, receiver) => { get: (target, prop, receiver) => {
let value = Reflect.get(target, prop, receiver) let value = Reflect.get(target, prop, receiver)
// 当访问的值是对象时,需要对这个对象也进行代理 // 当访问的值是对象时,需要对这个对象也进行代理
if (typeof value === 'object') { if (typeof value === 'object') {
return this.#createProxy(value) return this.#createProxy(value, {}, key)
} }
return value return value
}, },
@ -214,9 +222,10 @@ export class Component extends HTMLElement {
return true return true
} }
let oldValue = target[prop] 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) { if (options.observer) {
options.observer.call(this, value, oldValue) options.observer.call(this, value, oldValue)
} }
@ -249,6 +258,9 @@ export class Component extends HTMLElement {
} }
disconnectedCallback() { disconnectedCallback() {
if (this.keepAlive) {
this.deactivated()
} else {
this[__children__]?.setConnected(false) this[__children__]?.setConnected(false)
if (!document.body?.contains(this)) { if (!document.body?.contains(this)) {
@ -266,11 +278,16 @@ export class Component extends HTMLElement {
} }
this.unmounted() this.unmounted()
} }
}
// 监听属性变化 // 监听属性变化
attributeChangedCallback(name, old, val) { attributeChangedCallback(name, old, val) {
if (old === val) { if (old === val) {
return return
} }
if (name === KEEP_ALIVE) {
this.keepAlive = val !== null
return
}
this.#attr2prop(name, val, old) this.#attr2prop(name, val, old)
} }
@ -368,7 +385,7 @@ export class Component extends HTMLElement {
if (this.$animate?.immediate) { if (this.$animate?.immediate) {
this.$animate() this.$animate()
} }
if (this.__keep_alive__) { if (this.keepAlive) {
nextTick(_ => this.activated()) nextTick(_ => this.activated())
} }
nextTick(_ => this.mounted()) nextTick(_ => this.mounted())