我现在正在做类似的事情,该项目最初是使用 Thymeleaf 和 jQuery 编写的,现在我们正在切换到 Vue。
你可以通过几种方式在 vue 组件和非 vue 组件之间进行通信,它们都不是“漂亮”的。
通讯
经典 JavaScript 事件
很简单
// legacy code
document.dispatchEvent(new CustomEvent('legacy-vue.something-happened', { detail: payload }))
// vue component
created () {
document.addEventListener('legacy-vue.something-happened', this.onSomethingHappened)
},
destroyed () { // don't forget to remove the listener!
document.removeEventListener('legacy-vue.something-happened', this.onSomethingHappened)
}
暴露 EventHub
与上一个类似,但您使用的是 vue 事件。 这是我的建议,因为它是 Vue 处理事件的方式,而您的目标是 Vuetify 您的应用程序。
// initialization
const hub = new Vue()
Vue.prototype.$eventHub = hub
window.$vueEventHub = hub
// legacy code
$vueEventHub.$emit('something-happened', payload)
// vue component
created () {
this.$eventHub.$on('something-happened', this.onSomethingHappened)
},
destroyed () {
this.$eventHub.$off('something-happened', this.onSomethingHappened)
}
暴露整个组件
最灵活的方式,但很难看出在哪里发生了什么。在我看来,基于事件的方法更容易(它很容易跟踪事件)。
// vue component
created () {
window.vueTableComponent = this
}
// legacy component
vueTableComponent.fetchNextPage()
vueTableComponent.registerOnPageFetchedCallback(callback);
总结
无论您选择哪种方法,我都建议您这样做:
假设您有 TableComponent。 TableComponent 几乎没有像 apiUrl 这样的 props,发出 row-clicked 事件等。最好在设计组件时根本不考虑遗留代码,然后创建它的遗留包装器,因为在某一时刻它将与 vue- 一起使用仅屏幕和混合屏幕(带有遗留组件和 vue 组件)。一个例子:
LegacyTableComponentWrapper.vue
<template>
<table-component
:api-path="apiPath"
@row-clicked="onRowClicked"
ref="table-component"
/>
</template>
export default {
data: () => ({
apiPath: null
}),
methods: {
onRowClicked (row) {
this.$eventHub.$emit('table-row-clicked', row) // notify legacy code
},
onApiPathDefined (payload) {
this.apiPath = payload
}
},
mounted () {
// legacy code might require the TableComponent to act differently
// and if you don't want the TableComponent to know whenever it's legacy or not
// you can always override one or more of it's methods.
this.$refs['table-component'] = this.overriddenImplementationOfXYZ
},
created () {
this.$eventHub.$on('define-api-path', this.onApiPathDefined)
},
destroyed () {
this.$eventHub.$off('define-api-path', this.onApiPathDefined)
}
}
一开始肯定会做更多的工作,但稍后会省去你的麻烦,因为你将处理完全在 vue 中的第一个视图,并且所有遗留的通信内容都在路上。