WebCell v3 受到了 MobX 的 本地可观察状态 思想 的深刻启发,不仅仅是 React,Web Components 可以更轻松地管理 内部状态和逻辑,无需任何复杂的操作:
this.state 声明及其类型注解/断言this.setState() 方法的调用及其回调只需像管理 全局状态 一样声明一个 状态存储类,并在 this(即 Web Component 实例)上初始化它。然后像 MobX 一样使用并观察这些状态,一切就完成了。
import {
component,
+ observer,
- mixin,
- createCell,
- Fragment
} from 'web-cell';
+import { observable } from 'mobx';
-interface State {
+class State {
+ @observable
- key: string;
+ accessor key = '';
}
@component({ tagName: 'my-tag' })
+@observer
-export class MyTag extends mixin<{}, State>() {
+export class MyTag extends HTMLElement {
- state: Readonly<State> = {
- key: 'value'
- };
+ state = new State();
- render({}: any, { key }: State) {
+ render() {
+ const { key } = this.state;
return <>{value}</>;
}
}
同时,shouldUpdate() {} 生命周期方法已被移除。你只需在 State 类的方法中,在状态改变之前控制逻辑即可。
DOM 属性 不同于 React 的 props,它们是 响应式的。它们不仅负责 更新组件视图,还会与 HTML 属性同步。
MobX 的 @observable 和 reaction() 是实现上述功能的优秀 API,代码也非常清晰,因此我们添加了 mobx 包作为依赖:
npm install mobx
另一方面,mobx-web-cell 适配器 已经合并到了核心包中。
import {
WebCellProps,
component,
attribute,
- watch,
+ observer,
- mixin,
- createCell,
- Fragment
} from 'web-cell';
-import { observer } from 'mobx-web-cell';
+import { observable } from 'mobx';
export interface MyTagProps extends WebCellProps {
count?: number
}
@component({ tagName: 'my-tag' })
@observer
-export class MyTag extends mixin<MyTagProps>() {
+export class MyTag extends HTMLElement {
+ declare props: MyTagProps;
@attribute
- @watch
+ @observable
- count = 0;
+ accessor count = 0;
- render({ count }: MyTagProps) {
+ render() {
+ const { count } = this;
return <>{count}</>;
}
}
mode 选项控制渲染目标childrenimport {
component,
- mixin
} from 'web-cell';
@component({
tagName: 'my-tag',
- renderTarget: 'children'
})
-export class MyTag extends mixin() {
+export class MyTag extends HTMLElement {
}
shadowRootimport {
component,
- mixin
} from 'web-cell';
@component({
tagName: 'my-tag',
- renderTarget: 'shadowRoot'
+ mode: 'open'
})
-export class MyTag extends mixin() {
+export class MyTag extends HTMLElement {
}
render()这样使得 Shadow CSS 可以随着可观察数据的更新而响应。
+import { stringifyCSS } from 'web-utility';
import {
component,
- mixin
} from 'web-cell';
@component({
tagName: 'my-tag',
- renderTarget: 'shadowRoot',
+ mode: 'open',
- style: {
- ':host(.active)': {
- color: 'red'
- }
- }
})
-export class MyTag extends mixin() {
+export class MyTag extends HTMLElement {
render() {
return <>
+ <style>
+ {stringifyCSS({
+ ':host(.active)': {
+ color: 'red'
+ }
+ })}
+ </style>
test
</>;
}
}
mixin() => HTMLElement 及其子类mixinForm() => HTMLElement 和 @formField@watch => @observable accessor