Vuejs - 使用 v-if 切换的保持活动组件

Vuejs - keep-alive component toggled with v-if

问题

我有一个子组件可能存在也可能不存在于带有 v-if 的页面上。尝试在用户单击其他内容时将其缓存起来,以便在用户 returns 失败时再次显示搜索词和诸如此类的东西,无论我如何尝试使用 <keep-alive>.

进行缓存

我试过的

documentation 似乎表明我需要做的就是将我的组件包装在 <keep-alive> 标记中,事情应该会正常进行。我尝试匹配一些使用显然不起作用的 <component> 标签的文档。我也尝试使用 include 道具,因为只是包装它不起作用。

Vue.component('child', {
  template: '<div>child: {{text}}<div>',
  data() {return {text: ""}},
  created(){
    this.$nextTick(() => {
      this.text = `${Math.round(Math.random() * 100)}`
  })
},
  activated: function() {
    this.$nextTick(() => {
     console.log('in activated');
    });
  }
})

var vm = new Vue({
  el: '#app',
  data: function() {
    return {
      showNow:false,
      message: 'This is a test.'
    }
  },
  methods: {
    changeText: function() {
      this.message = 'changed';
    },
    toggle() {
      this.showNow = !this.showNow
    }
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <keep-alive include="child">
    <div v-if="showNow">
        <h4>Title of section to be toggled</h4>
        <component is="child"></component>
    </div>
  </keep-alive>
  
  <button @click="toggle()">toggle child</button>
</div>

我也尝试过不使用 include 而只是像这样包装 <keep-alive><child></child></keep-alive> 或使用 <component> 语法,但这些都不起作用。

如果去掉条件渲染,activated 钩子会被调用,但这显然违背了<keep-alive> 的目的!就目前而言,该钩子从未被调用,这令人沮丧。

此外,文档中的 the example 也无济于事,因为他们没有使用 v-if,只是更改通过字符串呈现的组件....

P.S。除了 Vue.js

之外,我不知道如何标记它

这里是您的代码的一个轻微修改版本,keep-alive 可以正常工作:

Vue.component('child', {
  template: '<div>child: {{text}}</div>',
  data() {return {text: ""}},
  created(){
    console.log('in created')
    this.$nextTick(() => {
      this.text = `${Math.round(Math.random() * 100)}`
    })
  },
  activated: function() {
    this.$nextTick(() => {
     console.log('in activated');
    });
  }
})

var vm = new Vue({
  el: '#app',
  data: function() {
    return {
      showNow:false,
      message: 'This is a test.'
    }
  },
  methods: {
    changeText: function() {
      this.message = 'changed';
    },
    toggle() {
      this.showNow = !this.showNow
    }
  },
});
<script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script>
<div id="app">
  <keep-alive>
    <child v-if="showNow"></child>
  </keep-alive>
  
  <button @click="toggle()">toggle child</button>
</div>

created 挂钩仅在第一次调用。在随后的激活中,调用 activated 挂钩但不调用 created.

关键的变化是 <child> 组件必须是 <keep-alive> 的直接子组件。此直接子项还必须是具有 v-if.

的组件

您不能为此目的使用 <div>,因为 <keep-alive> 专门查找组件,而不仅仅是元素。参见:

https://github.com/vuejs/vue/blob/ec78fc8b6d03e59da669be1adf4b4b5abf670a34/src/core/components/keep-alive.js#L85

keep-alive 的另一个常见错误是将 v-if 放在 keep-alive 组件本身或其祖先之一上。这将不起作用,因为 keep-alive 组件本身将被销毁。 keep-alive 组件维护子组件的缓存,但如果 keep-alive 本身被销毁,那么该缓存将丢失。