Refactor component structure: move ComponentOptions to main.ts, update package.json, and remove unused files
This commit is contained in:
parent
5a1d8469d6
commit
cd4d195bd4
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"name": "laterano",
|
"name": "laterano",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"main": "dist/index.js",
|
"main": "dist/main.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/main.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc"
|
"build": "tsc"
|
||||||
},
|
},
|
||||||
|
|
32
src/index.ts
32
src/index.ts
|
@ -1,32 +0,0 @@
|
||||||
export default (options: ComponentOptions) => {
|
|
||||||
const { tag, template, style, onMount, onUnmount, onAttributeChanged } = options
|
|
||||||
|
|
||||||
class CustomElement extends HTMLElement {
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
this.attachShadow({ mode: 'open' })
|
|
||||||
this.shadowRoot!.innerHTML = `
|
|
||||||
<style>${style}</style>
|
|
||||||
${template}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
if (onMount) onMount()
|
|
||||||
}
|
|
||||||
|
|
||||||
disconnectedCallback() {
|
|
||||||
if (onUnmount) onUnmount()
|
|
||||||
}
|
|
||||||
|
|
||||||
static get observedAttributes() {
|
|
||||||
return ['data-attribute']
|
|
||||||
}
|
|
||||||
|
|
||||||
attributeChangedCallback(attrName: string, oldValue: string, newValue: string) {
|
|
||||||
if (onAttributeChanged) onAttributeChanged(attrName, oldValue, newValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define(tag, CustomElement)
|
|
||||||
}
|
|
66
src/main.ts
Normal file
66
src/main.ts
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
interface ComponentOptions {
|
||||||
|
tag: string
|
||||||
|
template: string
|
||||||
|
style?: string
|
||||||
|
onMount?: () => void
|
||||||
|
onUnmount?: () => void
|
||||||
|
onAttributeChanged?: (attrName: string, oldValue: string, newValue: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (options: ComponentOptions) => {
|
||||||
|
const { tag, template, style, onMount, onUnmount, onAttributeChanged } = options
|
||||||
|
const componentRegistry = new Map()
|
||||||
|
componentRegistry.set(tag, options)
|
||||||
|
|
||||||
|
const domTree = document.createElement('template')
|
||||||
|
|
||||||
|
class CustomElement extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.attachShadow({ mode: 'open' })
|
||||||
|
this._initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
private _initialize() {
|
||||||
|
if (style) {
|
||||||
|
const styleElement = document.createElement('style')
|
||||||
|
styleElement.textContent = style
|
||||||
|
this.shadowRoot?.appendChild(styleElement)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 text/html 解析,这更适合处理 HTML 模板
|
||||||
|
const parser = new DOMParser()
|
||||||
|
const doc = parser.parseFromString(template, 'text/html')
|
||||||
|
|
||||||
|
// 找到并导入主要内容元素
|
||||||
|
const mainContent = doc.body.firstElementChild
|
||||||
|
if (mainContent) {
|
||||||
|
// 使用 importNode 确保所有事件和属性都被正确复制
|
||||||
|
this.shadowRoot?.appendChild(document.importNode(mainContent, true))
|
||||||
|
} else {
|
||||||
|
// 如果没有根元素,将所有内容放入一个新的 div 中
|
||||||
|
const container = document.createElement('div')
|
||||||
|
container.innerHTML = template
|
||||||
|
this.shadowRoot?.appendChild(container)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
if (onMount) onMount()
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
if (onUnmount) onUnmount()
|
||||||
|
}
|
||||||
|
|
||||||
|
static get observedAttributes() {
|
||||||
|
return ['data-attribute']
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeChangedCallback(attrName: string, oldValue: string, newValue: string) {
|
||||||
|
if (onAttributeChanged) onAttributeChanged(attrName, oldValue, newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define(tag, CustomElement)
|
||||||
|
}
|
8
src/types/ComponentOptions.d.ts
vendored
8
src/types/ComponentOptions.d.ts
vendored
|
@ -1,8 +0,0 @@
|
||||||
interface ComponentOptions {
|
|
||||||
tag: string
|
|
||||||
template: string
|
|
||||||
style?: string
|
|
||||||
onMount?: () => void
|
|
||||||
onUnmount?: () => void
|
|
||||||
onAttributeChanged?: (attrName: string, oldValue: string, newValue: string) => void
|
|
||||||
}
|
|
|
@ -32,7 +32,7 @@
|
||||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||||
"typeRoots": ["./src/types"], /* Specify multiple folders that act like './node_modules/@types'. */
|
// "typeRoots": ["./src/types"], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user