stimulus 和 turbo js 实现像element-plus 一样的多级Cascader 级联选择器
要实现像element-plus一样的多级Cascader级联选择器,可以使用Stimulus和TurboJS来进行开发。以下是一些步骤:
- 创建一个包含所有级别选项的JSON数组。例如,对于一个多级Cascader级联选择器,可以使用以下JSON数组:
[
{
"value": "zhinan",
"label": "指南",
"children": [
{
"value": "shejiyuanze",
"label": "设计原则",
"children": [
{
"value": "yizhi",
"label": "一致"
},
{
"value": "fankui",
"label": "反馈"
},
{
"value": "xiaolv",
"label": "效率"
},
{
"value": "kekong",
"label": "可控"
}
]
},
{
"value": "daohang",
"label": "导航",
"children": [
{
"value": "cexiangdaohang",
"label": "侧向导航"
},
{
"value": "dingbudaohang",
"label": "顶部导航"
}
]
}
]
}
]
- 创建一个Cascader控制器,该控制器将使用Stimulus和TurboJS来管理级联选择器的行为。例如:
import { Controller } from "stimulus"
import Turbo from "@hotwired/turbo"
export default class extends Controller {
static targets = [ "input", "menu" ]
initialize() {
this.selected = []
this.options = JSON.parse(this.data.get("options"))
this.renderMenu(this.options)
}
renderMenu(options) {
const html = options.map(option => `
<li data-value="${option.value}" data-label="${option.label}" data-children="${option.children ? JSON.stringify(option.children) : null}">
${option.label}
${option.children ? '<i class="fas fa-angle-right"></i>' : ''}
</li>
`).join("")
this.menuTarget.innerHTML = html
}
selectOption(event) {
const target = event.target.closest("li")
const value = target.dataset.value
const label = target.dataset.label
const children = JSON.parse(target.dataset.children)
if (children) {
this.selected.push({ value, label })
this.renderMenu(children)
} else {
this.selected.push({ value, label })
this.inputTarget.value = this.selected.map(option => option.label).join(" / ")
Turbo.navigator.visit(this.data.get("url") + "?value=" + this.selected.map(option => option.value).join(","))
}
}
goBack() {
this.selected.pop()
const lastSelected = this.selected[this.selected.length - 1]
if (lastSelected) {
this.renderMenu(JSON.parse(this.menuTarget.querySelector(`[data-value="${lastSelected.value}"]`).dataset.children))
} else {
this.renderMenu(this.options)
}
}
}
- 在HTML中创建一个包含级联选择器的元素,并将其与Cascader控制器关联。例如:
<div data-controller="cascader" data-cascader-options='[{
"value": "zhinan",
"label": "指南",
"children": [
{
"value": "shejiyuanze",
"label": "设计原则",
"children": [
{
"value": "yizhi",
"label": "一致"
},
{
"value": "fankui",
"label": "反馈"
},
{
"value": "xiaolv",
"label": "效率"
},
{
"value": "kekong",
"label": "可控"
}
]
},
{
"value": "daohang",
"label": "导航",
"children": [
{
"value": "cexiangdaohang",
"label": "侧向导航"
},
{
"value": "dingbudaohang",
"label": "顶部导航"
}
]
}
]
}]'>
<input type="text" data-cascader-target="input">
<ul data-cascader-target="menu" data-action="click->cascader#selectOption"></ul>
</div>
- 样式化级联选择器,以使其看起来像element-plus的级联选择器。例如:
[data-controller="cascader"] {
position: relative;
display: inline-block;
vertical-align: middle;
font-size: 14px;
color: #606266;
cursor: pointer;
}
[data-controller="cascader"] input {
display: inline-block;
width: 100%;
padding: 10px 30px 10px 10px;
border: 1px solid #dcdfe6;
border-radius: 4px;
background-color: #fff;
background-image: none;
transition: border-color .2s cubic-bezier(.645,.045,.355,1);
}
[data-controller="cascader"] input:focus {
outline: none;
border-color: #409EFF;
box-shadow: 0 0 0 2px rgba(64,158,255,.2);
}
[data-controller="cascader"] ul {
position: absolute;
top: 100%;
left: 0;
z-index: 999;
display: none;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0;
font-size: 14px;
text-align: left;
list-style: none;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #dcdfe6;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
}
[data-controller="cascader"] ul li {
position: relative;
display: block;
padding: 5px 10px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
cursor: pointer;
}
[data-controller="cascader"] ul li:hover {
color: #409EFF;
background-color: #f5f7fa;
}
[data-controller="cascader"] ul li i {
position: absolute;
top: 0;
right: 0;
padding: 5px;
color: #c0c4cc;
font-size: 12px;
transition: transform .2s cubic-bezier(.645,.045,.355,1);
}
[data-controller="cascader"] ul li:hover i {
transform: rotate(90deg);
color: #409EFF;
}
这样,就可以使用Stimulus和TurboJS来实现像element-plus一样的多级Cascader级联选择器了。
原文地址: https://www.cveoy.top/t/topic/FuC 著作权归作者所有。请勿转载和采集!