gem 的问题

执行顺序:
  1. parent constructor
  2. parent connectedCallback
  3. parent render
  4. child constructor
  5. child connectedCallback
  6. child render
  7. child mounted
  8. sibling...
  9. parent mounted
  10. ...
  11. parent updated
  12. chidren updated
  13. ...
  14. parent unmounted
  15. 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`