【问题标题】:Vue component inside legacy php/jquery project遗留 php/jquery 项目中的 Vue 组件
【发布时间】:2020-09-22 04:23:25
【问题描述】:

我有这个基于 Codeigniter 和 jQuery 的大型遗留网络应用程序。

计划是逐步淘汰 jQuery 并开始使用 Vuejs。我们正在逐步更换网站的某些部分。

我刚刚安装了 Nuxtjs,并以我喜欢的方式在遗留项目中获得了文件结构。

现在回答问题。如何从我的旧 javascript 文件之一访问 Vue 组件?

App.vue

<template>
  <div id="app">
    <HelloWorld msg="Welcome to Your Vue.js + TypeScript App" />
  </div>
</template>

<script lang="ts">
import Vue from "vue";
import HelloWorld from "./components/HelloWorld.vue";

export default Vue.extend({
  name: "App",
  components: {
    HelloWorld
  }
});
</script>

main.ts

import Vue from "vue";
import App from "./App.vue";
import store from "./store";

Vue.config.productionTip = false;

new Vue({
  store,
  render: h => h(App)
}).$mount("#app");

我想在普通的 php/html 视图中显示我的 App.vue。

【问题讨论】:

  • 您说您正在使用 Nuxt.js.. 这是因为您也打算替换应用程序的后端吗?或者您的意图只是将所有 jQuery 换成 Vue?
  • 我们不会更换后端。我们正在构建一个新的外部 API,我们将从 vue 部分调用它。所以 Vue 不会与我们的遗留后端通信。

标签: javascript jquery codeigniter vue.js nuxt.js


【解决方案1】:

我现在正在做类似的事情,该项目最初是使用 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 中的第一个视图,并且所有遗留的通信内容都在路上。

【讨论】:

  • 首先,非常感谢您的彻底回答。我可能一直不清楚,但我们不会直接与遗留后端进行通信,而是通过我们正在构建的新 API。所以我要做的只是在 php 视图中显示我的 index.vue/通过 jQuery 绑定到元素。有什么想法吗?
  • 操作。要实例化 vue,您只需要创建具有特定 id 的 div(比如说 - app),导入 vue 生成的脚本和 css,然后在您的 vue 项目的索引中以标准方式创建新的 vue 实例 - new Vue({ el: '#app', ... })。无需进一步更改。我仍然不确定我是否理解正确,这是您要求的吗?
  • 我不确定我是否完全理解。我的 Vue“项目”是在遗留项目的自己的文件夹中创建的。我要在旧文件中导入什么?现在在应用程序的 Vue 部分,我有 App.vue、main.ts 和一个 HelloWorld.vue 组件。我想在我的旧文件中显示 App.vue。我要更新原来的帖子。请在那里寻找更彻底的解释。
  • App 组件模板 (&lt;div id="app"&gt;) 中的包装 div 不应该存在。当您的 JS 包在浏览器中运行时,创建的新 Vue 实例将在当前页面中查找 ID 为“app”的元素并将其自身附加到那里。您的 App 组件将在那里呈现,替换该元素内部的任何内容。
  • 我还是不太明白。我删除了“app” div,并在我想要展示组件的文件中创建了一个带有 ID 的 div。在那个文件中我还需要做什么?因为 Vue 找不到元素。
猜你喜欢
  • 1970-01-01
  • 2022-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-02
  • 1970-01-01
  • 2012-04-06
  • 1970-01-01
相关资源
最近更新 更多