每次弹窗组件都要重置数据?试试动态组件

398 阅读1分钟

先看问题

20221021_101541[00_00_00--00_00_13].gif

可以看到,点击新增按钮,填写了数据,关掉弹窗,再打开的时候数据还在

看看代码:

App.vue

<template>
  <div id="app">
    <a-button @click="open">新增</a-button>
    <form-test :visible="visible" @cancel="cancel" @ok="ok" />
  </div>
</template>

<script>
import FormTest from "./components/form-test";

export default {
  name: 'App',
  components: {
    FormTest,
  },
  data(){
    return {
      visible:false,
    }
  },
  methods:{
    open(){
      this.visible = true;
    },
    cancel(){
      this.visible = false;
    },
    ok(form_data){
      this.visible = false;
    },

  }
}
</script>

<style>

#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  padding-top: 60px;
}
</style>

form-test.vue

<template>
<a-modal title="标题" :visible="visible"
         @cancel="cancel"
         @ok="ok"
>
  <a-form-model>
    <a-form-model-item label="输入框">
      <a-input v-model="form_data.test"/>
    </a-form-model-item>

  </a-form-model>
</a-modal>
</template>

<script>
export default {
  name: "form-test",
  props:{
    visible:Boolean,
  },
  data(){
    return {
      form_data:{}
    }
  },
  methods:{
    cancel(){
      this.$emit('cancel')
    },
    ok(){
      this.$emit('ok',this.form_data)
    },
  }
}
</script>

<style scoped>

</style>

代码在app.vue的时候,直接实例化的form-test.vue组件,该组件就算关闭了弹窗,实际上组件本身还是一直存在的,只是没有渲染出来而已,所以每次打开的时候需要把data里面的数据都重置了

像这样

  watch:{
    visible(v){
      if(v){
        this.form_data = {}
      }
    }
  },

但是,如果data字段很多的话, 都要重置也很麻烦,以后组件没新增字段都要考虑重置问题

如何解决?

那我们看看如何用动态组件解决

app.vue做如下修改:

<template>
  <div id="app">
    <a-button @click="open">新增</a-button>
    <component :is="component_val" :visible="visible" @cancel="cancel" @ok="ok"></component>
  </div>
</template>

<script>
import FormTest from "./components/form-test";

export default {
  name: 'App',
  components: {
  },
  data(){
    return {
      visible:false,
      component_val:'',
    }
  },
  methods:{
    open(){
      this.component_val = FormTest;
      this.visible = true;
    },
    cancel(){
      this.component_val = '';
      this.visible = false;
    },
    ok(form_data){
      this.component_val = '';
      this.visible = false;
    },

  }
}
</script>

我们使用动态组件来渲染我们需要的组件,关闭弹窗的时候把组件设置为空,就会销毁弹窗

并且可以看到我们每次点击新增按钮,都会调用created方法,如果没有点击添加,from表单组件也不会实例化的

image.png

总结

使用动态组件,我们可以得到如下好处:

子组件如果不需要打开,是不会初始化的 子组件每次都会初始化新的,所以子组件的数据都不会保存,也就不需要我们清理了

但也有缺点

就是每次会初始化新的子组件,如果初始化很耗资源,那可能还是初始化一次就好