【问题标题】:how to open add modal based on click event from Parent component- vuejs如何根据父组件的点击事件打开添加模式-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"
               height="20"
               width="28"
           />
       </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

标签: javascript vue.js vuejs2


【解决方案1】:

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

例子:

父组件代码

<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>
    

    【讨论】:

      猜你喜欢
      • 2020-03-29
      • 1970-01-01
      • 1970-01-01
      • 2021-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-12
      • 1970-01-01
      相关资源
      最近更新 更多