如何使用 props 动态挂载 vue 组件

Posted

技术标签:

【中文标题】如何使用 props 动态挂载 vue 组件【英文标题】:How to dynamically mount vue component with props 【发布时间】:2020-07-02 08:20:42 【问题描述】:

场景/上下文

我有一个概览组件,其中包含一个表格和一个添加按钮。添加按钮打开一个模态组件。当我在模式中填写一些文本字段并单击保存按钮时,会调用一个回调(作为道具给出),以便更新父组件(概述)。保存按钮还会触发模型切换功能,因此模型会关闭。

到目前为止,一切都像预期的那样工作,但是当我想添加第二个条目时,模式是用最近添加的项目的数据“预填充”的。

我很清楚这是因为模型组件一直挂载在后台(所以它只是隐藏了)。我可以通过在触发切换功能时“重置”模态数据来解决这个问题,但我认为应该有更好的方法。

当我想在模式中获取数据时,我遇到了类似的问题。目前我在模式的挂载钩子中调用 fetch 函数。所以在这种情况下,当父组件挂载模态时,就会发生获取。这没有意义,因为它应该只(并且每次)在打开模式时获取。

我认为解决此问题的最佳方法是在我单击“添加”(打开模式)按钮时动态安装模式组件,但我找不到如何实现这一点。这也避免了后台挂载了很多可能不使用的组件。

截图

示例代码

概述:

<template>
  <div>
    // mount of my modal component
    <example-modal
        :toggleConstant = modalToggleUuid
        :submitHandler = submitHandler />
    // The overview component html is here
    </div>
</template>

<script>
  export default 
    data() 
      return 
                modalToggleUuid: someUuid,
                someList: [],
            
    ,

    mounted() 

    ,

    methods: 
          showModal: function() 
        EventBus.$emit(this.modalToggleUuid);
      ,

            submitHandler: function(item) 
                this.someList.push(item);
            
    
  
</script>

模态:

<template>
  <div>
    <input v-model="item.type">
    <input v-model="item.name">
    <input v-model="item.location">
    </div>
</template>

<script>
  export default 
    data() 
      return 
                modalToggleUuid: someUuid,
                item: ,
            
    ,

    mounted() 
            // in some cases i fetch something here. The data should be fetched each time the modal is opened 
    ,

    methods: 
          showModal: function() 
        EventBus.$emit(this.modalToggleUuid);
      ,

            submitHandler: function(item) 
                this.someList.push(item);
            
    
  
</script>

问题

处理上述情况的最佳实践是什么?

我应该动态挂载模态组件吗? 我是否正确安装了组件,我是否应该一直重置内容?

【问题讨论】:

【参考方案1】:

你走在正确的道路上,为了实现你想要的,你可以像这样使用v-if 解决方案来解决这个问题 - 然后mounted() 钩子将在你每次切换模式时运行,它也不会不使用时存在于 DOM 中。

<template>
  <div>
    // mount of my modal component
    <example-modal
      v-if="isShowModal"
      :toggleConstant="modalToggleUuid"
      :submitHandler="submitHandler"
    />
    // The overview component HTML is here
  </div>
</template>

<script>
export default 
  data() 
    return 
      isShowModal: false,
      modalToggleUuid: someUuid,
      someList: []
    ;
  ,

  mounted() ,

  methods: 
    showModal: function() 
      this.isShowModal = true;
    ,

    submitHandler: function(item) 
      this.someList.push(item);
      this.isShowModal = false;
    
  
;
</script>

【讨论】:

实现我想要的东西的好方法!是“Vue 方式”还是只是一种工作方式?是否也建议/最佳实践在需要时始终仅在 DOM 中加载组件?例如。性能或资源使用?还是仅建议这样做以实现某些特定要求,例如我的情况? 目前我使用事件e.$emit(theModalId, args) 和 e.$on(theModalId, (args) => do something) 切换我的模式。当我使用您的 v-if 建议时,默认情况下我可以在组件安装上显示模态但我错过了在某些情况下我需要的 args 功能(例如编辑模态)。用 v-if 加载模态组件并触发一个事件来显示它感觉很难看,有没有更好的方法来做到这一点?我可以先设置一个变量,然后用 var 作为 prop 加载组件以避免该事件,但这感觉有点 hacky.... 只有在需要的时候才有东西总是好的,而Vue中的经验法则是这样的:如果初始化很重-使用v-show,如果相对容易-使用v-如果。这绝对是最佳实践,而不是解决方法。关于传递道具 - 这样做的好方法不是在事件中传递,而是将它们作为道具传递,例如&lt;modal v-if="isShowModal" :entity="entityToEdit" /&gt; 感谢您的回答和明确的答复!我没有得到实体部分,因为我已经需要在使用 v-if 切换组件之前定义道具。这是否意味着我需要定义一个占位符变量(并将其作为道具提供) - 当单击编辑按钮时用 entityToEdit 填充它而不是切换 if? 是的,有不同的可能方法来实现这一点 - 包括带有事件的方法(有一个侦听器包装模态并在那里传递实体),但它们最终都会做同样的事情- 显示模态并传递可编辑的内容,因为这就是它在 Vue 中的工作方式。不同的方法是将可编辑实体存储在 Vuex 中,但 props 方法对我来说看起来更清晰。

以上是关于如何使用 props 动态挂载 vue 组件的主要内容,如果未能解决你的问题,请参考以下文章

如何在Vue中动态添加类名

如何使用 Vue 2 基于 props 创建动态标签

如何在挂载期间获取嵌套子组件中的 div - Vue.js

灵光一闪!帮你使用Vue,搞定无法解决的“动态挂载”

使用 array.map() 创建组件时如何动态分配 Prop 值

灵光一闪!帮你使用Vue,搞定无法解决的“动态挂载”