Alpine.js按标签筛选内容的简洁实现方案
Alpine.js 静态内容标签筛选实现方案
需求背景
- 实现页面预渲染内容的标签筛选能力,筛选全程无需请求后端接口,用户选中标签后直接缩小内容展示范围,无页面刷新
- 后端基于Laravel开发,选择前端筛选方案是为了减少数据库查询次数,提升交互流畅度
- 现有可运行实现冗余度高,标签数量增多时维护成本极高,需要更简洁优雅的Alpine.js写法,支持直接在内容项上关联标签规则完成过滤
原有冗余实现
原有实现给每个标签单独定义布尔状态、单独绑定全局事件,内容项显隐需要手动枚举所有排除标签,代码如下:
<button x-data="{active:false}" @click="$dispatch('tag1'), active=!active" :class="{'bg-red-300': active}"> Tag1</button> <button x-data="{active:false}" @click="$dispatch('tag2'), active=!active" :class="{'bg-red-300': active}"> Tag2</button> <button x-data="{active:false}" @click="$dispatch('tag3'), active=!active" :class="{'bg-red-300': active}"> Tag3</button> <button x-data="{active:false}" @click="$dispatch('tag4'), active=!active" :class="{'bg-red-300': active}"> Tag4</button> <div x-data="{tag1: false, tag2: false, tag3: false, tag4: false}" @tag1.window="tag1=!tag1" @tag2.window="tag2=!tag2" @tag3.window="tag3=!tag3" @tag4.window="tag4=!tag4" > <div x-show="true && (!tag3 && !tag4)"> 选中tag1和/或tag2时展示,选中Tag3和/或Tag4时隐藏 </div> <div x-show="true && (!tag1 && !tag3)"> 选中tag2和/或tag4时展示,选中Tag1和/或Tag3时隐藏 </div> </div>
优化后方案
核心优化思路
- 用单个数组统一存储所有已选中标签,无需为每个标签单独定义状态变量
- 封装标签切换、标签匹配公共方法,消除重复的事件监听、状态判断代码
- 内容项直接传入排除标签列表即可完成显隐控制,新增标签无需修改核心逻辑
- 反转判断逻辑:默认展示所有内容,仅当选中内容项排除列表内的标签时隐藏对应项
最终可用代码
<script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script> <div class="h-full overflow-auto" x-data="{ tags: [], toggle(tag) { if (this.tags.includes(tag)) { this.tags = this.tags.filter(x => x != tag) } else { this.tags.push(tag) } }, is_selected(tag) { return this.tags.some(r => tag.indexOf(r) >= 0) } }"> <button @click="toggle('tag1')" :style="is_selected('tag1') && {background: 'salmon'}">Tag 1</button> <button @click="toggle('tag2')" :style="is_selected('tag2') && {background: 'salmon'}">Tag 2</button> <button @click="toggle('tag3')" :style="is_selected('tag3') && {background: 'salmon'}">Tag 3</button> <button @click="toggle('tag4')" :style="is_selected('tag4') && {background: 'salmon'}">Tag 4</button> <div x-show="!is_selected('[tag3,tag4]')"> 选中tag1和/或tag2时展示,选中Tag3和/或Tag4时隐藏 </div> <div x-show="!is_selected('[tag1,tag3]')"> 选中tag2和/或tag4时展示,选中Tag1和/或Tag3时隐藏 </div> </div>
逻辑说明
- 点击标签按钮时调用
toggle方法,自动处理标签的选中/取消选中状态,无需给每个按钮单独定义状态、派发全局事件 is_selected方法自动判断已选标签是否命中传入的排除标签列表,单个内容项仅需调用一次方法即可完成显隐判断- 标签按钮的选中态样式复用
is_selected方法判断,无需单独维护每个按钮的激活状态 - 后续新增任意数量的标签、内容项,都不需要调整核心筛选逻辑,仅需新增对应按钮、给内容项传入正确的排除标签列表即可
内容的提问来源于stack exchange,提问作者Megued
相关产品推荐
相关产品推荐

