zoukankan      html  css  js  c++  java
  • 基于Vue构建n级联动下拉框组件

    利用递归组件实现

    组件参数:

    • v-model 用于双向绑定的属性,目前绑定option里的id
    • options 一个数组,例如[{title:'a',id:1,children:[{title:'b',id:2}]}]
    <template>
      <div class="selectors">
        <template v-if="!hasChildren">
          <select @change="onChanged" :value="mvalue">
            <option v-for="option in options" :value="option.id" :key="option.id">{{option.title}}</option>
          </select>
        </template>
        <template v-else>
          <select @change="onParentChanged" :value="pvalue">
            <option v-for="option in options" :value="option.id" :key="option.id">{{option.title}}</option>
          </select>
          <PropertySelector :mvalue="cvalue" @change="onChidrenChanged" :options="childOptions" />
        </template>
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Prop, Vue, Model, Watch } from "vue-property-decorator";
    
    @Component
    export default class PropertySelector extends Vue {
      private childOptions: any[] = [];
      private cvalue: string | number = "";
      private pvalue: string | number = "";
      @Model("change") private mvalue!: string | number;
      @Prop() private options!: any[];
      @Watch("options")
      private onOptionsChanged(newOptions: any[], oldVal: any[]) {
        /*options更新时,处理相关内容*/
        if (newOptions.length > 0) {
          // 更新子options
          const childOptions = newOptions[0].children;
          this.$set(this, "childOptions", childOptions);
    
          // 更新选中值
          const pvalue = newOptions[0].id;
          if (this.hasChildren) {
            this.pvalue = pvalue;
          } else {
            this.$emit("change", "" + pvalue);
          }
        }
      }
    
      private onChidrenChanged(val: number | string) {
        this.cvalue = val;
        this.$emit("change", val);
      }
    
      private onParentChanged(event: any) {
        this.pvalue = event.target.value;
        this.updateChildren(event.target.value);
      }
    
      private onChanged(event: any) {
        this.$emit("change", event.target.value);
      }
    
      private updateChildren(pid: number | string) {
        const finded = this.options.filter((op: any) => {
          return Number(op.id) === Number(pid);
        });
        if (finded.length > 0) {
          this.$set(this, "childOptions", finded[0].children);
        }
      }
    
      private mounted() {
        if (this.options && this.options.length > 0) {
          const pid = this.options[0].id;
          this.updateChildren(pid);
          if (this.hasChildren) {
            this.pvalue = pid;
          } else {
            this.$emit("change", pid);
          }
        }
      }
    
      private get hasChildren() {
        if (this.childOptions) {
          return this.childOptions.length > 0;
        } else {
          return false;
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped lang="scss">
    .selectors {
      display: inline-flex;
    }
    </style>
    

      

  • 相关阅读:
    mui实现分页上拉加载更多 下拉刷新数据的简单实现 移动端下拉上拉
    滑动时候警告:Unable to preventDefault inside passive event listener
    vue-cli3 一直运行 /sockjs-node/info?t= 解决方案
    css设置不允许复制文本内容
    SDK manager打不开解决办法
    Android Studio 于夜神模拟器进行连接
    从零开始学 Java
    从零开始学 Java
    从零开始学 Java
    从零开始学 Java
  • 原文地址:https://www.cnblogs.com/xihui/p/13048989.html
Copyright © 2011-2022 走看看