【问题标题】:Display dropdowns dynamically in one component在一个组件中动态显示下拉菜单
【发布时间】:2021-06-11 04:57:53
【问题描述】:

我想在一个组件中使用一个变量来显示或不显示多个下拉菜单,并点击远离它们的 div 以关闭它们:

<div class="dropdown">
  <button @click.prevent="isOpen = !isOpen"></button>
    <div v-show="isOpen">Content</div>
</div>
// second dropdown in same component
<div class="dropdown">
  <button @click.prevent="isOpen = !isOpen"></button>
    <div v-show="isOpen">Content</div>
</div>
data() {
  return {
    isOpen: false
  }
},
watch: {
  isOpen(isOpen) {
    if(isOpen) {
      document.addEventListener('click', this.closeIfClickedOutside)
    }
  }
},
methods: {
  closeIfClickedOutside(event){
    if(! event.target.closest('.dropdown')){
      this.isOpen = false;
    }
  }
}

但是现在当我单击一个下拉菜单时,它会同时显示它们。我对 vue 有点陌生,找不到解决这个问题的方法

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    要为此仅使用一个变量,该变量需要识别打开的下拉菜单,因此它不能是布尔值。我建议将索引(例如,一个数字)存储在变量中,并通过索引有条件地呈现选定的下拉列表:

    1. 声明一个数据属性来存储选中的索引:

      export default {
        data() {
          return {
            selectedIndex: null
          }
        }
      }
      
    2. 更新closeIfClickedOutside() 以清除所选索引,从而关闭下拉菜单:

      export default {
        methods: {
          closeIfClickedOutside() {
            this.selectedIndex = null
          }
        }
      }
      
    3. 在模板中,更新click-handlers 来设置选中的索引:

      <button @click.stop="selectedIndex = 1">Open 1</button>
      <button @click.stop="selectedIndex = 2">Open 2</button>
      
    4. 另外,更新v-show 条件以根据索引进行渲染:

      <div v-show="selectedIndex === 1">Content 1</div>
      <div v-show="selectedIndex === 2">Content 2</div>
      

    另外,不要使用观察程序在document 上安装click 处理程序,因为我们想知道渲染此组件时的外部点击。在mounted 钩子中添加处理程序会更合适,然后在beforeDestroy 钩子中删除:

    export default {
      mounted() {
        document.addEventListener('click', this.closeIfClickedOutside)
      },
      beforeDestroy() {
        document.removeEventListener('click', this.closeIfClickedOutside)
      },
    }
    

    demo

    【讨论】:

      【解决方案2】:

      创建一个数组并循环遍历它,这样更容易。

      <template>     
      <div id="app">
              <div class="dropdown" v-for="(drop, index) in dropData" :key="index">
            <button @click="openDropdown(index);">{{ drop.title }}</button>
              <div v-show="isOpen === index">{{ drop.content }}</div>
          </div>
            </div>
          </template>
          
          <script>
          export default {
            data() {
              return {
                isOpen: null,
                dropData: [
                  {
                    title: "Hey",
                    content: "Hey it's content 1"
                  },
                    {
                    title: "Hey 2",
                    content: "Hey it's content 2"
                  },
                    {
                    title: "Hey 3",
                    content: "Hey it's content 3"
                  },
                ]
              };
            },
           
          methods: {
              openDropdown(idx){
               if (this.isOpen === idx) {
                    this.isOpen = null;
                  } else {
                  this.isOpen = idx;
                  }
          
              }
          
          }
          };
          </script>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-12
        • 1970-01-01
        • 1970-01-01
        • 2017-06-09
        • 2013-03-20
        • 1970-01-01
        • 1970-01-01
        • 2020-12-09
        相关资源
        最近更新 更多