能否使用Go template构建跨项目复用的通用Web UI components?
Go template实现可复用Web UI组件的实践参考
完全可以用Go标准库的html/template实现全项目通用的可复用Web UI组件,树形组件、分页器、导航栏、表单控件这类常用组件我在好几个后端渲染的生产项目里都落地过,跑了好几年没什么问题,完全能满足复用需求。
核心落地方法
- 组件文件单独管理:所有通用组件统一放在
templates/components/目录下,每个组件对应一个独立模板文件,比如树形组件就存为tree.html。项目启动时一次性把所有组件模板、页面模板全部解析加载到全局模板缓存,不要每次请求重复解析,性能很好。 - 给每个组件定义专属输入结构体:不要零散传参,比如树形组件就定义专门的
TreeData结构体,字段包含节点列表、当前选中ID、节点点击跳转规则、自定义扩展配置等,渲染的时候直接把结构体实例传给组件就行,后续迭代加配置只要改结构体字段,不会影响已有调用。 - 用模板引用语法做组件嵌入:Go template原生支持
{{template "模板名" 传入数据}}语法,在任意页面模板里要插组件的时候,直接写{{template "components/tree.html" .PageTreeData}}就能把组件渲染到对应位置,和写原生HTML标签一样方便。
树形组件实现的关键注意点
树形组件的核心是递归渲染,Go template本身支持模板自调用,不需要额外写复杂的Go端渲染逻辑,给你看个最简的核心实现片段:
{{define "components/tree.html"}} <ul class="tree-list"> {{range .Nodes}} <li class="tree-node" data-id="{{.ID}}"> <span class="node-label {{if eq .ID $.SelectedID}}active{{end}}">{{.Name}}</span> {{if gt (len .Children) 0}} {{template "components/tree.html" (dict "Nodes" .Children "SelectedID" $.SelectedID)}} {{/if}} </li> {{end}} </ul> {{end}}
这里用到的dict是自定义模板函数,项目初始化模板的时候加到FuncMap里就行,作用是把多个键值对打包成map传给子模板,解决递归调用时多参数传递的问题,实现起来就几行代码。
提升复用性的实用技巧
- 可以通过传入预定义模板名的方式实现类似插槽的效果,比如要给树节点加自定义操作按钮,不需要修改组件核心代码,只要在调用组件时把自定义按钮的模板名作为参数传入,组件内部预留位置用
{{template .ActionTpl .}}渲染即可,灵活度很高。 - 组件对应的CSS、JS代码和模板文件绑定管理,做个简单的资源引用标记,避免同一个组件的静态资源在一个页面里重复加载。
- 不用一开始就追求做覆盖所有场景的大而全组件,先把项目里重复出现3次以上的UI块抽成组件,随着业务迭代慢慢补配置项,比上来就做全功能组件好用很多,也不会增加不必要的复杂度。
内容的提问来源于stack exchange,提问作者user3737851
相关产品推荐
相关产品推荐

