Vue.js - Keep Alive Component - Error next Tick

2019-08-10 19:00发布

问题:

Description

I'm trying to take advantage of the keep-alive functionality of vue-js 2.3 so my AJAX call is made only once.

Problem

The second time I try to open the popup component I get this error :

Error in nextTick: "TypeError: Cannot read property 'insert' of undefined"

TypeError: Cannot read property 'insert' of undefined

Steps

Click on the button to display the popup

Wait for one second

Close the popup

Click again on the button

https://jsfiddle.net/4fwphqhv/

Minimal reproduction example

<div id="app">
  <button @click="showDialog = true">Show Component PopUp</button>
  <keep-alive>
      <popup v-if="showDialog" :show-dialog.sync="showDialog"></popup>
  </keep-alive>
</div>

<template id="popup">
    <el-dialog :visible.sync="show" @visible-change="updateShowDialog">{{asyncData}}</el-dialog>
</template>


Vue.component('popup', {
  template: '#popup',
  props : ['showDialog'],
  data(){
    return {
        show: this.showDialog,
      asyncData: "Loading please wait"
    }
  },
  methods: {
   updateShowDialog(isVisible) {
       if (isVisible) return false;
       this.$emit('update:showDialog', false )
   }
  },
   created:function (){
    const _this = this
    setTimeout(() => _this.asyncData = 'Async Data was loaded' , 1000)
  },
});

var vm = new Vue({
  el: '#app',
  data: {
    showDialog: false,
  },
});

Real code of the popup component

<template>
    <el-dialog title="Order in progress" size="large" :visible.sync="show" @visible-change="updateShowLoadOrder"></el-dialog>
</template>

<script>
  let popUpData;
  export default {
    name: '',
    data () {
      return {
        ordersInProgress: [],
        show: this.showLoadOrder
      }
    },
    props: ['showLoadOrder'],
    methods: {
      updateShowLoadOrder (isVisible) {
        if (isVisible) return false;
        this.$emit('update:showLoadOrder', false)
      }
    },
    created () {
      const _this = this;
      if (!popUpData) {
        axios.get('api/mtm/apiGetOrdersInProgress').then((response) => {
          _this.ordersInProgress = popUpData = response.data;
        });
      } else {
        this.ordersInProgress = popUpData;
      }
    }
  }
</script>

回答1:

Ok. So your problem here is the wrong life-cycle hook.

If you change created to activated... it should work. It did for me in your JS fiddle.

activated:function (){
    setTimeout(() => this.asyncData = 'Async Data was loaded' , 1000)
}

There are two other hooks, activated and deactivated. These are for keep-alive components, a topic that is outside the scope of this article. Suffice it to say that they allow you to detect when a component that is wrapped in a tag is toggled on or off. You might use them to fetch data for your component or handle state changes, effectively behaving as created and beforeDestroy without the need to do a full component rebuild.

SOURCE: here