今天早上打开github,发现尤大新开了个仓库叫 vue-lit,打开看了下,大概主体思想是用vue响应式核心去驱动lit-html的更新机制。

lit-html 是谷歌的一款 web-components的框架,class base的api风格,不能说非常难用,实际上还是和现在主流的React hooks开发体验不可同日而语。在这里我要也吐槽下vue3composition api,昨天我闲来无事看了下element-plus的源码,当时其实我是被雷到了的,我们来看一段props的定义:

export default defineComponent({
    name: 'ElDivider',
    props: {
        direction: {
            type: String,
            default: 'horizontal',
            validator(val: string): boolean {
            return ['horizontal', 'vertical'].indexOf(val) !== -1
            },
        },
        contentPosition: {
            type: String,
            default: 'center',
            validator(val: string): boolean {
            return ['left', 'center', 'right'].indexOf(val) !== -1
            },
        },
    },
})

这。。。运行时的类型检查?typescript的静态类型检查他不香吗?几个单词就完事的东西要整上面这么一坨。。。然后就是各种 as看的我血压上升。好吧就算最后会用预编译把这些类型检查去掉,开发的时候写这些定义也不知道会是什么感想,这绝对不是一个很舒服的写代码方式。

言归正传。

Web Components 是一个浏览器原生支持的组件化方案,,实际上它的组件就和原生的input之类的没啥区别,实际原生的包括 input的dom元素内部实现也是shadowdom,什么?你看不见,没事打开 f12,点击右上角的小齿轮,然后勾选 显示用户代理影子dom。(什么浏览器?当然是牛逼的edgechrome应该也在差不多的位置)

更多关于web-components的内容这里也不做过多赘述了,到处都有,总的来说,它可以让你写的组件真真正正是一个符合web标准的运行时的组件,这很重要,有了标准什么事都好办

再来谈谈Hooks

其实大家现在都认可了React Hooks的开发体验,但是其实Hooks也有一些暗坑,也就是尤大一直说的心智负担,但是总的来说这些负担并不是 Hooks设计直接带来的,而是Immutable闭包共同带来的。React 开发者都习惯了的闭包陷阱当初也是坑了我老半天。这个已经被讨论烂了,就不多赘述了。然后社区就有两种人,一种说你们全部放redux啊,另一种说redux就是傻逼。但是其实都没有根本上解决问题。Immutable才是心智负担最大的问题。

那么问题来了:为什么不把HooksProxy一起用呢?一份快乐加上另一份快乐,然后再结合web-components去面向未来,那岂不是三份快乐?岂不美哉?

然后就有人告诉我:行行行,这么快乐的事就交给你了。

实际上不用告诉我,我早就开始实践了,文档都整的差不多了 Gallop

废话不多说直接上代码。

// 这拉胯的网站怎么嵌入iframe...

Sandbox

import {
    render,
    html,
    component,
    useState,
    useEffect,
    useStyle,
    css,
    ReactiveElement
} from "@gallop/gallop";

component("sand-box", function (
    this: ReactiveElement,
    { color = "red" }: { color: string }
) {
    const [state] = useState({ tick: 0, text: "hello!" });

    useEffect(() => {
        console.log(`${this.localName}'s state tick was changed to ${state.tick}`);
    }, [state.tick]);

    useStyle(
        () => css`
        div {
        color: ${state.tick % 2 ? "red" : "blue"};
        }
        `,
        [state.tick, color]
    );

    return html`
        <button @click="${() => state.tick++}">tick +1</button>
        <div>${state.tick}</div>
        <hr />
        <input
        @input="${(e: Event) => {
        const { value } = e.target as HTMLInputElement;
        state.text = value;
        }}"
        />
        <div>${state.text}</div>
    `;
});

render(html` <sand-box :color="blue"></sand-box> `);

那么这个叫Gallop玩意除了3份快乐之外,还有啥好玩的?

其实大部分在文档里面都已经提及了,其实这个框架都不能算是一个框架,它只是从底层到顶层提供了一些api,让你自己去组合着玩,如果你只是写网页,那么你可能只会用到10来个,如果你想拓展它,那么你可能需要20来个,如果你想玩各种各样的骚操作,那么这些api也完全能让你开发的舒服又舒服。另外,你其实就是在写原生的ts/Js,没有充满魔法的预编译,没有那么多乱七八糟的调度机制,也没有太多诡异的模板语法,我相信基础扎实的你,只需要几小时就能搞定,如果你开发过React Hooks,那么我估计不需要10分钟。

目前Gallop已经在笔者的公司内部开始解决一些业务组件上跨框架技术栈的问题,但是我还不能完全保证bug free,但是开发效率是绝对酸爽的,在这里也希望有更多的bug 能在实践的磨练下能够浮现水面。

说了这么多,还是希望web的未来会越来越方便,开发者们少掉点头发,少整点kpi,多干点有意思的事。

最后感谢我的猫子们,陪自己写完这个"框架"。如果对Gallop感兴趣,也可以在 Github 上交流,欢迎各种 Pr / Issue 或者对Gallop的扩展。

顺便附上Gallop和各个框架之间的性能/体积对比 ===> 传送门,实际上已经是很久以前的版本了,大家图一乐就好。

03-05 14:06