要实现像element-plus一样的多级Cascader级联选择器,可以使用Stimulus和TurboJS来进行开发。以下是一些步骤:

  1. 创建一个包含所有级别选项的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": "顶部导航"
          }
        ]
      }
    ]
  }
]
  1. 创建一个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)
    }
  }
}
  1. 在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>
  1. 样式化级联选择器,以使其看起来像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级联选择器了。

stimulus 和 turbo js 实现像element-plus 一样的多级Cascader 级联选择器

原文地址: https://www.cveoy.top/t/topic/FuC 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录