数组长度更改时,v-for内部的keep-alive不起作用

时间:2018-06-29 07:40:37

标签: vue.js

我正在尝试根据计算值来渲染组件。但是,当数组长度从先前的长度更改时,<keep-alive>标签将不起作用。

我希望cOption组件创建的钩子只触发一次, 但它继续记录其“ cOption已创建!”每次flag值切换为false时都会显示一条消息。

我正在使用Vue版本^ 2.5.13(使用Nuxt版本1.4.0)

这是我的代码:

new Vue({
  el: '#app',
  data() {
    return {
      flag: false
    }
  },
  computed: {
    options() {
      let opts = []
      if (this.flag) opts.push('aOption')
      else {
        opts.push('bOption', 'cOption')
      }
        
      return opts
    }
  },
  components: {
    defaultOption: {
      template: '<span>defaultOption</span>',
    },
    aOption: {
      template: '<span>aOption {{ flag }}</span>',
      props: {
        flag: {
          type: Boolean,
          default: false
        }
      },
      created: function() {
        console.log("aOption created!")
      },
    },
    bOption: {
      template: '<span>bOption {{ flag }}</span>',
      props: {
        flag: {
          type: Boolean,
          default: false
        }
      },
      created: function() {
        console.log("bOption created!")
      },
    },
    cOption: {
      template: '<span>cOption {{ flag }}</span>',
      props: {
        flag: {
          type: Boolean,
          default: false
        }
      },
      created: function() {
        console.log("cOption created!")
      },
    }
  }
})
<script src="https://unpkg.com/vue@2.5.13"></script>

<div id="app">
  <div>  
    <button @click='flag = !flag'>
        toggle option
    </button>
    <div v-for='option in options'>
        <keep-alive>
          <component :is='option' :flag='flag' :key='option' />
        </keep-alive>
    </div>
  </div>
</div>

Here's a js fiddle of the above code

1 个答案:

答案 0 :(得分:1)

正在发生的事情是,当options数组从只有两个项目变为只有一个项目时,第二个<keep-alive>标签就被销毁了。因此,当数组变回两个项目时,将创建<keep-alive>组件,其中的<component>也将创建。

您想防止<keep-alive>被破坏。一种简单的方法是在flag值为true时,在数组中的第二个项目中提供一个空字符串:

computed: {
  options() {
    return this.flag ? ['aOption', ''] : ['bOption', 'cOption'];
  }
}

这样,v-for将保留第二个<keep-alive>,而动态<component>则不会呈现任何内容。


这是您所做的更改的代码:

new Vue({
  el: '#app',
  data() {
    return { flag: false }
  },
  computed: {
     options() {
        return this.flag ? ['aOption', ''] : ['bOption', 'cOption'];
     }
  },
  components: {
    aOption: {
      template: '<span>aOption {{ flag }}</span>',
      props: {
        flag: { type: Boolean, default: false }
      },
      created: function() {
        console.log("aOption created!")
      },
    },
    bOption: {
      template: '<span>bOption {{ flag }}</span>',
      props: {
        flag: { type: Boolean, default: false }
      },
      created: function() {
        console.log("bOption created!")
      },
    },
    cOption: {
      template: '<span>cOption {{ flag }}</span>',
      props: {
        flag: { type: Boolean, default: false }
      },
      created: function() {
        console.log("cOption created!")
      },
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>

<div id="app">
  <div>  
    <button @click='flag = !flag'>toggle option</button>
    <div v-for='option in options'>
      <keep-alive>
        <component  :is='option' :flag='flag' :key='option' />
      </keep-alive>
    </div>
  </div>
</div>