一大波优化
parent
e122462b1e
commit
85d4dbd6a2
147
src/constants.js
147
src/constants.js
|
@ -38,60 +38,129 @@ export const WC_PART = Symbol('wc_path')
|
||||||
export const NO_CHANGE = Symbol('wc-noChange')
|
export const NO_CHANGE = Symbol('wc-noChange')
|
||||||
export const NOTHING = Symbol('wc-nothing')
|
export const NOTHING = Symbol('wc-nothing')
|
||||||
export const __finalized__ = Symbol('finalized')
|
export const __finalized__ = Symbol('finalized')
|
||||||
export const __update__ = Symbol('update')
|
export const __render__ = Symbol('render')
|
||||||
export const __init__ = Symbol('init')
|
export const __init__ = Symbol('init')
|
||||||
export const __props__ = Symbol('props')
|
export const __props__ = Symbol('props')
|
||||||
export const __changed_props__ = Symbol('changed_props')
|
export const __changed_props__ = Symbol('changed_props')
|
||||||
export const __mounted__ = Symbol('mounted')
|
export const __mounted__ = Symbol('mounted')
|
||||||
|
export const __feedback__ = Symbol('feedback')
|
||||||
|
export const __pending__ = Symbol('pending')
|
||||||
|
export const __prop2attr__ = Symbol('prop2attr')
|
||||||
|
export const __attr2prop__ = Symbol('attr2prop')
|
||||||
|
export const __clear_update__ = Symbol('clearupdate')
|
||||||
|
export const __children__ = Symbol('children')
|
||||||
|
export const __updated__ = Symbol('updated')
|
||||||
|
|
||||||
export const RESET_CSS_STYLE = `* {box-sizing: border-box;margin: 0;padding: 0;}::before,::after {box-sizing: border-box;}`
|
export const RESET_CSS_STYLE = `* {box-sizing: border-box;margin: 0;padding: 0;}::before,::after {box-sizing: border-box;}`
|
||||||
|
|
||||||
export const DEFAULT_CONVERTER = {
|
function getDefaultValue(type) {
|
||||||
toAttribute(value, type) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Boolean:
|
|
||||||
// console.log(this, '>>>', value)
|
|
||||||
value = value ? '' : null
|
|
||||||
break
|
|
||||||
case Object:
|
|
||||||
case Array:
|
|
||||||
value = value == null ? value : JSON.stringify(value)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
},
|
|
||||||
fromAttribute(value, type) {
|
|
||||||
let fromValue = value
|
|
||||||
switch (type) {
|
|
||||||
case Boolean:
|
|
||||||
fromValue = value !== null
|
|
||||||
break
|
|
||||||
case Number:
|
case Number:
|
||||||
fromValue = value === null ? null : Number(value)
|
return 0
|
||||||
break
|
|
||||||
|
case Boolean:
|
||||||
|
return false
|
||||||
|
|
||||||
case Object:
|
case Object:
|
||||||
|
return {}
|
||||||
|
|
||||||
case Array:
|
case Array:
|
||||||
try {
|
return []
|
||||||
fromValue = JSON.parse(value)
|
|
||||||
} catch (e) {
|
default:
|
||||||
fromValue = null
|
return ''
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getType(v) {
|
||||||
|
switch (typeof v) {
|
||||||
|
case 'number':
|
||||||
|
return { type: Number, default: v }
|
||||||
|
|
||||||
|
case 'boolean':
|
||||||
|
return { type: Boolean, default: v }
|
||||||
|
|
||||||
|
case 'object':
|
||||||
|
return Array.isArray(v)
|
||||||
|
? { type: Array, default: v }
|
||||||
|
: { type: Object, default: v }
|
||||||
|
|
||||||
|
default:
|
||||||
|
return { type: String, default: v + '' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parsePropsDeclaration(options) {
|
||||||
|
if (options && typeof options === 'object') {
|
||||||
|
if (options.hasOwnProperty('type')) {
|
||||||
|
return Object.assign(
|
||||||
|
{ attribute: true, default: getDefaultValue(options.type) },
|
||||||
|
options
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (options) {
|
||||||
|
case Number:
|
||||||
|
options = { type: Number }
|
||||||
|
break
|
||||||
|
|
||||||
|
case Boolean:
|
||||||
|
options = { type: Boolean }
|
||||||
|
break
|
||||||
|
|
||||||
|
case Object:
|
||||||
|
options = { type: Object }
|
||||||
|
break
|
||||||
|
|
||||||
|
case Array:
|
||||||
|
options = { type: Array }
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
options = getType(options)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return fromValue
|
options.default = options.default || getDefaultValue(options.type)
|
||||||
}
|
options.attribute = true
|
||||||
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
export function notEqual(value, old) {
|
export function fixedValue(value, options) {
|
||||||
return old !== value && (old === old || value === value)
|
switch (options.type) {
|
||||||
}
|
case Number:
|
||||||
|
return +value || 0
|
||||||
|
break
|
||||||
|
|
||||||
export const DEFAULT_PROPERTY_DECLARATION = {
|
case Boolean:
|
||||||
attribute: true,
|
return value === false ? false : value !== null
|
||||||
type: String,
|
break
|
||||||
formater: DEFAULT_CONVERTER,
|
|
||||||
// converter: DEFAULT_CONVERTER,
|
case Object:
|
||||||
reflect: false,
|
if (typeof value === 'object') {
|
||||||
hasChanged: notEqual,
|
return value
|
||||||
default: ''
|
} else {
|
||||||
|
try {
|
||||||
|
return JSON.parse(value)
|
||||||
|
} catch (err) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
case Array:
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
return value
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
return JSON.parse(value)
|
||||||
|
} catch (err) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
return value + ''
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/html.js
16
src/html.js
|
@ -1,9 +1,6 @@
|
||||||
import { WC_PART, NO_CHANGE, NOTHING } from './constants.js'
|
import { WC_PART, NO_CHANGE, NOTHING } from './constants.js'
|
||||||
|
|
||||||
var ENABLE_EXTRA_SECURITY_HOOKS = true
|
var ENABLE_EXTRA_SECURITY_HOOKS = true
|
||||||
var global3 = window
|
|
||||||
var debugLogRenderId = 0
|
|
||||||
var issueWarning2
|
|
||||||
|
|
||||||
var identityFunction = value => value
|
var identityFunction = value => value
|
||||||
var noopSanitizer = (_node, _name, _type) => identityFunction
|
var noopSanitizer = (_node, _name, _type) => identityFunction
|
||||||
|
@ -726,17 +723,12 @@ class ElementPart {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function render(value, container, options) {
|
export function render(value, container, options) {
|
||||||
const renderId = 0
|
let part = container[WC_PART]
|
||||||
const partOwnerNode = options?.renderBefore || container
|
|
||||||
|
|
||||||
let part = partOwnerNode[WC_PART]
|
|
||||||
|
|
||||||
if (part === void 0) {
|
if (part === void 0) {
|
||||||
const endNode = options?.renderBefore || null
|
container[WC_PART] = part = new ChildPart(
|
||||||
|
container.insertBefore(createMarker(), null),
|
||||||
partOwnerNode[WC_PART] = part = new ChildPart(
|
null,
|
||||||
container.insertBefore(createMarker(), endNode),
|
|
||||||
endNode,
|
|
||||||
void 0,
|
void 0,
|
||||||
options !== null && options !== void 0 ? options : {}
|
options !== null && options !== void 0 ? options : {}
|
||||||
)
|
)
|
||||||
|
|
289
src/index.js
289
src/index.js
|
@ -4,29 +4,28 @@
|
||||||
* @date 2023/03/07 18:10:43
|
* @date 2023/03/07 18:10:43
|
||||||
*/
|
*/
|
||||||
import {
|
import {
|
||||||
DEFAULT_CONVERTER,
|
fixedValue,
|
||||||
DEFAULT_PROPERTY_DECLARATION,
|
parsePropsDeclaration,
|
||||||
notEqual,
|
|
||||||
boolMap,
|
boolMap,
|
||||||
__finalized__,
|
__finalized__,
|
||||||
__update__,
|
__render__,
|
||||||
__init__,
|
__init__,
|
||||||
__props__,
|
__props__,
|
||||||
__changed_props__,
|
__changed_props__,
|
||||||
__mounted__
|
__mounted__,
|
||||||
|
__feedback__,
|
||||||
|
__pending__,
|
||||||
|
__prop2attr__,
|
||||||
|
__attr2prop__,
|
||||||
|
__clear_update__,
|
||||||
|
__children__,
|
||||||
|
__updated__
|
||||||
} from './constants.js'
|
} from './constants.js'
|
||||||
import { css, adoptStyles } from './css.js'
|
import { css, adoptStyles } from './css.js'
|
||||||
import { render, html, svg } from './html.js'
|
import { render, html, svg } from './html.js'
|
||||||
import { fire, bind, unbind } from './utils.js'
|
import { nextTick, fire, bind, unbind } from './utils.js'
|
||||||
export {
|
export { $, $$, offset, outsideClick, clearOutsideClick } from './utils.js'
|
||||||
$,
|
export { html, css, svg, bind, unbind, nextTick }
|
||||||
$$,
|
|
||||||
nextTick,
|
|
||||||
offset,
|
|
||||||
outsideClick,
|
|
||||||
clearOutsideClick
|
|
||||||
} from './utils.js'
|
|
||||||
export { html, css, svg, bind, unbind }
|
|
||||||
|
|
||||||
export class Component extends HTMLElement {
|
export class Component extends HTMLElement {
|
||||||
/**
|
/**
|
||||||
|
@ -39,21 +38,12 @@ export class Component extends HTMLElement {
|
||||||
this.finalize()
|
this.finalize()
|
||||||
|
|
||||||
this[__props__].forEach((options, prop) => {
|
this[__props__].forEach((options, prop) => {
|
||||||
if (options) {
|
options.attribute && list.push(prop.toLowerCase())
|
||||||
options.watch && list.push(k.toLowerCase())
|
|
||||||
} else {
|
|
||||||
list.push(k.toLowerCase())
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
static createProperty(name, options = DEFAULT_PROPERTY_DECLARATION) {
|
|
||||||
if (options.state) {
|
|
||||||
options.attribute = false
|
|
||||||
}
|
|
||||||
|
|
||||||
this[__props__].set(name, options)
|
|
||||||
|
|
||||||
|
static createProperty(name, options) {
|
||||||
let key = Symbol(name)
|
let key = Symbol(name)
|
||||||
let descriptor = {
|
let descriptor = {
|
||||||
get() {
|
get() {
|
||||||
|
@ -61,15 +51,18 @@ export class Component extends HTMLElement {
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
let oldValue = this[key]
|
let oldValue = this[key]
|
||||||
|
value = fixedValue(value, options)
|
||||||
|
if (oldValue === value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
this[key] = value
|
this[key] = value
|
||||||
this.requestUpdate(name, oldValue, options)
|
this.requestUpdate(name, oldValue)
|
||||||
},
|
},
|
||||||
enumerable: false
|
enumerable: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this[__props__].set(name, options)
|
||||||
Object.defineProperty(this.prototype, name, descriptor)
|
Object.defineProperty(this.prototype, name, descriptor)
|
||||||
|
|
||||||
// this.prototype[name] = options.default
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理静态声明
|
// 处理静态声明
|
||||||
|
@ -83,187 +76,157 @@ 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) {
|
||||||
|
let options = parsePropsDeclaration(this.props[k])
|
||||||
if (boolMap[k] && k !== boolMap[k]) {
|
if (boolMap[k] && k !== boolMap[k]) {
|
||||||
this.props[boolMap[k]] = this.props[k]
|
|
||||||
delete this.props[k]
|
|
||||||
k = boolMap[k]
|
k = boolMap[k]
|
||||||
}
|
}
|
||||||
this.createProperty(k, this.props[k])
|
this.createProperty(k, options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete this.props
|
delete this.props
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
static __attributeNameForProperty(name, options) {
|
|
||||||
const attribute = options.attribute
|
|
||||||
return attribute === false
|
|
||||||
? void 0
|
|
||||||
: typeof attribute === 'string'
|
|
||||||
? attribute
|
|
||||||
: typeof name === 'string'
|
|
||||||
? name.toLowerCase()
|
|
||||||
: void 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
|
this[__pending__] = false
|
||||||
this.isUpdatePending = false
|
|
||||||
this.__reflectingProperty = null
|
|
||||||
this[__mounted__] = false
|
this[__mounted__] = false
|
||||||
this[__init__]()
|
this[__init__]()
|
||||||
this.created && this.created()
|
this.created()
|
||||||
}
|
}
|
||||||
|
|
||||||
[__init__]() {
|
[__init__]() {
|
||||||
this.__updatePromise = new Promise(res => (this.enableUpdating = res))
|
this.root = this.shadowRoot || this.attachShadow({ mode: 'open' })
|
||||||
|
|
||||||
this[__changed_props__] = new Map() // 记录本次变化的属性
|
this[__changed_props__] = new Map() // 记录本次变化的属性
|
||||||
// 初始化 props
|
// 初始化 props
|
||||||
this.constructor[__props__].forEach((options, prop) => {
|
this.constructor[__props__].forEach((options, prop) => {
|
||||||
this[prop] = options.default
|
this[prop] = options.default
|
||||||
})
|
})
|
||||||
this.requestUpdate()
|
// 若无定义props时, 手动执行一次渲染
|
||||||
|
if (this[__pending__] === false) {
|
||||||
|
this[__pending__] = true
|
||||||
|
this.performUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#getPropOptions(name) {
|
||||||
|
return this.constructor[__props__].get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
this.root = this.shadowRoot || this.attachShadow({ mode: 'open' })
|
|
||||||
|
|
||||||
adoptStyles(this.root, this.constructor.styles)
|
adoptStyles(this.root, this.constructor.styles)
|
||||||
|
|
||||||
this.enableUpdating(true)
|
this[__children__]?.setConnected(true)
|
||||||
|
|
||||||
this.__childPart?.setConnected(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
this.__childPart?.setConnected(false)
|
this[__children__]?.setConnected(false)
|
||||||
}
|
}
|
||||||
attributeChangedCallback(name, _old, value) {
|
// 监听属性变化
|
||||||
this._$attributeToProperty(name, value)
|
attributeChangedCallback(name, old, val) {
|
||||||
}
|
if (old === val) {
|
||||||
__propertyToAttribute(name, value, options = DEFAULT_PROPERTY_DECLARATION) {
|
|
||||||
const attr = this.constructor.__attributeNameForProperty(name, options)
|
|
||||||
if (attr !== void 0 && options.reflect === true) {
|
|
||||||
const converter = options.converter?.toAttribute
|
|
||||||
? options.converter
|
|
||||||
: DEFAULT_CONVERTER
|
|
||||||
const attrValue = converter.toAttribute(value, options.type)
|
|
||||||
|
|
||||||
this.__reflectingProperty = name
|
|
||||||
if (attrValue == null) {
|
|
||||||
this.removeAttribute(attr)
|
|
||||||
} else {
|
|
||||||
this.setAttribute(attr, attrValue)
|
|
||||||
}
|
|
||||||
this.__reflectingProperty = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_$attributeToProperty(name, value) {
|
|
||||||
const ctor = this.constructor
|
|
||||||
const propName = ctor.__attributeToPropertyMap.get(name)
|
|
||||||
if (propName !== void 0 && this.__reflectingProperty !== propName) {
|
|
||||||
const options = ctor.getPropertyOptions(propName)
|
|
||||||
const converter =
|
|
||||||
typeof options.converter === 'function'
|
|
||||||
? { fromAttribute: options.converter }
|
|
||||||
: options.converter?.fromAttribute
|
|
||||||
? options.converter
|
|
||||||
: DEFAULT_CONVERTER
|
|
||||||
this.__reflectingProperty = propName
|
|
||||||
this[propName] = converter.fromAttribute(value, options.type)
|
|
||||||
this.__reflectingProperty = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
requestUpdate(name, oldValue, options) {
|
|
||||||
let shouldRequestUpdate = true
|
|
||||||
if (name !== void 0) {
|
|
||||||
options = options || this.constructor[__props__][name]
|
|
||||||
const hasChanged = options.hasChanged || notEqual
|
|
||||||
if (hasChanged(this[name], oldValue)) {
|
|
||||||
if (!this[__changed_props__].has(name)) {
|
|
||||||
this[__changed_props__].set(name, oldValue)
|
|
||||||
}
|
|
||||||
if (options.reflect === true && this.__reflectingProperty !== name) {
|
|
||||||
if (this.__reflectingProperties === void 0) {
|
|
||||||
this.__reflectingProperties = new Map()
|
|
||||||
}
|
|
||||||
this.__reflectingProperties.set(name, options)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
shouldRequestUpdate = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!this.isUpdatePending && shouldRequestUpdate) {
|
|
||||||
this.__updatePromise = this.__enqueueUpdate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async __enqueueUpdate() {
|
|
||||||
this.isUpdatePending = true
|
|
||||||
try {
|
|
||||||
await this.__updatePromise
|
|
||||||
} catch (e) {
|
|
||||||
Promise.reject(e)
|
|
||||||
}
|
|
||||||
const result = this.scheduleUpdate()
|
|
||||||
if (result != null) {
|
|
||||||
await result
|
|
||||||
}
|
|
||||||
return !this.isUpdatePending
|
|
||||||
}
|
|
||||||
scheduleUpdate() {
|
|
||||||
return this.performUpdate()
|
|
||||||
}
|
|
||||||
performUpdate() {
|
|
||||||
if (!this.isUpdatePending) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
this[__attr2prop__](name, val)
|
||||||
|
}
|
||||||
|
|
||||||
const changedProperties = this[__changed_props__]
|
/**
|
||||||
|
* 处理需要显式渲染到html标签上的属性
|
||||||
|
* 复杂类型永不显式渲染
|
||||||
|
* @param name<String>
|
||||||
|
* @param value<String|Boolean|Number>
|
||||||
|
*/
|
||||||
|
[__prop2attr__](name, value) {
|
||||||
|
let options = this.#getPropOptions(name)
|
||||||
|
|
||||||
|
switch (options.type) {
|
||||||
|
case Number:
|
||||||
|
case String:
|
||||||
|
if (value === null) {
|
||||||
|
this.removeAttribute(name)
|
||||||
|
} else {
|
||||||
|
this.setAttribute(name, value)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
case Boolean:
|
||||||
|
if (value === null || value === false) {
|
||||||
|
this.removeAttribute(name)
|
||||||
|
} else {
|
||||||
|
this.setAttribute(name, '')
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过setAttribute设置的值, 需要转成props
|
||||||
|
* @param name<String>
|
||||||
|
* @param value<String|Boolean|Number>
|
||||||
|
*/
|
||||||
|
[__attr2prop__](name, value) {
|
||||||
|
let options = this.#getPropOptions(name)
|
||||||
|
|
||||||
|
this[name] = fixedValue(value, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 请求更新
|
||||||
|
requestUpdate(name, oldValue) {
|
||||||
|
let shouldUpdate = true
|
||||||
|
|
||||||
|
this[__changed_props__].set(name, this[name])
|
||||||
|
this[__prop2attr__](name, this[name])
|
||||||
|
|
||||||
|
if (this[__pending__] === false) {
|
||||||
|
this[__pending__] = true
|
||||||
|
nextTick(_ => this[__updated__]())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认更新到视图
|
||||||
|
[__updated__]() {
|
||||||
|
if (this[__pending__]) {
|
||||||
try {
|
try {
|
||||||
this[__update__](changedProperties)
|
let props = this[__changed_props__]
|
||||||
this._$didUpdate(changedProperties)
|
this[__render__]()
|
||||||
} catch (e) {
|
this[__feedback__](props)
|
||||||
this.__markUpdated()
|
} catch (err) {
|
||||||
throw e
|
console.error(err)
|
||||||
|
}
|
||||||
|
this[__clear_update__]()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_$didUpdate(changedProperties) {
|
|
||||||
|
// 更新回调反馈
|
||||||
|
[__feedback__](props) {
|
||||||
|
// 初始化时不触发updated回调
|
||||||
if (!this[__mounted__]) {
|
if (!this[__mounted__]) {
|
||||||
this[__mounted__] = true
|
this[__mounted__] = true
|
||||||
this.mounted && this.mounted()
|
this.mounted(props)
|
||||||
|
} else {
|
||||||
|
this.updated(props)
|
||||||
}
|
}
|
||||||
this.updated(changedProperties)
|
|
||||||
}
|
|
||||||
__markUpdated() {
|
|
||||||
this[__changed_props__] = new Map()
|
|
||||||
this.isUpdatePending = false
|
|
||||||
}
|
|
||||||
get updateComplete() {
|
|
||||||
return this.getUpdateComplete()
|
|
||||||
}
|
|
||||||
getUpdateComplete() {
|
|
||||||
return this.__updatePromise
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[__update__](_changedProperties) {
|
[__clear_update__]() {
|
||||||
|
this[__changed_props__] = new Map()
|
||||||
|
this[__pending__] = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染视图
|
||||||
|
[__render__]() {
|
||||||
let htmlText = this.render()
|
let htmlText = this.render()
|
||||||
|
|
||||||
if (this.__reflectingProperties !== void 0) {
|
this[__children__] = render(htmlText, this.root, {
|
||||||
this.__reflectingProperties.forEach((v, k) =>
|
|
||||||
this.__propertyToAttribute(k, this[k], v)
|
|
||||||
)
|
|
||||||
this.__reflectingProperties = void 0
|
|
||||||
}
|
|
||||||
this.__markUpdated()
|
|
||||||
this.__childPart = render(htmlText, this.root, {
|
|
||||||
host: this,
|
host: this,
|
||||||
isConnected: !this[__mounted__] && this.isConnected
|
isConnected: !this[__mounted__] && this.isConnected
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
updated(_changedProperties) {}
|
// 几个生命周期回调
|
||||||
|
created() {}
|
||||||
|
mounted() {}
|
||||||
|
updated() {}
|
||||||
|
|
||||||
$on(type, callback) {
|
$on(type, callback) {
|
||||||
return bind(this, type, callback)
|
return bind(this, type, callback)
|
||||||
|
|
Loading…
Reference in New Issue