【问题标题】:How to re-mount a component in VueJS?如何在 VueJS 中重新挂载组件?
【发布时间】:2018-05-07 16:12:57
【问题描述】:

我有一个作为 DOM 渲染的一部分安装的组件。应用程序的骨架是

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>title</title>
  </head>
  <body>
    <div id="app">
      <my-component></my-component>
      <button>press this button to reload the component</button>
    </div>
  </body>
</html>

&lt;my-component&gt; 是功能性的(它显示一些表单输入)和$emit 数据到父级。

有没有办法重新挂载它? 目标是让组件的内容和设置就像是第一次渲染一样(包括重置data() 元素保持其状态)。

some solutions,但他们都假设重写data(),我想避免这种情况。

我的理解是,组件实际上是在渲染过程中在正确位置注入到 dom 中的 HTML/CSS/JS 代码,所以我担心“重新安装”它的概念不存在 - 我只是想做在采用 data()-rewrite 方式之前确定。

【问题讨论】:

  • 为什么要避免重置data
  • @mklimek:我一直在寻找一种更简洁的方式来重置组件。如果我覆盖data(),我需要保留原件,或者拥有它的“主副本”(空),或其他类似的东西。我希望重新安装命令可以将其重置为其通用状态。如果没有,这不是世界末日——这对我来说是一个美学问题(和代码简单性)。
  • 数据可以用这个方便的单行代码重置(到data() 函数返回的原始值):Object.assign(this.$data, this.$options.data.call(this));

标签: vue.js vuejs2 vue-component vuejs3


【解决方案1】:

诀窍是改变密钥

当key发生变化时,vue将其视为一个新组件,所以会卸载“旧”组件,并挂载一个“新”组件。

参见示例,created() 挂钩只会运行一次,因此如果您看到值发生变化,您将看到一个全新的对象。

示例:

Vue.component('my-component', {
  template: `<div>{{ rand }}</div>`,
  data() {
    return {
      rand: ''
    }
  },
  created() {
    this.rand = Math.round(Math.random() * 1000)
  }
});

new Vue({
  el: '#app',
  data: {
    componentKey:0
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.8/vue.min.js"></script>

<div id="app">
  <my-component :key="componentKey"></my-component>
  <button @click="componentKey=!componentKey">press this button to reload the component</button>
</div>

【讨论】:

  • 谢谢 - 这太棒了。这也完全符合我的预期用途,我需要为组件提供一些 id(作为道具传递)。我在这里和那里阅读有关组件中的key,这是一个了解更多信息的机会。再次感谢!
  • 好例子。我也在努力实现你所拥有的。我在标签栏内有组件。我遇到了错误Attribute ":key" is ignored on component &lt;&gt; because the component is a fragment instance 你能帮忙吗?
  • 你能问一个单独的问题吗?
  • 这不会重新安装它。它只会重新渲染视图。
  • @Roel 嗯,mounted 和destroyed 方法在你这样做的时候运行正常,所以好像是重新mount。
【解决方案2】:

在您的模板中,您将添加 v-if 指令:

<template>
  <my-component v-if="renderComponent" />
</template>

在您的脚本中,您将添加这个使用 nextTick 的方法:

<script>
  export default {
    data() {
      return {
        renderComponent: true,
      };
    },
    methods: {
      forceRerender() {
        // Remove my-component from the DOM
        this.renderComponent = false;

        this.$nextTick(() => {
          // Add the component back in
          this.renderComponent = true;
        });
      }
    }
  };
</script>

这就是这里发生的事情:

最初renderComponent被设置为true,所以my-component被渲染 当我们调用 forceRerender 时,我们立即将 renderComponent 设置为 false 我们停止渲染 my-component 因为 v-if 指令现在评估为 false 在下一个刻度上,renderComponent 被设置回 true 现在 v-if 指令的计算结果为 true,所以我们再次开始渲染 my-component

【讨论】:

    猜你喜欢
    • 2018-02-08
    • 2018-11-18
    • 2021-06-15
    • 2022-01-13
    • 2021-09-16
    • 1970-01-01
    • 2021-06-15
    • 2019-04-10
    • 2018-03-25
    相关资源
    最近更新 更多