Skip to content

Commit

Permalink
fix(omi): fix props missing of lazy define component
Browse files Browse the repository at this point in the history
  • Loading branch information
dntzhang committed Nov 2, 2023
1 parent 6d1870e commit 59c321c
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 4 deletions.
92 changes: 92 additions & 0 deletions packages/omi/examples/lazy-define.tsx
Original file line number Diff line number Diff line change
@@ -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<typeof computed>

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 (
<>
<input type="text" value={todoApp.value.newItem} onInput={this.onInput} />
<button onClick={addTodo}>Add</button>
<my-el a="11" onInstalled={(el)=> {
console.log(el.detail,'installed')
}}></my-el>
<p>Completed count: {completedCount.value}</p>
</>
)
}
})



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 <div>b{this.props.a}b</div>

}
})

}, 1000);


render(<todo-list onInstalled={()=>{
console.log('installed')
}} />, document.body)

2 changes: 1 addition & 1 deletion packages/omi/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "omi",
"version": "7.3.0",
"version": "7.3.1",
"scripts": {
"start": "vite",
"dev-vite": "vite",
Expand Down
4 changes: 3 additions & 1 deletion packages/omi/src/component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
import { isArray, hyphenate, capitalize, createStyleSheet } from './utils'
import { diff } from './diff'
import { ExtendedElement } from './dom'
Expand Down Expand Up @@ -26,7 +27,8 @@ export class Component extends HTMLElement {
static isLightDOM: boolean
static noSlot: boolean

props: Record<string, unknown>
// 不能声明 props,不然懒加载的 props 执行完构造函数会变成 udnefined, 会导致元素升级为自定义元素之前的 props 丢失
// props: Record<string, unknown>
prevProps: Record<string, unknown> | null
elementId: number
isInstalled: boolean
Expand Down
2 changes: 1 addition & 1 deletion packages/omi/src/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion packages/omi/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'


0 comments on commit 59c321c

Please sign in to comment.