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

dlk*_*ulp 9 javascript preprocessor-directive vue.js

问题

我有一个子组件,它可能存在也可能不存在于带有v-if. 试图在用户单击其他内容时将其缓存,以便无论我如何尝试使用<keep-alive>.

我试过的

文件似乎表明,所有我需要做的就是总结我的成分在<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
    }
  },
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

PS 我不知道除了 Vue.js 之外如何标记这个

ski*_*tle 9

这是您的代码的轻微修改版本,可以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
    }
  },
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

created钩仅称为第一次。在随后的激活中,activated钩子会被调用,但不会被调用created

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

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

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

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