如何根据父组件的点击事件打开添加模式-vuejs

Posted

技术标签:

【中文标题】如何根据父组件的点击事件打开添加模式-vuejs【英文标题】:how to open add modal based on click event from Parent component- vuejs 【发布时间】:2021-07-18 20:05:09 【问题描述】:

有一个产品页面,其中有产品列表组件和操作按钮。这是父组件。该产品列表组件由列表表和编辑/添加模式组成。现在,问题是添加动作事件在父组件中。但是,添加模态相关数据在子组件中可用。

那么,如何根据父级的点击事件打开该模型?这里我就是这样做的。

父组件(产品组件 sn-ps)

<template>
  ..... other code ....
   <div class="action-buttons">
       <vu-button class="add-action" @click="onAddAction">
          <svg-icon
               fill="#0071E3"
               name="add"
               
               
           />
       </vu-button>
   </div>
 <ChildComponent :open-add-modal="isAddModal" />
</template>

父组件中的方法

onAddAction() 
       this.editable = false;
       this.isAddModal = true;
    ,

现在,在子组件中,我传递布尔道具 openAddModal 但我正在检查条件到创建的钩子以显示添加模式。

问题在于初始渲染或页面加载添加模式未在点击事件中显示。我该如何解决这个问题?

子组件(创建的钩子)

created() 
    if(this.openAddModal) 
         this.showModal = true;
         this.formType = 'add';
         this.editId = null;
  
,

我想显示基于来自父级的点击事件的添加模式,而不是在初始页面加载中。

【问题讨论】:

是 v-for loopt 吗?有很大的不同;)在我看来,isAddModal 的初始值是true,如果它在渲染期间打开的话。请提供MCVE 【参考方案1】:

您可以尝试使用观察程序,而不是在 created 钩子中检查 open-add-modal 的值。这样,当子组件中的 prop open-add-modal 发生变化时,您可以检查那里的新值并将所需的数据发送给父组件,然后打开模态。

例子:

父组件代码

<template>
  <div>
    <p>Parent component</p>

    <button @click="changeOpenAddModal">Clic to get child data</button>
    <button @click="resetParent">Reset data in parent</button>
    <p>Data from child:  childData </p>

    <br />
    <br />
    <Child
      :openAddModal="this.openAddModal"
      @child-component-data-emit="this.setChildData"
    />
  </div>
</template>

<script>
import Child from "./Child";

export default 
  name: "Parent",
  components:  Child ,
  data() 
    return 
      childData: null,
      openAddModal: false,
    ;
  ,
  methods: 
    changeOpenAddModal() 
      this.openAddModal = !this.openAddModal;
      console.log(
        "changing openAddModal data. New value is ",
        this.openAddModal
      );
    ,
    setChildData(data) 
      console.log("setting child data", data);
      this.childData = data;
    ,
    resetParent() 
      this.childData = null;
      this.changeOpenAddModal();
    ,
  ,
;
</script>

子组件代码

<template>
  <div>
    <p>Child component</p>
  </div>
</template>

<script>
export default 
  name: "Child",
  props: 
    openAddModal: 
      type: Boolean,
      default: false,
    ,
  ,
  data() 
    return 
      childData: 
        prop1: "lorem",
        prop2: "ipsum",
        prop3: "dolor",
      ,
    ;
  ,
  watch: 
    openAddModal: function (newValue, oldValue) 
      console.log("child watcher with newValue", newValue);
      if (newValue) 
        this.$emit("child-component-data-emit", this.childData);
      
    ,
  ,
  mounted: function () 
    console.log("prop openAddModal value on mounted:", this.openAddModal);
  ,
;
</script>

【讨论】:

【参考方案2】:

我已经使用 Vue 2 和 Vue CLI 构建了一些模式,并使用另一种方法来显示、隐藏以及确定是添加还是编辑模式。不需要监视或单独的添加/编辑模式布尔值。

“产品”处理有些人为,因为在此示例中没有使用数据库或 AJAX,但您应该能够评估功能。

父.vue

<template>
  <div class="parent">
    <h4>Parent of Form Modal</h4>
    <div class="row">
      <div class="col-md-6">
        <button class="btn btn-secondary" @click="showAddModal">Show Add Modal</button>
        <button class="btn btn-secondary btn-edit" @click="showEditModal">Show Edit Modal</button>
      </div>
    </div>
    <form-modal v-if="displayModal"
      :parentProduct="product"
      @save-product-event="saveProduct"
      @close-modal-event="hideModal"
    />
  </div>
</template>

<script>
  import FormModal from './FormModal.vue'

  export default 
    components: 
      FormModal
    ,
    data() 
      return 
        product: 
          id: 0,
          name: '',
          description: ''
        ,
        displayModal: false
      
    ,
    methods: 
      showAddModal() 
        this.resetProduct();
        this.displayModal = true;
      ,
      showEditModal() 
        this.product.id = 1;
        this.product.name = 'productEdit';
        this.product.description = 'productEditDescription';
        this.displayModal = true;
      ,
      hideModal() 
        this.displayModal = false;
      ,
      saveProduct(modalProduct) 
        this.product = modalProduct;
        this.hideModal();
        console.log(this.product);
      ,
      resetProduct() 
        this.product.id = 0;
        this.product.name = '';
        this.product.description = '';
      
    
  
</script>

<style scoped>
  .btn-edit 
    margin-left: 0.5rem;
  
</style>

FormModal.vue

<template>
  <!-- The Modal -->
  <div id="form-modal" class="modal-dialog-container">
    <div class="modal-dialog-content">
      <div class="modal-dialog-header">
        <h4> modalTitle </h4>
      </div>
      <div class="modal-dialog-body">
        <form @submit.prevent="saveProduct">
          <div class="form-group">
            <label for="product-name">Name</label>
            <input type="text" class="form-control" id="product-name" v-model="product.name">
          </div>
          <div class="form-group">
            <label for="product-description">Description</label>
            <input type="text" class="form-control" id="product-description" v-model="product.description">
          </div>
          <button type="submit" class="btn btn-primary">Submit</button>
          <button type="button" class="btn btn-secondary btn-close" @click="closeModal">Cancel</button>
        </form>
      </div>
    </div>
  </div>
</template>

<script>
  export default 
    props: 
      parentProduct: 
        type: Object,
        required: true
      
    ,
    data() 
      return 
        product: this.parentProduct
      
    ,
    computed: 
      modalTitle() 
         return this.product.id === 0 ? 'Add Product' : 'Edit Product';
      
    ,
    methods: 
      closeModal() 
        this.$emit('close-modal-event');
      ,
      saveProduct() 
        // Add product
        if (this.product.id === 0) 
          this.product.id = 2;
        
        this.$emit('save-product-event', this.product);
      
    
  
</script>

<style scoped>
  .modal-dialog-container 
    /* display: none; Hidden by default */
    position: fixed;
    /* Stay in place */
    z-index: 1;
    /* Sit on top */
    left: 0;
    top: 0;
    width: 100%;
    /* Full width */
    height: 100%;
    /* Full height */
    overflow: auto;
    /* Enable scroll if needed */
    background-color: rgb(0, 0, 0);
    /* Fallback color */
    background-color: rgba(0, 0, 0, 0.4);
    /* Black w/ opacity */
  

  .modal-dialog-content 
    background-color: #fefefe;
    margin: 10% auto;
    padding: 20px;
    border: 1px solid #888;
    border-radius: 0.3rem;
    width: 30%;
  

  .btn-close 
    margin-left: 0.5rem;
  
</style>

【讨论】:

以上是关于如何根据父组件的点击事件打开添加模式-vuejs的主要内容,如果未能解决你的问题,请参考以下文章

VueJS:在子组件中触发事件时在父组件中运行函数

Vuejs 3 从子组件向父组件发出事件

如何在 VueJs 中添加动态/异步/惰性组件

发出的事件不会调用 Vue JS 组件中的父方法

VueJS子组件按钮更改父类

修改 vuejs 中父组件通过槽添加的子组件数据