-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[gem] Update docs #182
Comments
v2 介绍经过漫长的开发实践,Gem 终于开始迈入了 v2,Gem 以让用户简单的方式编写自定义元素为宗旨进行了此次迭代。下面将介绍 v2 的一些重大更新。 装饰器v2 使用 ES 装饰器代替了以前的 TS 装饰器,并且将 @customElement('my-element')
+@aria({ foucusable: true, role: 'button' })
+@shadow()
+@asnyc()
class MyElement extends GemElement {
- constructor() {
- super({ focusable: true, isAsync: true, isLight: false });
- this.internals.role = 'button';
- }
} 使用装饰器具有更好的可扩展性,另外也降低了代码复杂度。基于同样的目的,还添加了 @customElement("my-element")
class MyElement extends GemElement {
@attribute name: string;
#content: string;
@memo((myElement) => [myElemnt.name])
#caleContent() {
this.#content = this.name;
}
@effect((myElement) => [myElement.name])
#fetchData() {
// request
}
} Warning 未来 Gem 可能会弃用生命周期回调函数,全面使用装饰器代替 内部状态v1 使用特定的字段 @customElement("my-element")
class MyElement extends GemElement {
#state = createState({ a: true })
render() {
this.#state({ a: false });
console.log(this.#state.a);
}
} Note v2 支持在任意地方更新状态,这在 v1 中将造成死循环 默认使用 Light DOMGem 使用 Shadow DOM 的一个理由是样式隔离性,他让用户可以直接编写“模块化”的 CSS,但是使用 Shadow DOM 编写 WebApp 也有一些缺点:
如果不是写需要高度封装的自定义元素(例如 UI 库),使用 Light DOM 是更合适的选择。现在,CSS 规范带来了 const styles = createCSSSheet(css`
:scope {
display: block;
}
div {
color: red;
}
`);
@customElement('my-element')
@adoptedStyle(styles)
class MyElement extends GemElement {} Note 就像开头的例子,如果想要使用 Shadow DOM,需要添加 主题增强v1 只支持全局主题,v2 支持范围主题,并且支持主题覆盖: // 全局主题将自动添加到 `document`
const [theme] = useTheme({ textColor: '#eee' });
const [scopedTheme] = useScopedTheme({ scopeTextColor: '#333' });
const [overrideTheme] = overrideTheme(theme, { textColor: '#eff' })
const styles = createCSSSheet(css`
:scope {
color: ${theme.textColor};
background: ${scopedTheme.scopeTextColor};
}
`);
@customElement('my-element')
@adoptedStyle(styles)
@adoptedStyle(scopedTheme)
@adoptedStyle(overrideTheme)
class MyElement extends GemElement {} 此外,得益于相对颜色语法,主题中以 一起创造更好的 Gem希望 Gem 能以卓越的设计成为创建自定义元素的首选方案,如果你有任何建议和想法,请创建 Issue。 |
从 React 迁移到 GemReact 是一个非常优秀的 UI 构建库,其生态中也有很多优秀的工具,Gem 在许多地方都有借鉴,目的是打造一个基于原生、无需编译、易于使用的 WebApp 开发框架。 从编写组件到编写自定义元素先来看一个简单的 React 组件,这里的函数名称可以作为标签名在其他组件中使用,该组件的属性使用 interface IProps {
name: string;
data?: Record<string, string>;
}
function MyComponent(props: IProps) {
const str = JSON.stringify(props.data);
return (
<div>
{props.name}
<pre>{str}</pre>
</div>
);
} 在 Gem 中使用 Classes 定义自定义元素,并且必须使用 @customElement("my-element")
class MyElement extends GemElement {
@attribute name: string;
@property data?: Record<string, string>;
get str() {
return JSON.stringify(this.data);
}
render() {
return html`
<div>
${this.name}
<pre>${this.str}</pre>
</div>
`;
}
} 一般情况下 React 组件没有那么简单,组件很可能有副作用,或者一些重计算需要记忆化,这些需求在 React 中使用 Hooks,例如将上面 React 组件中的序列化结果记忆化,并在挂载后打印日志: function MyComponent(props: IProps) {
userEffect(() => {
console.log("mounted!");
}, []);
const str = React.useMemo(() => {
return JSON.stringify(props.data);
}, [props.data]);
return (
<div>
{props.name}
<pre>{str}</pre>
</div>
);
} 在 Gem 中,是通过装饰器装饰函数来完成中: @customElement("my-element")
class MyElement extends GemElement {
@attribute name: string;
@property data?: Record<string, string>;
@effect(() => [])
log() {
console.log("mounted!");
}
// 注意:不能从 `this` 访问 `data`
@memo((e) => [e.data])
get str() {
return JSON.stringify(this.data);
}
render() {
return html`
<div>
${this.name}
<pre>${this.str}</pre>
</div>
`;
}
} 总的来说 Gem 写的自定义组件要比 React 组件复杂,带来的好处是可以在 Vanilla JavaScript 中使用。 从 CSS Modules 迁移到 Gem编写一个组件绕不开样式,在 React 中,为了让样式模块化,通常使用 CSS Modules 或者 CSS in JS 方案如 Styled Components,来看看在 React 组件中使用 CSS Modules: .title {
font-size: medium;
} import styles from "./styles.css";
function MyComponent() {
return <div className={styles.title}></div>;
} 在 Gem 中,需要手动创建对象并应用到元素上(应该自动应用?): const styles = createCSSStyle({
title: `
font-size: medium;
`,
});
@customElement("my-element")
@adoptedStyle(styles)
class MyElement extends GemElement {
render() {
return html`<div class=${styles.title}></div>`;
}
} 其他工具迁移到 Gem
|
esm.sh v136 上线就要发布 v2,因为例子中的装饰器都是使用 v1,例外需要更新:
The text was updated successfully, but these errors were encountered: