【问题标题】:Vue instance inside another Vue instance另一个 Vue 实例中的 Vue 实例
【发布时间】:2018-02-15 00:21:49
【问题描述】:

我正在将 Vue 与一个名为 AEM 的 CMS 集成,它基本上就像 Vue 一样的组件基础系统工作。但是,这个 CMS 上的每个组件都不是一个 webpack 和 .vue 文件的导入,而是一个新的 Vue 实例(new Vue({…}))。因此,在我的页面上,我有很多 Veu 实例使用同一个商店 (vuex) 相互通信。

这实际上工作得很好,但是当我需要一个 CMS 组件在另一个组件中时,我有一个场景。由于这两个组件都是唯一的 vue 实例,并且父组件的“el”属性包含子组件的“el”,因此子组件不起作用。

我知道这不是这个库的预期用途,但有什么方法可以让我在两个 vue 实例上告诉或共享相同的“上下文”,甚至是这种场景的另一种方法。

谢谢, 亚历山大。

【问题讨论】:

标签: vue.js components aem


【解决方案1】:

应该只有一个 Vue 实例。

  • 我建议你在 body 标签内创建一个空的 Vue 实例
  • 所有现有的 Vue 实例都转换为组件
  • 在根 Vue 实例中注册所有组件

使用这种方法,可以将一个组件嵌套到另一个组件中

【讨论】:

  • 虽然是一种真正的反模式,但可以通过使用忽略元素Vue.config.ignoredElements = ['aem-slot'] 等功能安全地创建嵌套的 Vue 实例。这样,如果实例的模板放在 标记内,您就可以嵌套实例。再说一遍:这对 Vue 来说是一种反模式,但是如果要在能够嵌套组件的同时保留 AEM 的创作功能,那么这种方法就成为强制性的。
【解决方案2】:

你应该只使用@shrpne提到的一个 Vue实例。

如果您继续为每个组件实例化 Vue 实例,您将在调试或组件通信时遇到问题,总体而言,这会变得非常棘手,您会错过 Vue 提供的父子通信和继承。

我不了解您的 Vue 架构,但我目前正在编写在 AEM 中使用 Vue 的手册。

基本前提是使用 Vue 的 inline-template 和 vanilla-js,在构建时没有 typescript、nodeJS 构建、jsx 或其他任何东西,只有 vanilla-js,这样当你的页面加载时,甚至在你的 js 包被加载之前目前,DOM 已经存在,您只需要通过实例化一个将挂载所有组件的 Vue 实例来挂载组件。这对于 SEO 也很有用(除非您打算在 Java 中服务器端渲染 Vue 组件……这在理论上是可能的,但祝您好运!)

这是一个示例 AEM/Vue 组件:

  <simple-counter inline-template>
    <button v-bind:style="style" v-on:click="add">${properties.clicksText || 'clicks: '} {{ counter }}</button>
  </simple-counter>

JS:

注意它在 JS 中没有模板,因为它在上面内联

Vue.component('simple-counter', {
  data: function() {
    return {
      counter: 0,
      style: {
        color: 'red',
        width: '200px'
      }
    }
  },
  methods: {
    add: function() {
      this.counter = this.counter + 1;
      this.style.color = this.style.color == 'red' ? 'green' : 'red';
    }
  }
})

您可以以这种方式构建更多的 AEM 组件,然后在您的客户端库结束时,当您的所有 Vue 组件都已注册时,您可以运行:

new Vue({ el: '#app'})

当然,这假定您的页面 body 或其他一些父元素的 id 为:app

第二部分,如何在提交创作对话框后重新安装组件,你可以刷新页面。

我有一个关于如何在不刷新页面here 的情况下重新安装组件的问题 基本思想是向组件添加一个afteredit 事件,并仅在新变异的组件上运行一个新的 Vue 实例......仍在努力

【讨论】:

    【解决方案3】:

    解决方案:

    1. 将所有 new Vue(...) 替换为 Vue.component(...) Vue.extend(...) 等,以便更好地管理界面。

    2. 仅使用 ONE Vue 实例女巫是new Vue({...options})

    3. 将您的 vuex 存储分割成模块。
    4. Google 老师无所不知。

    【讨论】: