将 Vue 组件数据绑定到外部状态

Binding Vue component data to external state

我有一个 Vue 组件需要在几个地方嵌入到一个大型遗留(非 Vue)系统中。 该组件发出一些 AJAX 请求并显示基于数据库记录 ID 数组的信息,它通常在页面加载时收到。该数组由服务器直接嵌入到页面模板中,并作为 props 传递给组件,如下所示:

let config = {
  records: {{ template_code_outputting_array }},
  ...otherConfigOptions
}

let app = new Vue({
  el: '#app',
  store,
  render: h => h(ComponentName, {
    props: config
  })
})

我的问题是,在其中一个需要嵌入的屏幕上,用户可以使用搜索和添加类型 AJAX 界面动态选择数据库记录(而不是预先-在页面加载时设置),因此我需要使组件与用户的选择保持同步,以便可以根据需要重新呈现它。

我有一个可行的解决方案,但它远非理想;每当用户对他们的选择进行一些更改时,我目前直接在组件上调用一个方法,传递新的选择,以便组件可以更新自己的内部副本:

app.$children[0].recordsChanged(newSelection)

但显然这不是反应式的,而且感觉有点老套。我觉得我不应该直接对组件进行寻址,而且我正在调用的函数仅供外部使用;组件内部没有任何东西使用它。

我试过将 data 中的值绑定到全局变量(这同样不理想,但我没有太多选择)然后添加 watch 方法触发重新渲染变化。显然标量值不会起作用,因为它们是按值而不是引用,但是将它们包装在一个对象中似乎也不起作用。它们绑定良好并采用提供的初始值,但更新对象(直接改变其值或用新对象替换对象)似乎不会触发 watch 方法或任何反应性。

执行此操作是否有任何最佳实践,或者我目前的方法是否是我希望的最佳方法?

事件总线(正如 AfikDeri 在评论中所建议的那样)是一个很好的解决方案。它提供了一个简单的界面。

也可以对数据进行响应式处理,with some caveats. An Object used to initialize a data item will itself be made reactive. If the things that change your array do so in the approved ways,您应该会在 Vue 中看到更改。

let stuff = [2, 3, 5];

const v = new Vue({
  el: '#app',
  data: {
    reactiveStuff: stuff
  },
  components: {
    myComponent: {
      props: ['arr'],
      template: '<div><div v-for="item in arr">{{item}}</div></div>'
    }
  }
});

setTimeout(() => {
  stuff.push(7);
}, 1200);
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<my-component id="app" :arr="reactiveStuff">
</my-component>