VueJS-列表数组和独立显示/隐藏

时间:2019-09-09 00:08:52

标签: javascript vue.js vue-cli

我试图弄清楚如何使列出的每个项目都独立隐藏和显示,当前当您打开一个项目时,另一个也会打开。我需要使用某种索引吗?我之所以使用v-show,是因为我需要先呈现内容并在加载时将其隐藏,但在点击时显示。

<template>
    <div>
        <div v-for="item in items" :key="item">
            {{ item.title }}

            <div v-if="item.examples != null">
                <a v-on:click="visibleExample = !visibleExample">Example</a>
                <transition name="fade">
                    <div v-show="visibleExample">
                        <div v-for="example in item.examples" :key="example">
                            {{ example }}
                        </div>
                    </div>
                </transition>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                visibleExample: false,
                items: [{
                        title: 'Title',
                        examples: [
                            'Question',
                            'Answer'
                        ]
                    },
                    {
                        title: 'ABC',
                        examples: [
                            '1',
                            '2',
                            '3',
                            '4',
                            '5'
                        ]
                    }
                ]
            }
        }
    }
</script>

请注意:这是我的原始代码的简化版本。

3 个答案:

答案 0 :(得分:1)

您有三个主要选择:

  1. visibleExample使用布尔数组,并按索引与items配对。可以使用v-for中的索引在模板中执行配对,也可以使用计算属性将两个数组“合并”。
  2. 向您的每个items添加一个布尔属性,该布尔属性用于确定是否应为该特定项目显示示例。
  3. 提取一个单独的组件来代表一个项目。这可能包括v-for中的所有内容,也可能仅包含示例部分。无论哪种方式,在visibleExample中都有一个data属性,每个组件都拥有自己的状态。这通常是最好的解决方案,但是如果您需要在组件外部使用visibleExample状态,则可以轻松解决。对于问题中的代码来说,这不是问题,但这取决于完整代码的样子。

答案 1 :(得分:1)

您可以使用新的项目辅助列表,并且可以为项目列表的每个对象附加新的boolean属性。然后,您可以在auxItems上使用v-for,如下所示:

Vue.config.devtools = false
Vue.config.productionTip = false
new Vue({
  el: "#app",
  data() {
    return {
      items: [
        {
          title: 'Title',
          examples: [
            'Question',
            'Answer'
          ]
        },
        {
          title: 'ABC',
          examples: [
            '1',
            '2',
            '3',
            '4',
            '5'
          ]
        }
    	],
      auxItems: []
    }
  },
  mounted () {
    this.auxItems = this.items.map(i => ({ ...i, isVisible: false }))
  }
})
.item {
  border: 1px solid black
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="item in auxItems" :key="item.title" class="item">
    {{ item.title }}
    <div v-if="item.examples !== null">
      <a v-on:click="item.isVisible = !item.isVisible">Example</a>
      <transition name="fade">
        <div v-show="item.isVisible">
          <div v-for="example in item.examples" :key="example">
            {{ example }}
          </div>
        </div>
      </transition>
    </div>
  </div>
</div>

答案 2 :(得分:0)

如您所建议,解决该问题的一种方法是跟踪当前选定的项目。

可以通过执行以下操作来实现:

<div v-if="item.examples != null">
   <a v-on:click="visibleExample = !visibleExample; crtSelectedItem = item">Example</a>
   <transition name="fade">
    <div v-show="visibleExample && item.id === crtSelectedItem.id">
        <div v-for="example in item.examples" :key="example">
           {{ example }}
        </div>
     </div>
   </transition>
 </div>