Stimulus.js切换CSS display属性:遇data-toggle-display-class缺失报错
报错根源
Stimulus 对类绑定属性的查找规则是严格限定在控制器挂载的根节点(即声明data-controller的元素本身)上,不会向内部子元素遍历检索。
你现在把data-toggle-display-class="display"写在了内部的.dropnav子元素上,Stimulus 在根节点的<li class="nav_items" data-controller="toggle">上找不到对应的类绑定属性,就会直接抛出Missing attribute的错误。
修正步骤
挪动类绑定属性的位置
把类绑定属性从子元素上移到控制器根节点,也就是写在带data-controller="toggle"的<li>标签上:<li class="nav_items" data-controller="toggle" <!-- 类绑定属性挪到根节点位置 --> data-toggle-display-class="dropnav--show" > <a href="" data-action="toggle#toggle" > <i class="far fa-user-circle fa-2x "></i> </a> <!-- 子元素上只保留target绑定即可,删掉原来写在这里的类绑定属性 --> <div class="dropnav" data-toggle-target="hide" > <a href="" class="drop_down_items" ></a> <a href="" class="drop_down_items">Links</a> </div> </li>补全显示/隐藏对应的CSS规则
你现在只写了.dropnav{display:flex}的默认样式,切换类的时候没有对应的隐藏规则,即使类能正常切换,也达不到flex/none切换的效果,需要补全两个状态的类:/* 隐藏状态 */ .dropnav--hide { display: none; } /* 显示状态 */ .dropnav--show { display: flex; }调整控制器逻辑匹配需求
如果你需要页面加载完成后默认隐藏下拉菜单,就可以把connect方法里自动加显示类的逻辑删掉,只保留toggle的切换逻辑:// 对应文件需命名为 toggle_controller.js 才能被自动识别 export default class extends Controller { static targets = [ "hide" ] static classes = ["display"] // 删掉connect里自动加显示类的逻辑,避免页面加载就弹出下拉 toggle() { this.hideTarget.classList.toggle(this.displayClass) } }同时给
.dropnav元素加上默认的隐藏类:<div class="dropnav dropnav--hide" data-toggle-target="hide">
注意:你HTML里挂载的控制器标识是
data-controller="toggle",对应的控制器文件需要命名为toggle_controller.js才能被Stimulus自动识别加载,不要命名为hide_controller.js,否则会出现控制器找不到的问题。
可选简化方案
如果不需要依赖Stimulus的类绑定特性,也可以直接操作元素的display属性,省掉类绑定的配置,也不会触发缺失属性的报错:
toggle() { const currentDisplay = this.hideTarget.style.display this.hideTarget.style.display = currentDisplay === 'none' ? 'flex' : 'none' }
内容的提问来源于stack exchange,提问作者foliwe83

