Alpine.js根据屏幕尺寸切换交互事件实现状态控制的方案咨询
实现方案
你可以直接利用Alpine.js内置的$screen魔法属性(和Tailwind断点完全匹配)做响应式交互判断,不需要额外引入依赖,修改后完整代码如下:
<div x-data="{itemActive: false}" x-on:click.away="if (!$screen('md')) itemActive = false" class="w-full pb-12 mt-5 overflow-x-hidden overflow-y-scroll md:flex md:flex-wrap md:w-auto md:mt-0 md:pb-0 md:overflow-visible" > {% for item in menu.items %} {% set index = loop.index0 %} <div x-on:mouseenter="if ($screen('md')) itemActive = {{ index }}" x-on:mouseleave="if ($screen('md')) itemActive = false" x-on:click="if (!$screen('md')) itemActive = itemActive === {{ index }} ? false : {{ index }}" class="flex flex-wrap w-full md:block md:w-auto {{ item.classes|join(' ') }}" > <a :class="{'bg-gray-900' : itemActive === {{ index }}}" class="flex flex-wrap items-center justify-between w-full h-10 px-4 cursor-pointer md:h-14 md:justify-start md:w-auto" href="{{ item.link }}" {% if item.children %} x-on:click.prevent="if (!$screen('md')) {}" {% endif %} > {{ item.title }} {% if item.children %} <span><i class="pl-2 fa fa-caret-down"></i></span> {% endif %} </a> {% if item.children %} <div x-show="itemActive === {{ index }}" class="absolute z-10 w-48 bg-gray-900"> {% for child in item.children %} <a class="flex flex-wrap items-center h-12 px-4 transition-colors cursor-pointer md:h-14 hover:bg-gray-700" href="{{ child.link }}" > {{ child.title }} </a> {% endfor %} </div> {% endif %} </div> {% endfor %} </div>
核心修改说明
- 交互逻辑判断:所有事件都通过
$screen('md')判断当前屏幕是否≥768px,大屏走hover触发逻辑,小屏走点击触发逻辑,同时小屏点击当前激活的菜单项会自动收起子菜单,符合移动端交互习惯 - 小屏防跳转:有子菜单的导航项在小屏点击时阻止默认跳转,优先触发子菜单展开/收起逻辑,如果你需要实现「第一次点击展开子菜单,第二次点击跳转」的逻辑,直接修改click事件的判断即可
- 兼容老版本Alpine:如果你使用的Alpine版本低于3.0没有内置
$screen魔法,直接把所有$screen('md')替换为window.innerWidth >= 768即可正常运行
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

