将 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>
我有一个 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>