【问题标题】:Multiple Vue Instances on same page using same codebase同一页面上的多个 Vue 实例使用相同的代码库
【发布时间】:2019-08-29 17:25:09
【问题描述】:

我正在努力将 Vue.js 的功能引入 WordPress 生态系统,我的第一个项目是在页面上进行搜索和过滤。

因为主网站最初是由 WordPress 使用 PHP/HTML 呈现的,所以我在附加到我使用 WordPress 输出的 HTML 元素的页面上初始化了 Vue。这一切都很好,但现在我试图通过拥有相同代码库的多个实例(可以一起工作)更进一步

以这个示例截图为例(假设这是一个 WordPress 网站):

由于整个输出不是在 Vue.js 中完成的,我必须从 WordPress 端输出多个 HTML DIV 元素,并在它们上初始化 Vue。

因为表单/字段将根据用户配置/设置动态生成,所以两个实例都将使用相同的代码库......但我需要以某种方式使其能够协同工作,也就是说,在任何实例中选择或更改值时更新页面上的结果。

这里的想法是在我的主 JS 文件中使用 vanilla javascript 来检测页面上存在的所有特定 HTML 元素(甚至可能为数据对象中的每个元素定义一个 slug),然后执行一个 foreach 循环来然后在每个实例上初始化一个new Vue()

我的第一个想法是使用 Vuex 存储,将单个存储附加到所有实例,存储任何选定的值,并在其中任何一个更改时触发调度以更新列表。

以前有人做过类似的事情吗?这样做有什么我应该厌倦的吗?或者有人对如何做到这一点有更好的建议吗?

认为我最好还是在这里提问,而不是苦苦学习,然后发现这可能是不可能的,或者这样做会有问题。

非常感谢任何建议、cmets、批评或想法

更新 有一个建议是将 Vue 实例绑定到主体,删除 render 函数,然后在需要的地方输出组件 HTML 元素(而不是输出 div 然后附加到它)。打算对此进行测试,但对围绕此的想法感到好奇?

【问题讨论】:

  • 事件总线是这里要看的东西。有了它,您可以让多个 Vue 实例(及其内部组件)相互通信。 VueX 也可以完成这项工作,但由于这不是 SPA,因此许多人会认为它过大。

标签: wordpress vue.js vuex


【解决方案1】:

对于遇到这种情况的任何人,我最终只是像这样初始化 Vue 实例:

const sections = document.getElementsByClassName( "my-wrapper" )

for ( var i = 0; i < sections.length; i ++ ) {
    new Vue( {
         el: '#' + sections[ i ].id,
         store
     })
}

基本上在页面上找到的每个输出上初始化新的 Vue 实例,将共享存储传递给每个输出。

【讨论】:

  • 这对您的效果如何? (假设您的项目向前推进)
  • @robert 在今天仍然使用它,效果很好,安装了数千次,我没有发现真正的“主要”问题
  • 谢谢。很高兴听到!我在 Vue3+ 工作中离开了 Vuex,所以我正在考虑实例之间的消息(比如这里的 mkuehn:forum.vuejs.org/t/…
【解决方案2】:

我还没有自己设置多个 Vue 实例,但我在几个地方读到 Vue 旨在支持这个用例。例如,请参见此处:Vue: is multiple Vue apps for a single website okay?

Vuex 非常适合包含多个组件的大型 SPA,而您的建议本质上是相同的,而所有组件之间没有共享根实例。这就是 Vuex 商店非常有用的地方,它使页面上的每个 Vue 组件与应用数据的单一“真实来源”保持同步。

我不确定我是否明白你的问题:

我的第一个想法是使用 Vuex 存储,将单个存储附加到所有实例,存储任何选定的值,并在列表发生任何变化时触发调度以更新列表。

当数据在 Vuex 存储中更新时,如果你正确设置了 Vuex,对 DOM 的更新将自动“反应地”发生。除了修改商店的数据外,没有其他操作可做。

关于您的更新,也许它会起作用,但对我来说这似乎不是一个好主意。这听起来与 Vue 通常使用的方式背道而驰,我不记得文档中有任何部分提到了这种设置。

就像我说的,我对您提出的设计没有直接经验,所以我可能遗漏了一些东西。我想我还是会分享。

【讨论】:

    【解决方案3】:

    要执行更多实例 vue,您必须将以下代码附加到 vue 的元素(注意元素 el )分开:

    <div id="app" class="container">
            <my-component 
            v-for="(item,index) in array_2_element" 
            v-bind:item="item"
            v-bind:index="index"
            v-bind:key="item.name"
            > test componente <br> <my-component>
          </div>
          <hr><br>
      </div>
    </div>
    
      <div id="todo-list-example">
        <form v-on:submit.prevent="addNewTodo">
          <label for="new-todo"> add a todo </label>
          <input type="text" 
          v-model="newTodoText"
          id="new-todo"
          placeholder="E.g. Feed to cat "
          >
          <button type="button" class="btn btn-primary"> add</button>
        </form>
        <ul>
          <li
          is="todo-item"
          v-for="(todo,index ) in todos "
          v-bind:key="todo.id"
          v-bind:title="todo.title"
          v-on:remove="todos.splice(index,1)"
          ></li>
        </ul>
      </div>
    
    <script> 
        var vm2= new Vue({
        el: '#todo-list-example',
        // do somethings 
    });
    
    var vm = new Vue({
        el: '#app',
        // do somethings 
    })
    </script>
    

    【讨论】:

      猜你喜欢
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多