A cascade selector written by vue

Posted by rebelo on Sat, 28 Dec 2019 19:18:33 +0100

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }

    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }

    a {
      text-decoration: none;
    }

    .clearfix:before,
    .clearfix:after {
      content: ' ';
      display: table;
    }

    .clearfix:after {
      clear: both;
    }

    input {
      outline: none;
    }

    ol,
    ul {
      list-style: none;
    }

    body {
      padding: 20px;
    }

    .select-box {
      position: relative;
    }

    .select-box .curr {
      width: 240px;
      padding-left: 15px;
      padding-right: 30px;
      border: 1px solid #ddd;
      border-radius: 5px;
      height: 40px;
      line-height: 40px;
      font-size: 14px;
      position: relative;
      z-index: 15;
      background-color: white;
    }

    .select-box .curr:hover {
      border-color: #aaa;
      cursor: pointer;
    }

    .arrow {
      position: absolute;
      right: 10px;
      top: 17px;
      display: block;
      width: 10px;
      height: 10px;
      border-left: 1px solid #aaa;
      border-top: 1px solid #aaa;
      transform: rotate(225deg);
      transform-origin: 2px 2px;
      transition: 200ms;
    }

    .on .arrow {
      transform: rotate(45deg);
    }

    .list-box {
      position: absolute;
      top: 30px;
      left: 0;
      border: 1px solid #ddd;
      box-shadow: 0px 0px 8px 0px #ccc;
      padding: 5px 0;
      z-index: 10;
      transition: 200ms;
    }

    .on .list-box {
      top: 50px;
    }

    .list-box .list {
      float: left;
      width: 180px;
      height: 204px;
      overflow: auto;
      border-left: 1px solid #ccc;
    }

    .list-box .list.first {
      border: none;
    }

    .list .item {
      height: 38px;
      line-height: 38px;
      padding-left: 15px;
      font-size: 14px;
      cursor: pointer;
      position: relative;
    }

    .list .item:hover {
      background-color: rgb(245, 247, 250);
    }

    .list .item.active {
      color: #409EFF;
      font-weight: bold;
    }

    .list .icon {
      position: absolute;
      top: -6px;
      left: 30px;
      width: 10px;
      height: 10px;
      border-left: 1px solid #ddd;
      border-top: 1px solid #ddd;
      z-index: 20;
      transform: rotate(45deg);
      background-color: white;
    }

    .list .arrow-icon {
      position: absolute;
      right: 10px;
      top: 17px;
      display: block;
      width: 10px;
      height: 10px;
      border-left: 1px solid #aaa;
      border-top: 1px solid #aaa;
      transform: rotate(135deg);
      transform-origin: 2px 2px;
      transition: 200ms;
    }
  </style>
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>

  <div id="app" :class="{'on':isVisibleFirst}">

    <div class="select-box" @click="showFirstLayer">
      <div class="curr" :class="{'on':isVisibleFirst}"><span v-if="selectionBoxDisplay">Please choose</span><span v-else>{{theString}}</span><span class="arrow"></span></div>
      <div class="list-box clearfix" v-if="isVisibleFirst">
        <div class="list">
          <div class="item" v-for="(theitem,index) in list" @click="givenValueOfCurr(index)" :class="{'active':index==curr}">{{theitem.name}}

          </div>

        </div>
        <div class="list" v-if="isVisibleSecond">

          <div class="item" V-for="(theSeItem,index1) in list[curr].children" @click="clickingSecondLayer(index1)" :class="{'active':index1==currSec}">
            {{theSeItem.name}}</div>


        </div>
        <div class="icon"></div>
      </div>
    </div>

  </div>

  <script>
    var vm = new Vue({
      el: '#app',
      data: {

        list: [{
          name: 'Cantonese cuisine',
          children: [{
            name: 'Steamed mandarin fish'
          }, {
            name: 'Braised Pork with Preserved Vegetable in Soya Sauce'
          }]
        }, {
          name: 'Hunan cuisine',
          children: [{
            name: 'Braised steak fillet'
          }, {
            name: 'Steamed Fish Head with Diced Hot Red Peppers'
          }, {
            name: 'Sliced Fish in Hot Chili Oil'
          }]
        }, {
          name: 'Dessert',
          children: [{
            name: 'Sago'
          }, {
            name: 'Double skin milk'
          }, {
            name: 'Bean jelly'
          }]
        }],
        curr: -1,
        currSec: -1,

        firstTimeClick: 0,

        isVisibleFirst: false,

        isVisibleSecond: false,

        theString: "",

        selectionBoxDisplay: true,

      },
      methods: {
        showFirstLayer() {
          this.isVisibleFirst = true;
          this.firstTimeClick += 1;
          if (this.firstTimeClick > 1) {
            this.isVisibleSecond = true;
          }
          this.selectionBoxDisplay = false;

        },
        givenValueOfCurr(index) {
          this.curr = index;
          console.log(this.list[this.curr].children);
          this.isVisibleSecond = true;
          this.currSec = -1;
          this.theString = this.list[this.curr].name + "\/";
        },
        clickingSecondLayer(index1) {
          this.isVisibleFirst = false;
          this.currSec = index1;
          console.log(this.isVisibleFirst);
          this.isVisibleSecond = false;
          event.stopPropagation();
          this.theString += this.list[this.curr].children[this.currSec].name;
        }

      }
    })
  </script>
</body>

</html>

 

This is the diagram of the finished product. For the main technology, one is that v-if will display the first level menu after clicking, and then v-if will click an element in the first level menu, use a subscript in v-for, pass in the subscript, and then put the data into the second level menu accordingly.

If the color is selected, it is the application of v-bind:class. The effect of: class is to add a class to the value tag of the Index corresponding to curr (that is, the currently selected value), and the class will turn blue.

And notice the bubbling, so stop it

Topics: Vue Javascript npm