当前位置: 首页 > article >正文

js,html,css,vuejs手搓级联单选

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>级联选择器</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      #app {
        height: 700px;
      }
      .cascader-container {
        position: relative;
        display: inline-block;
      }
      .cascader-input {
        width: 250px;
        padding: 8px;
        border: 1px solid #ccc;
        border-radius: 4px;
        cursor: pointer;
      }
      .dropdown {
        position: absolute;
        top: 40px;
        left: 0;
        display: flex;
        border: 1px solid #ddd;
        background: white;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      }
      .column {
        width: 150px;
        border-right: 1px solid #eee;
      }
      .column:last-child {
        border-right: none;
      }
      ul {
        list-style: none;
        padding: 5px;
      }
      li {
        display: flex;
        align-items: center;
        padding: 5px;
        cursor: pointer;
      }
      li:hover {
        background: #f5f5f5;
      }
      input[type="radio"] {
        margin-right: 8px;
      }
      .selected {
        color: #409eff;
        font-weight: bold;
      }
      .arrow {
        margin-left: auto;
      }
    </style>
  </head>
  <body>
    <div id="app" @click="hideDropdown">
      <div class="cascader-container" @click.stop>
        <input
          class="cascader-input"
          :value="selectedPath"
          readonly
          @click="toggleDropdown"
        />
        <div v-if="dropdownVisible" class="dropdown" @click.stop>
          <div
            v-for="(items, level) in visibleData"
            :key="level"
            class="column"
          >
            <ul>
              <li
                v-for="item in items"
                :key="item.value"
                @click.stop="toggleExpand(item, level)"
              >
                <input
                  type="radio"
                  name="cascader"
                  :value="item.value"
                  v-model="selectedValue"
                  @click.stop="selectItem(item)"
                />
                <span :class="{ selected: selectedValue === item.value }"
                  >{{ item.label }}</span
                >
                <span v-if="item.children" class="arrow">></span>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>

    <script>
      new Vue({
        el: "#app",
        data: {
          dropdownVisible: false,
          selectedValue: "",
          selectedPath: "请选择",
          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: "顶部导航",
                    },
                  ],
                },
              ],
            },
            {
              value: "zujian",
              label: "组件",
              children: [
                {
                  value: "basic",
                  label: "Basic",
                  children: [
                    {
                      value: "layout",
                      label: "Layout 布局",
                    },
                    {
                      value: "color",
                      label: "Color 色彩",
                    },
                    {
                      value: "typography",
                      label: "Typography 字体",
                    },
                    {
                      value: "icon",
                      label: "Icon 图标",
                    },
                    {
                      value: "button",
                      label: "Button 按钮",
                    },
                  ],
                },
                {
                  value: "form",
                  label: "Form",
                  children: [
                    {
                      value: "radio",
                      label: "Radio 单选框",
                    },
                    {
                      value: "checkbox",
                      label: "Checkbox 多选框",
                    },
                    {
                      value: "input",
                      label: "Input 输入框",
                    },
                    {
                      value: "input-number",
                      label: "InputNumber 计数器",
                    },
                    {
                      value: "select",
                      label: "Select 选择器",
                    },
                    {
                      value: "cascader",
                      label: "Cascader 级联选择器",
                    },
                    {
                      value: "switch",
                      label: "Switch 开关",
                    },
                    {
                      value: "slider",
                      label: "Slider 滑块",
                    },
                    {
                      value: "time-picker",
                      label: "TimePicker 时间选择器",
                    },
                    {
                      value: "date-picker",
                      label: "DatePicker 日期选择器",
                    },
                    {
                      value: "datetime-picker",
                      label: "DateTimePicker 日期时间选择器",
                    },
                    {
                      value: "upload",
                      label: "Upload 上传",
                    },
                    {
                      value: "rate",
                      label: "Rate 评分",
                    },
                    {
                      value: "form",
                      label: "Form 表单",
                    },
                  ],
                },
                {
                  value: "data",
                  label: "Data",
                  children: [
                    {
                      value: "table",
                      label: "Table 表格",
                    },
                    {
                      value: "tag",
                      label: "Tag 标签",
                    },
                    {
                      value: "progress",
                      label: "Progress 进度条",
                    },
                    {
                      value: "tree",
                      label: "Tree 树形控件",
                    },
                    {
                      value: "pagination",
                      label: "Pagination 分页",
                    },
                    {
                      value: "badge",
                      label: "Badge 标记",
                    },
                  ],
                },
                {
                  value: "notice",
                  label: "Notice",
                  children: [
                    {
                      value: "alert",
                      label: "Alert 警告",
                    },
                    {
                      value: "loading",
                      label: "Loading 加载",
                    },
                    {
                      value: "message",
                      label: "Message 消息提示",
                    },
                    {
                      value: "message-box",
                      label: "MessageBox 弹框",
                    },
                    {
                      value: "notification",
                      label: "Notification 通知",
                    },
                  ],
                },
                {
                  value: "navigation",
                  label: "Navigation",
                  children: [
                    {
                      value: "menu",
                      label: "NavMenu 导航菜单",
                    },
                    {
                      value: "tabs",
                      label: "Tabs 标签页",
                    },
                    {
                      value: "breadcrumb",
                      label: "Breadcrumb 面包屑",
                    },
                    {
                      value: "dropdown",
                      label: "Dropdown 下拉菜单",
                    },
                    {
                      value: "steps",
                      label: "Steps 步骤条",
                    },
                  ],
                },
                {
                  value: "others",
                  label: "Others",
                  children: [
                    {
                      value: "dialog",
                      label: "Dialog 对话框",
                    },
                    {
                      value: "tooltip",
                      label: "Tooltip 文字提示",
                    },
                    {
                      value: "popover",
                      label: "Popover 弹出框",
                    },
                    {
                      value: "card",
                      label: "Card 卡片",
                    },
                    {
                      value: "carousel",
                      label: "Carousel 走马灯",
                    },
                    {
                      value: "collapse",
                      label: "Collapse 折叠面板",
                    },
                  ],
                },
              ],
            },
            {
              value: "ziyuan",
              label: "资源",
              children: [
                {
                  value: "axure",
                  label: "Axure Components",
                },
                {
                  value: "sketch",
                  label: "Sketch Templates",
                },
                {
                  value: "jiaohu",
                  label: "组件交互文档",
                },
              ],
            },
          ],
          expandedNodes: [],
        },
        computed: {
          visibleData() {
            let levels = [];
            let currentLevel = this.options;
            levels.push(currentLevel);
            for (let i = 0; i < this.expandedNodes.length; i++) {
              let found = currentLevel.find(
                (node) => node.value === this.expandedNodes[i]
              );
              if (found && found.children) {
                levels.push(found.children);
                currentLevel = found.children;
              } else {
                break;
              }
            }
            return levels;
          },
        },
        methods: {
          toggleDropdown() {
            this.dropdownVisible = !this.dropdownVisible;
          },
          hideDropdown() {
            this.dropdownVisible = false;
          },
          toggleExpand(item, level) {
            this.expandedNodes = this.expandedNodes.slice(0, level);
            if (item.children) {
              this.expandedNodes.push(item.value);
            }
          },
          selectItem(item) {
            this.selectedValue = item.value;
            this.selectedPath = this.getFullPath(item.value, this.options, "");
            this.dropdownVisible = false;
            console.log("this.selectedValue", this.selectedValue);
            console.log("this.selectedPath", this.selectedPath);
          },
          getFullPath(value, options, path) {
            for (let opt of options) {
              let newPath = path ? `${path} / ${opt.label}` : opt.label;
              if (opt.value === value) return newPath;
              
              if (opt.children) {
                let result = this.getFullPath(value, opt.children, newPath);
                if (result) return result;
              }
            }
            return "";
          },
        },
      });
    </script>
  </body>
</html>


 


http://www.kler.cn/a/590876.html

相关文章:

  • 使用 Hyperlane 框架的 WebSocket 功能
  • 一例print spooler打印服务问题自动停止的解决方法
  • Maven常见问题汇总
  • 【Python】Python与算法有应用关系吗?
  • Android Handle 机制常见问题深度解析
  • zemax高低温优化
  • 数据库设计实验(3)—— 分离与附加、还原与备份
  • WPS表格导入CSV文件(适合处理数据库导出数据)
  • 深入理解 Qt 系统托盘图标:创建自定义的系统托盘图标类
  • 《C#上位机开发从门外到门内》3-4:基于TCP/IP的远程监控系统设计与实现
  • 基于 Python 爬取 TikTok 搜索数据 Tiktok爬虫(2025.3.17)
  • EMLOG漏洞防护方法(防Webshell、防篡改、防劫持、防SQL注入、防XSS攻击)
  • 分区表和分表
  • 【STM32】uwTick在程序中的作用及用法,并与Delay函数的区别
  • NLP高频面试题(五)——BERT的基本结构介绍、预训练任务、下游任务
  • ubuntu20.04关机进程阻塞解决方法
  • Java+AI:传统编程语言的智能化突围之路
  • 【gopher的java学习笔记】Maven依赖中的scope字段:精准控制依赖生命周期的实战指南
  • 贴吧ip什么意思?贴吧ip可以查到姓名吗
  • 学c++的人可以几天速通python?