hotwiredstimulus 和 tailwindcss 实现像element-plus 多层级 Cascader 级联选择器
首先,需要在项目中引入 @hotwired/stimulus 和 tailwindcss。然后,可以创建一个 Stimulus 控制器来实现多层级 Cascader 级联选择器的功能。
以下是一个示例控制器代码:
import { Controller } from '@hotwired/stimulus'
export default class extends Controller {
static targets = ['menu', 'option']
connect() {
// 初始化菜单
this.openMenu(0)
}
// 点击选项时触发
selectOption(event) {
const option = event.currentTarget
const level = parseInt(option.dataset.level)
// 更新选项
this.updateOption(level, option.textContent)
// 关闭之前的菜单
this.closeMenu(level)
// 打开下一个菜单
this.openMenu(level + 1)
}
// 打开菜单
openMenu(level) {
const menu = this.menuTargets[level]
if (menu) {
menu.classList.remove('hidden')
menu.classList.add('block')
}
}
// 关闭菜单
closeMenu(level) {
const menu = this.menuTargets[level]
if (menu) {
menu.classList.remove('block')
menu.classList.add('hidden')
}
}
// 更新选项
updateOption(level, value) {
const option = this.optionTargets[level]
option.textContent = value
}
}
在 HTML 中,可以使用以下代码来定义级联选择器:
<div data-controller="cascader">
<div class="relative">
<button type="button" class="inline-flex justify-between items-center w-full px-4 py-2 border border-gray-300 bg-white text-gray-700 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" data-action="click->cascader#openMenu">
<span class="block truncate" data-target="cascader.option"></span>
<svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M10.707 3.293a1 1 0 00-1.414 0l-6 6a1 1 0 001.414 1.414L4 7.414V17a1 1 0 001 1h10a1 1 0 001-1V7.414l1.293 1.293a1 1 0 001.414-1.414l-6-6z" clip-rule="evenodd" />
</svg>
</button>
<div class="absolute z-10 right-0 mt-2 w-64 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 hidden" data-target="cascader.menu">
<ul class="py-1">
<li><a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900" data-action="click->cascader#selectOption" data-level="0">Option 1</a></li>
<li><a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900" data-action="click->cascader#selectOption" data-level="0">Option 2</a></li>
</ul>
</div>
</div>
<div class="relative">
<button type="button" class="inline-flex justify-between items-center w-full px-4 py-2 border border-gray-300 bg-white text-gray-700 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" data-action="click->cascader#openMenu">
<span class="block truncate" data-target="cascader.option"></span>
<svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M10.707 3.293a1 1 0 00-1.414 0l-6 6a1 1 0 001.414 1.414L4 7.414V17a1 1 0 001 1h10a1 1 0 001-1V7.414l1.293 1.293a1 1 0 001.414-1.414l-6-6z" clip-rule="evenodd" />
</svg>
</button>
<div class="absolute z-10 right-0 mt-2 w-64 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 hidden" data-target="cascader.menu">
<ul class="py-1">
<li><a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900" data-action="click->cascader#selectOption" data-level="1">Option 1-1</a></li>
<li><a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900" data-action="click->cascader#selectOption" data-level="1">Option 1-2</a></li>
</ul>
</div>
</div>
<div class="relative">
<button type="button" class="inline-flex justify-between items-center w-full px-4 py-2 border border-gray-300 bg-white text-gray-700 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" data-action="click->cascader#openMenu">
<span class="block truncate" data-target="cascader.option"></span>
<svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M10.707 3.293a1 1 0 00-1.414 0l-6 6a1 1 0 001.414 1.414L4 7.414V17a1 1 0 001 1h10a1 1 0 001-1V7.414l1.293 1.293a1 1 0 001.414-1.414l-6-6z" clip-rule="evenodd" />
</svg>
</button>
<div class="absolute z-10 right-0 mt-2 w-64 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 hidden" data-target="cascader.menu">
<ul class="py-1">
<li><a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900" data-action="click->cascader#selectOption" data-level="2">Option 1-1-1</a></li>
<li><a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900" data-action="click->cascader#selectOption" data-level="2">Option 1-1-2</a></li>
</ul>
</div>
</div>
</div>
在这个示例中,我们定义了三个按钮,每个按钮都有一个菜单,用于显示级联选择器的选项。每个菜单都有一个 data-level 属性,用于指示该菜单属于级联选择器的哪个级别。
我们还定义了一个名为 cascader 的 Stimulus 控制器,并在按钮和菜单上使用了 data-controller 和 data-target 属性来将它们与控制器绑定起来。控制器中的 selectOption 方法负责更新选项并打开下一个菜单,openMenu 和 closeMenu 方法用于打开和关闭菜单,updateOption 方法用于更新选项的文本内容。
最后,在 CSS 中,我们使用 tailwindcss 来样式化级联选择器的外观和交互效果。
这样,我们就可以使用 @hotwired/stimulus 和 tailwindcss 来实现像 element-plus 多层级 Cascader 级联选择器的功能了。
原文地址: https://www.cveoy.top/t/topic/FwR 著作权归作者所有。请勿转载和采集!