JavaScript 折腾来折腾去,我看 Alpine.js 和 Rails 挺搭配的

u1435638317 · 2022年01月05日 · 最后由 xiaox 回复于 2023年01月10日 · 2449 次阅读

前端业态存在的问题

  1. React / Vue 一类的框架对于 Rails 这种 不甘于 View 端表达能力的,一下子就感觉是把一个人的手给剁了,感觉挺难受的。React / Vue 野心挺大,而 ActionView / ActionController 又配合也挺好的,这搞的挺分裂的。而 react_on_railsreact-rails解决不了根本的问题,它们服务端渲染的本质是另搞一个 js 环境来解释执行 JS 代码,传送到浏览器端。

  2. Hotwired / Stimulus 这种写写一般的页面逻辑还是挺方便的,但是对于组件抽象化的能力还是欠缺一些,不能形成生态气候,相对来说是一个封闭的环境。

  3. github 搞的 view_component ,基本来说是不错的,https://ruby-china.org/topics/42030,但是缺少前端的能力,希望能强化一下。

直到我看到 Alpine.js 我眼前一亮,这不就是我想要的吗? 轻量级,表达能力不弱,HTML 片段和 数据状态管理搭配的挺好,同时又没有像其它框架发明很多概念和词汇,就算以后换 JS 框架(经常干的事)也不是很费脑力。它的 Hello world 是这样的:

script src="//unpkg.com/alpinejs" defer></script>

<div x-data="{ open: false }">
    <button @click="open = true">Expand</button>

    <span x-show="open">
      Content...
    </span>
</div>

再来一个看起来组件化一点的例子:

<div x-data="dropdown">
    <button @click="toggle">...</button>

    <div x-show="open">...</div>
</div>

<script>
    document.addEventListener('alpine:init', () => {
        Alpine.data('dropdown', () => ({
            open: false,

            toggle() {
                this.open = ! this.open
            }
        }))
    })
</script>

Alpine.js

Alpine.js 通过很低的成本提供了与 Vue 或 React 这类大型框架相近的响应式和声明式特性,没有为了解决某某问题,给你再整个什么概念(说的就是你 React JS),它的文档里就这么点东西,看一会儿就可以上手了。

Alpine.js 中关于数据状态的 Reactivity 这部分,是直接基于 Vue 项目中的一个模块 @vue/reactivity,再没有其它依赖,整体代码很少,14KB,就这么点:https://unpkg.com/[email protected]/dist/cdn.min.js

我感觉是可以尝试一下了。大家觉得怎么样?

观望观望

作为前端,深知前端的轮子都靠不住。三天打鱼,两天造轮子。

之前看到一个 https://lit.dev/

在几个小项目的后台用过一下,纯前端方案,引用一下就直接开整,没什么心理压力。写过 Vue 的话,基本无缝上手。

看着像 vue,那为什么不用 vue 呢?

和 turbo 一起用有问题,虽然有人做了插件,不过转来转去,发现最好的搭配还是 Stimulus+Turbo

https://github.com/vuejs/petite-vue vue 也搞了一个类似的,和后端渲染一起用的框架

我是越来越倾向于 React 和 Vue 这种主流前端框架了,原因就是你要个什么组件都有十几种选择给你

ad583255925 回复

是的,生态环境已经起来了,各种组件库非常完善。

正好我也研究过 alpine.js

个人感觉,alpine.js 最大的好处就是简单的令人发指的同时,js 文件又小巧

可以脱离 webpack, 脱离 node 环境,不需要额外的文件扩展名,直接引用一个 14k 的 js 文件,之后就可以在 html 里写东西了,单纯用浏览器跑起来就好,就拥有了现代前端的 state => ui 的能力。

只要是自己用 stimulus 自己实现一个可用的 modal 就知道,如果用 vanilla javascript 写 modal 的逻辑,还是有点累的。

alpine.js 于类似 react, vue 的还一个比较大的区别是,react,vue 虽然说也可以用在页面的局部,但是现在的风气是 react 或 vue 接管前端的一切,从路由开始接管,整个 html 代码恨不得就一个 body , 天然的倾向于做成 SPA。而 alpine.js 由于轻量化的设计,导致几乎所有使用方式都是页面局部的处理,不排斥后端渲染页面,可以轻而易举的嵌入已有的项目中去。

现在 alpine.js 继续发展的一个思路就是做通用组件库,组件设计好规定的动作逻辑和基础的 UI,用户自行丰富 UI 以及对逻辑动作进行扩展。他抽离除了几个常用的组件,如 modal, dropdown, accordion 啥的。其实还有一个类似的项目 叫 headless ui, 只不过那个的实现是用的 react 或 vue, 如果开发者不想或不方便在代码中搞类似 webpack 的工具,就不太方便了。

另外,因为 alpine.js 的低侵入性,它是可以和 stimulusjs +turbo 混用的,代价就是多 15k(14k core +turbo bridge 1k) ,只不过这个损耗在今天的前端世界,简直就是白送。

jicheng1014 回复

感觉 html 标签承受了太多,尝试了一下很快放弃了,特别是在 erb 语法里面套 alpine.js 语法逻辑的情况,很耗费心智。

使用 vanilla javascript 写组件库是挺费尽,但是做好了就很方便使用。

  customElements.define('gem-table', class extends HTMLElement {
    constructor() { }
}

在页面中调用一下这个自定义标签,就能拥有一个增强版的表格,固定表头,拖拽缩放单元格等,没有什么记忆和心智负担。

<gem-table><table>..</table></gem-table>
jicheng1014 回复

一开始我也和你一样想法,现在我觉得 stimulus 就够了,基本上有的都能做,麻烦程度略有增加,但是多一个依赖不如少一个。。

ad583255925 回复

组件多不能说明啥,当你有能力做组件以后,真实的设计需求决定了要不要用组件,一般组件有几个大问题,一,看起来太普通太普遍,二,塞给你很多不需要的功能,三,可改性很差。

jicheng1014 回复

turbo bridge 是自己写的还是有现成的?有链接吗?

Vimesh Headless UI (https://github.com/vimeshjs/vimesh-headless)是 Tailwind Headless UI 的 Alpine.js 实现,不用 webpack 打包,开箱即用

俺拥抱生态...

需要 登录 后方可回复, 如果你还没有账号请 注册新账号