零构建的快感!dagger.js 与 React Hooks 实现对比,谁更优雅?

发布于:2025-09-03 ⋅ 阅读:(18) ⋅ 点赞:(0)

“Add Tags” 技术方案并行对比:React Hooks vs dagger.js(含核心 JS 代码)

源码:


在这里插入图片描述

一、对比总览(表格)

维度 React Hooks 实现(prvnbist) dagger.js 实现(dagger8224) 结论
框架/依赖 依赖 React/ReactDOM + Babel/JSX;ReactDOM.render 挂载 原生 DOM + 指令(+load/*each/*value#trim/+click/+keyup),零构建可跑 dagger 依赖更轻;React 生态更全
状态管理 useState(不可变更新) 作用域对象可变更新(push/splice React 可预测性强;dagger 上手直观
事件/输入 onKeyUp 手写回调读取/清空输入 *value#trim 双向绑定,+keyup#every:-Enter 声明式触发 dagger 更少样板
列表渲染/删除 tags.map(...) + onClick *each="tags" + +click="removeTags(...)" 均直观;dagger 更贴 HTML
对外通信 props.selectedTags([...]) 向父级冒泡 示例未展示(可拓展自定义事件/全局 store) React 更现成
A11y 删除控件是 span“x”,无按钮角色/ARIA(两边均是) 同左 建议两者都改 <button aria-label="Remove tag">
性能(本例) VDOM diff 开销极小 直达 DOM 绑定 小组件差异可忽略
适用场景 工程化/组件生态/团队协作 免构建/轻量嵌入/快速原型 视项目体量取舍

二、代码量差异(粗略非空行统计)

注:仅为量级参考;CSS 两边大致一致。

面板 React Hooks dagger.js
HTML ~1 行(<div id="root"> ~10 行(含指令模板)
JS ~33 行(TagsInput + App + render ~12 行(loading/removeTags/addTags
CSS ~80+ 行(两者近似) ~80+ 行
合计(HTML+JS) ~34 行 ~22 行

结论:dagger.js 显著减少 JS 体量,把交互“下沉”到 HTML 指令;React JS 更多但 HTML 更薄,符合组件化/状态提升的常规模式。


三、核心 JS 代码对照

1) React Hooks(核心 JS)

const TagsInput = props => {
  const [tags, setTags] = React.useState(props.tags);
  const removeTags = indexToRemove => {
    setTags([...tags.filter((_, index) => index !== indexToRemove)]);
  };
  const addTags = event => {
    if (event.target.value !== "") {
      setTags([...tags, event.target.value]);
      props.selectedTags([...tags, event.target.value]);
      event.target.value = "";
    }
  };
  return (
    <div className="tags-input">
      <ul id="tags">
        {tags.map((tag, index) => (
          <li key={index} className="tag">
            <span className='tag-title'>{tag}</span>
            <span className='tag-close-icon'
              onClick={() => removeTags(index)}
            >
              x
            </span>
          </li>
        ))}
      </ul>
      <input
        type="text"
        onKeyUp={event => event.key === "Enter" ? addTags(event) : null}
        placeholder="Press enter to add tags"
      />
    </div>
  );
};
const App = () => {
  const selectedTags = tags => {
    console.log(tags);
  };
  return (
    <div className="App">
      <TagsInput selectedTags={selectedTags}  tags={['Nodejs', 'MongoDB']}/>
    </div>
  );
};
ReactDOM.render(<App />, document.getElementById("root"));

2) dagger.js(核心 JS)

const loading = () => ({
  tag: '',
  tags: ['Nodejs', 'MongoDB']
});
const removeTags = (index, tags) => tags.splice(index, 1);
const addTags = $scope => {
  const { tag, tags } = $scope;
  if (tag) {
    tags.push(tag);
    $scope.tag = '';
  }
};

dagger 对应模板(片段),可见通过指令表达列表、事件与双向绑定:

<div dg-cloak class="App" +load="loading()">
  <div class="tags-input">
    <ul id="tags">
      <li class="tag" *each="tags">
        <span class='tag-title'>${ item }</span>
        <span class='tag-close-icon' +click="removeTags(index, tags)">x</span>
      </li>
    </ul>
    <input type="text" placeholder="Press enter to add tags"
           *value#trim="tag" +keyup#every:-Enter="addTags($scope)">
  </div>
</div>

四、与代码对应的实现分析

A. 初始化与挂载

  • Reactconst [tags, setTags] = useState(props.tags); 为局部状态;通过 ReactDOM.render(<App/>, #root) 挂载。组件化边界清晰,便于复用与组合。
  • dagger+load="loading()" 在容器上注入初始作用域(tag/tags),无需显式渲染入口,适合在任意静态页“就地”增强。

B. 输入与校验

  • ReactaddTags(event) 里手动读取/清空 event.target.value;默认不 trim,可在函数中补充校验与去重。
  • dagger*value#trim="tag" 天然裁剪空白,结合 +keyup#every:-Enter 让“回车新增”无需手写键值判断。

C. 列表渲染与删除

  • Reacttags.map(...) 渲染项,onClick={() => removeTags(index)} 删除。不可变更新(filter)便于可预测渲染、状态回溯。
  • dagger*each="tags" 迭代;+click="removeTags(index, tags)" 直接调用,常配合可变更新(splice)写法简洁。

D. 对外通信

  • Reactprops.selectedTags([...]) 将内部变更上报给父组件或外层应用(常见于表单控件封装)。
  • dagger:示例未展示;可通过自定义事件(dispatchEvent)或外层监听指令来完成数据冒泡。

E. 可访问性(A11y)

  • 两边删除控件均为 span,建议替换为:
    <button type="button" class="tag-close-icon" aria-label="Remove tag">x</button>
    
    并配合键盘支持(Enter/Space)和更明确的焦点样式。

五、改进建议(两边通用)

  • 输入规则:去重、最大标签数、禁止全空白;支持粘贴多标签(按逗号/空格分割)。
  • 错误反馈:同名标签时给出可视化提示(如 shake 动画/辅助文本)。
  • 测试:React 侧可配合 Testing Library;dagger 侧可通过 DOM 测试/端到端测试保障交互。
  • 样式与主题:抽离 tokens/vars,支持暗色模式与尺寸变体。

六、选型参考

  • 需要工程化、强生态、多人协作 —— 倾向 React:组件化边界清晰、工具链与第三方库成熟。
  • 追求零构建、轻量嵌入、快速上线 —— 倾向 dagger:指令式绑定 + 原生 DOM,代码量更小,上手极快。

本文内容就到这里,后续文章将为大家带来更多案例和讲解。

如果对dagger.js感兴趣的话,请您点赞收藏、分享本系列文章,也欢迎留言或者私信作者提出问题和建议,您的关注是对我最大的支持和鼓励。感谢您的阅读,祝工作学习顺利!


网站公告

今日签到

点亮在社区的每一天
去签到