清除隐藏的 bootstrap 模态主体

Clear bootstrap modal's body on hidden

我有一个使用 bootstrap vue 的 Nuxt 应用程序。

我有一个可重复使用的 Modal 组件

components/BaseModal.vue

<template>
  <b-modal id="base_modal" :title="title" size="md" @hidden="hide">
    <slot name="body"></slot>
    <hr>    
    <BaseButton class="btn" variant="outline-secondary" @click="close" buttonText="Cancel"/>      
    <slot name="footer"></slot>
  </b-modal>
</template>

<script>
export default {
  name: 'BaseModal',
  props: {
    title: { type: String, required: true },
    size: { type: String, default: "lg" }
  }, 
  methods: {  
    close() {
      this.$root.$emit('bv::hide::modal', 'base_modal');
    }, 
    hide() {
      // Clear slot body contents here
    }
  }
};
</script>

我通过使用命名范围呈现 html 个元素来调用此组件:

<template>
  <BaseButton @click="showModal" buttonText="Show Modal"/>

  <BaseModal title="Add Recommendation" size="md">
    <div slot="body">
      <b-form @submit.prevent="submit" autocomplete="off">
        <b-card-body>
          <b-row>
            <b-col><BaseTextInput v-model.trim="name" label="Headline"/></b-col>
          </b-row>
        </b-card-body>
      </b-form>
    </div>
    <BaseButton class="float-right btn" variant="outline-primary" @click="submit" buttonText="Save" slot="footer"/>
  </BaseModal>
</template>

<script>
  export default {
    name: 'FormInput',
    data() {
      return {
        name: ""
      } 
    },
    methods: {
      showModal: {
        this.$root.$emit('bv::show::modal','base_modal');
      },
      submit() {
        // dispatch creation
      }
    }
  }
</script>

如何在 隐藏 时 reset/clear modal 主体的内容,以便在触发 showModal 时它会再次重新呈现内容?

可以考虑以下解决方案:

选项 1:从模态组件发出事件

1) 模式关闭后,在 Modal 组件中发出自定义事件:

Modal.vue

<template>
  <b-modal id="base_modal" title="Modal example" @hidden="hide" >
    <slot name="body"></slot>
    <slot name="footer"></slot>
  </b-modal>
</template>

<script>
export default {
  name: "BaseModal",
  methods: {
    hide() {
      this.$emit('hide')
    }
  }
};
</script>

2) 然后在父组件中,一旦 hide 事件被触发,表单值可以像这样被清除:

App.vue

<template>
  <div>
    <b-button @click="showModal" ref="btnShow">Open Modal</b-button>
    <ModalExample @hide="hideModal">
      <div slot="body">
        <form @submit.stop.prevent="handleSubmit">
          <b-form-input type="text" placeholder="Enter your name" v-model="name"></b-form-input>
        </form>
      </div>
    </ModalExample>
  </div>
</template>

<script>
import ModalExample from "./components/ModalExample.vue";

export default {
  components: {
    ModalExample
  },
  data() {
    return {
      name: ""
    };
  },
  methods: {
    showModal() {
      this.$root.$emit("bv::show::modal", "base_modal");
    },
    hideModal() {
      this.name = ''; //clear form values
    }
  }
};
</script>

Here is a demo 演示了这种方法。

选项 2:利用作用域插槽

模态组件可以通过 scoped slots:

访问数据

ModalExample.vue

<template>
  <b-modal id="base_modal" title="Modal example" @hidden="hide" >
    <slot :formData="formData" name="body"></slot>
    <slot name="footer"></slot>
  </b-modal>
</template>

<script>
export default {
  name: "ModalExample",
  data() {
    return {
      formData : {}
    }
  },
  methods: {
    hide() {
      //clear form fields
      for (const name of Object.keys(this.formData)) {
        this.formData[name] = ""
      }
    }
  }
};
</script>

App.vue

<template>
  <div>
    <b-button @click="showModal" ref="btnShow">Open Modal</b-button>
    <ModalExample @hide="hideModal">
      <template slot="body" slot-scope="{formData}">
        <form @submit.stop.prevent="handleSubmit">
          <b-form-input
            type="text"
            placeholder="Enter your first name"
            v-model="formData.firstname"
          ></b-form-input>
          <b-form-input
            type="text"
            placeholder="Enter your last name"
            v-model="formData.lastname"
          ></b-form-input>
        </form>
      </template>
    </ModalExample>
  </div>
</template>

<script>
import ModalExample from "./components/ModalExample.vue";

export default {
  components: {
    ModalExample
  },
  data() {
    return {
    };
  },
  methods: {
    showModal() {
      this.$root.$emit("bv::show::modal", "base_modal");
    }
  }
};
</script>