gem 的问题
执行顺序:
- parent constructor
- parent connectedCallback
- parent render
- child constructor
- child connectedCallback
- child render
- child mounted
- sibling...
- parent mounted
- ...
- parent updated
- chidren updated
- ...
- parent unmounted
- chidren unmounted
global style // 构造样式表,需要内置?
style 元素不能覆盖 adoptedStyle 的样式 // 必须使用 important
不能扩展自内置(a, dialog)元素 // 类型不知道写
attachShadow 选项 // 可以替代
state 的深度数据更改时并不一定能触发 UI 更新
// 整条数据链更新
// 扁平 state
// 所有组件绑定 state // 经过一些操作变成了 react 的更新方式
ref 不能穿透 shadowdom // 需要改用 lit 2.0
元素依赖不能很好的具备 IDE 支持 // 需要手动添加和删除依赖
元素名称更新时需要使用替换 // 受限于模版的写法
依赖运行时,一些计算(比如构造样式表)造成不必要的性能消耗
没有冒泡的 "mouseover" 事件了 // 因为在一个元素内部
ParentNode.append 等方法操作已挂载的 gem 元素时,不会触发 unmounted, mounted 回调(会触发 disconnectCallback/connectCallback)
ts 中用字段来标记的 attr 也会被当成 prop
// attr/prop 全部用 prop 的写法来写
扩展自 HTMLElement、GemElement,HTMLElement、GemElement 的 attr、属性、方法、事件不能覆盖
// 使用私有 # 字段/方法
用模版字符串手写 HTML 时 attribute 的值必须写引号,不然值为空字符时解析不符合预期
同样具有 OOP 的问题:https://zhuanlan.zhihu.com/p/46207044
- 基类方法被覆盖 // 使用私有字段
- 基类,子类方法调用凌乱
- 方法 this 绑定 // 使用类字段
同一功能的代码写在不同的地方(生命周期中)// effect 方法类似 react effect hooks
effect 的依赖写法复杂(返回数组的函数)
lit-html 语法复杂:if 块、list
gem 元素内不要直接修改公开的 attr/prop(有可能造成更新死循环),但是 constructor,字段上可以这么做,当然 css state 往往需要内部修改
// gem 初始化 history 的 replace 将导致 electron webContents 崩溃
DOM 有 attr 和 prop 之分,attr 表示语义,prop 表示 js 对象属性,DOM 的有些 attr 和 prop 是同步的,有些不是
// string|boolean|number 类型的属性用 attr,否则使用 prop
为了统一开发体验,最佳实践是所有 attr 能像 prop 一样访问和设置。在 gem 中是在 constructor 中读取 observedAttributes 列表定义成访问器属性来实现的。问题:
- 并不是所有 attr 都能直接读取, 没有 observedAttributes 的 attr 只能 get/setAttribute
- attr 和 prop 名字重叠
- attr 要支持 lit-plugin 需要再写一份标记注释
- observed* 似乎有些多余, 没有写在 observedAttributes 中时直接访问得到的是 prop,且难以排查
- observedAttributes 合并原型链上的值
解决方案:使用装饰器。新问题:
- 装饰器字段通常都有默认值,但是 prop 装饰器没有 // 因为类型不确定
- 使用 TS 装饰器时不能使用 ES2022 私有字段 // 必须关闭 `useDefineForClassFields`
- 使用 ES 装饰器时必须插入文档才能正确读取属性
// 除了 property,其他元素内部装饰器都将描述符转为烤串格式
// React 事件监听无脑添加 on 前缀,比如 `onroute-change`