From 59c321c60ee99f399dde1ac38ea2391dfbbe3df2 Mon Sep 17 00:00:00 2001 From: dntzhang Date: Thu, 2 Nov 2023 20:40:42 +0800 Subject: [PATCH] fix(omi): fix props missing of lazy define component --- packages/omi/examples/lazy-define.tsx | 92 +++++++++++++++++++++++++++ packages/omi/package.json | 2 +- packages/omi/src/component.ts | 4 +- packages/omi/src/diff.ts | 2 +- packages/omi/src/index.ts | 2 +- 5 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 packages/omi/examples/lazy-define.tsx diff --git a/packages/omi/examples/lazy-define.tsx b/packages/omi/examples/lazy-define.tsx new file mode 100644 index 0000000000..6aa752c8d3 --- /dev/null +++ b/packages/omi/examples/lazy-define.tsx @@ -0,0 +1,92 @@ +import { render, Signal, tag, Component, h, computed, registerDirective, define } from '@/index' + +import autoAnimate from '@formkit/auto-animate' +registerDirective('auto-animate', autoAnimate) + +type Todo = { text: string, completed: boolean, id: number } + +class TodoApp extends Signal<{ todos: Todo[], filter: string, newItem: string }> { + completedCount: ReturnType + + constructor(todos: Todo[] = []) { + super({ todos, filter: 'all', newItem: '' }) + this.completedCount = computed(() => this.value.todos.filter(todo => todo.completed).length) + } + + addTodo = () => { + // api a + this.value.todos.push({ text: this.value.newItem, completed: false, id: Math.random() }) + this.value.newItem = '' + this.update() + + // api b, same as api a + // this.update((value) => { + // value.todos.push({ text: value.newItem, completed: false }) + // value.newItem = '' + // }) + } + + toggleTodo = (index: number) => { + const todo = this.value.todos[index] + todo.completed = !todo.completed + this.update() + } + + removeTodo = (index: number) => { + this.value.todos.splice(index, 1) + this.update() + } +} + +const todoApp = new TodoApp([ + { text: 'Learn OMI', completed: true, id: 1 }, + { text: 'Learn Web Components', completed: false, id: 2 }, + { text: 'Learn JSX', completed: false, id: 3 }, + { text: 'Learn Signal', completed: false, id: 4 } +]) + +define('todo-list', class TodoList extends Component { + onInput = (event: Event) => { + const target = event.target as HTMLInputElement + todoApp.value.newItem = target.value + } + + render() { + const { todos } = todoApp.value + const { completedCount, toggleTodo, addTodo, removeTodo } = todoApp + return ( + <> + + + { + console.log(el.detail,'installed') + }}> +

Completed count: {completedCount.value}

+ + ) + } +}) + + + +setTimeout(() => { + define('my-el', class TodoList extends Component { + onInput = (event: Event) => { + const target = event.target as HTMLInputElement + todoApp.value.newItem = target.value + } + + render() { + console.log('this.props', this.props) + return
b{this.props.a}b
+ + } + }) + +}, 1000); + + +render({ + console.log('installed') +}} />, document.body) + diff --git a/packages/omi/package.json b/packages/omi/package.json index 8faed4c2fc..c9e297022a 100644 --- a/packages/omi/package.json +++ b/packages/omi/package.json @@ -1,6 +1,6 @@ { "name": "omi", - "version": "7.3.0", + "version": "7.3.1", "scripts": { "start": "vite", "dev-vite": "vite", diff --git a/packages/omi/src/component.ts b/packages/omi/src/component.ts index a7e7052b86..432329944b 100644 --- a/packages/omi/src/component.ts +++ b/packages/omi/src/component.ts @@ -1,3 +1,4 @@ +// @ts-nocheck import { isArray, hyphenate, capitalize, createStyleSheet } from './utils' import { diff } from './diff' import { ExtendedElement } from './dom' @@ -26,7 +27,8 @@ export class Component extends HTMLElement { static isLightDOM: boolean static noSlot: boolean - props: Record + // 不能声明 props,不然懒加载的 props 执行完构造函数会变成 udnefined, 会导致元素升级为自定义元素之前的 props 丢失 + // props: Record prevProps: Record | null elementId: number isInstalled: boolean diff --git a/packages/omi/src/diff.ts b/packages/omi/src/diff.ts index 90f046ecbb..513f4f1e9e 100644 --- a/packages/omi/src/diff.ts +++ b/packages/omi/src/diff.ts @@ -136,7 +136,7 @@ function idiff(dom: ExtendedElement | ExtendedElement[] | null | Text | HTMLElem out = createNode(vnodeName, isForeignObject || isSvgMode) // 如果是组件,需要把 props 传递给组件,不然 install 里拿不到 props if ((out.constructor as typeof Component)?.is === 'Component') { - Object.assign((out as Component).props, vnode.attributes) + Object.assign((out as ExtendedElement).props, vnode.attributes) } if (dom) { // move children into the replacement node diff --git a/packages/omi/src/index.ts b/packages/omi/src/index.ts index d76c8e41f8..91c51d81f5 100644 --- a/packages/omi/src/index.ts +++ b/packages/omi/src/index.ts @@ -10,6 +10,6 @@ export { Signal } from './signal' export { css } from './css-tag' export { mixin } from './options' export { registerDirective } from './directive' -export const version = '7.3.0' +export const version = '7.3.1'