当在父项中单击按钮时,使所有 <b-collapse> 在 child.vue 中不可见

make all <b-collapse> non visible in child.vue when button is clicked in parent

我正在与 BootstrapVue 合作。

我有以下情况:我有一个 parent.vue 和一个 child.vue。在我的 parent.vue 中,我有一个 v-for,我可以在其中创建多个 Buttons。这些中的每一个都在我的 child.vue 中触发了一个 b-collapse,并且每个都有多个 b-collapse。 (见代码)

现在我需要执行以下操作:当我的 parent.vue 中的 b-collapse 将被关闭时,我想关闭我的 child.vue 中的所有 b-collapse。但我不知道该怎么做......(当我重新打开我的 parent.vue-collapse 时它们也应该关闭)

我已将我的代码减少到最少。但只是为了获得更多信息,我会在每次添加新项目或元素时执行 this.inputs.push[{id: this.id +=1}]。所以他们每个人都有一个 unique id.

希望有人能帮帮我!

代码

parent.vue

<div v-for="item in inputs" :key="item.id">
  <b-button v-b-toggle="'NewItem'+item.id"></b-button>
</div>

<Child/>

<b-button @click="addNewItem()"></b-button>

child.vue

<b-collapse visible :id="'NewItem' + item.id">  //Here i need a solution
  <div v-for="element in inputs" :key="element.id">
    <b-button v-b-toggle="'Element' + element.id"></b-button>
    <b-collapse :id="'Element' + element.id>
      <div>Here is Element {{element.id}}</div>
    </b-collapse>
  </div>

  <b-button @click="addElement()"></b-button>
</b-collapse>

编辑 - 完整代码:

Parent.vue

<template>
<div class="container">
  <div v-for="(item, index) in inputs" :key="item.id">
    <b-button v-b-toggle="'NewItem'+item.id" @click="closeAll()">Item {{index + 1}}</b-button>
  </div>

  <Child :idParent="item.id" :closeAllProducts="closeAllProducts" />

  <b-button @click="addNewItem()">Add new Item</b-button>
</div>
</template>

<script>

import Child from "./components/child.vue"

export default {

  components: {
    Child,
  },

  data() {
    return {
      closeAllProducts: true,
      id: 1,
      inputs: [{
        id: 1,
      }]
    }
  },

  methods: {
    addNewItem() {
      this.inputs.push({id: this.id += 1})
    },

    closeAll() {
      this.closeAllProducts = false;
    }
  }
}
</script>

Child.vue

<template>
  <b-collapse :visible="closeAllProducts" :id="'NewItem'+item.id">  
    <div v-for="(element, index) in inputs" :key="element.id">
      <b-button v-b-toggle="'Element' + element.id"></b-button>
      <b-collapse :id="'Element' + element.id">
        <div>Here is Element {{index + 1}}</div>
      </b-collapse>
    </div>

    <b-button @click="addElement()">Add new Element</b-button>
  </b-collapse>
</template>

<script>
export default {
  props: ["idParent", "closeAllProducts"],

  data() {
    return {
      id: 1,
      inputs: [{
        id: 1,
      }]
    }
  },

  methods: {
    addElement() {
      this.inputs.push({id: this.id += 1})
    }
  }
}
</script>

新编辑:添加了 closeAllProducts - 如果我在我的 parent.vue 中点击我的 button 它应该触发函数改变boolean**false**。但是当我像这样使用它时,每个项目中的所有元素都是 non visible.. 我需要用它传递一个 parameter 但我不知道如何..

一个解决方案是创建一个折叠其 b-collapse 元素的 child 道具,并让 parent 控制该道具:

  1. 在 child:

    中创建一个名为 collapsed 的布尔属性
    // child.vue
    export default {
      props: {
        collapsed: Boolean
      }
    }
    
  2. addElement() 中,插入一个 visible 属性以匹配 b-collapsevisible 属性。我们会将每个项目的 visible 绑定到相应的 b-collapse 道具。请注意,我们使用 b-collapsev-model 来绑定其 visible 道具,这使项目的 visible 道具与实际可见性状态保持同步。

    <!-- child.vue -->
    <script>
    export default {
      data() {
        return {
          inputs: [
            {
              id: 1,
              visible: false,
            },  
          ],
        }
      },
      methods: {
        addElement() {
          this.inputs.push({ id: ++this.id, visible: false })
        }                                      
      }
    }
    </script>
    
    <template>
      ⋮                              
      <b-collapse v-model="element.visible" ⋯>
         <div>Here is Element {{ index + 1 }}</div>
      </b-collapse>
    </template>
    
  3. 在 child 中的 collapsed 属性上添加一个 watcher。仅当 collapsedtrue:

    时,此观察者才会将每个元素的 visible 属性设置为 false
    // child.vue
    export default {
      watcher: {
        collapsed(collapsed) {
          if (collapsed) {
            this.inputs.forEach(input => input.visible = false)
          }
        },
      }
    }
    
  4. 要确保每个元素的 ID 在 parent 的上下文中是全局唯一的,请将 parent ID 合并到 child ID 中:

    <!-- child.vue -->
    <div v-for="(element, index) in inputs" :key="element.id">
      <b-button v-b-toggle="'Element' + idParent + '.' + element.id" ⋯>
        ⋯                                   
      </b-button>
      <b-collapse :id="'Element' + idParent + '.' + element.id" ⋯>
        ⋯                             
      </b-collapse>
    </div>
    
  5. 在parent的addNewItem()中添加一个collapsed属性。我们将每个 child 的 collapsed 属性绑定到这个新的 属性,并在 button-click:

    上切换它
    <!-- parent.vue -->
    <script>
    export default {
      data() {
        return {
          inputs: [
            {
              id: 1,
              collapsed: false,
            },  
          ],
        }
      },
      methods: {
        addNewItem() {
          this.inputs.push({ id: ++this.id, collapsed: false })
        }                                      
      }
    }
    </script>
    
    <template>
      ⋮
      <div v-for="(item, index) in inputs" :key="item.id">
        <b-button @click="item.collapsed = !item.collapsed">
          ⋯                       
        </b-button>
        <Child :idParent="item.id" :collapsed="item.collapsed" />
      </div>                                          
    </template>
    

demo