如何在 vue 中嵌入 Extjs ?

问题描述

改造一个项目的前端,项目很大,现在看源码加附件有500多兆(包括svn文件),前端页面也有几百个。我尝试用vue cli建了一个基于webpack的前端项目

vue init webpack myproject

用elementui写了个架子,下图这样。

clipboard.png
现在得知项目需要支持部分升级,就是没有写完的页面可以点击菜单之后,tab中显示之前Ext(3.0版本)写的页面,大概长这样

clipboard.png

之前的前后端也没有分开开发,都是写点前端写点后台。我不知道应该怎么做,是将Ext引入前端项目还是怎么样直接调用之前用Ext写的代码,请大家提供个思路

问题出现的环境背景及自己尝试过哪些方法

  • 在前端项目中引入Ext,再重写之前加载页面的代码
    我看Ext源码中并没有遵循ES5的严格模式,一运行就报错,而且Ext需要引入ext-base.js和ext-all.js,他们之间应该有依赖关系,具体引入方法应该怎么写
  • 不知道还能怎么办...

相关代码

  • tabs组件中使用动态组件的代码

    <template>
      <el-tabs
      v-show="this.tabsData.length!=0" closable @tab-remove="removeTab"
      tab-position="top" v-model="activeName"
      style="height: 100%;width: calc(100% - 65px);float: left;">
        <el-tab-pane v-for="tabData in this.tabsData"
        :key="tabData.id"
        :name="tabData.id"
        :label="tabData.text"
        style="height: 100%">
          <!-- 使用 M+菜单ID 作为动态组件名 -->
          <component v-if="tabData.URL!='#'" :is="tabData.id"></component>
        </el-tab-pane>
      </el-tabs>
    </template>
  • 老系统加载标签页的代码

    showTab = function() {
      var tab = null;
      //如果在当前的Tab页中没有,则加载    
      if (tab == null) {
        var loadPanelMethod = hasLoaded[loadingUrl].fn;
        var newPanel = loadPanelMethod();
        var tabObject = new Ext.Panel({
          id: item.id,
          layout: 'fit',
          title: item.text,
          iconCls: 'othertab',
          items: [newPanel],
          closable: true,
          autoScroll: true
        });
        tab = mainTabPanel.add(tabObject).show();
        newPanel.doLayout();
      }
      mainTabPanel.setActiveTab(tab);
      isLoading = false;
      mainTabPanel.body.unmask();
    }

见谅

之前没接触过这种工程化的前端开发,一直是个写java的小白,前端知识还停留在ES3 那个层面,有些问题描述不清楚或者用词不当的地方。

阅读 14.2k
3 个回答
  1. 先在index.html 中引入ext
  2. 在vue模板中定义一个dom元素作为ext的容器并且动态赋个id的值

    <template>
      <div class="container">
        <div :id="data.id" class="extContainer"></div>
      </div>
    </template>
  3. 在mounted的钩子中在那个DOM元素上建一个Ext的panel,用来盛放旧页面

      mounted: function () {
        const vm = this
        // 创建Ext容器,用来盛放之前老系统写的EXT界面
        // eslint-disable-next-line
        vm.elc = new Ext.Panel({
          renderTo: document.getElementById(vm.data.id),
          layout: 'fit',
          border: false,
          // eslint-disable-next-line
          height: Ext.get(vm.data.id).getHeight() - 10
        })
        let url = vm.data.url
        // 一些特殊页面
        vm.handleSpecialPages(url)
        // 加载旧页面
        axios.post(vm.contextPath + url).then(function (res) {
          vm.parseDOM(res.data)
        }).catch(function (e) {
          vm.$notify.error({title: '旧页面DOM加载失败!', message: e.message, duration: 0})
        })
      }
  4. 好在之前的每个标签页就是一个Ext元素(定义在一个js文件里),具体思路就是用ajax获得js的内容(extELFunStr),然后 body 中 append 一个 script 标签,这样就加载了之前创建的这个元素

      // 在页面中加载返回的js
      var script = document.createElement('script')
      script.setAttribute('type', 'text/javascript')
      // 注意不要用 innerText
      script.text = extELFunStr
      var body = document.body
      body.appendChild(script)
  5. 用 vm.elc.add(旧页面的Ext元素);vm.elc.doLayout() 就可以了

总结

上面是从项目中摘下来的代码,可能看的云里雾里,总结来说就是

  • index.html中引入ext库
  • mounted钩子中新建一个ext的容器
  • 想办法拿到你之前的ext元素
  • 把拿到的元素添加到新建的容器中

思路很简单,难点就在你怎么得到之前的ext的元素,我这里好在之前的一个ext标签页是写在一个文件里的,可以用axios得到整个页面内容,新建一个script标签,将页面内容添加到dom,就可以把页面添加到ext容器里了。你可能也需要去做dom解析,看具体情况吧。

写了个demo https://github.com/earor-R/vue-ext-demo

这个有没有可能通过重定向解决问题呢,因为毕竟是两种不同的开发方式。

ext.js本身就是一个基于MVC/MVVM的库,你用vue-cli,还不如用create-react-app呢,使用vue你的改造会比较大,且需要你对vue-cli吃的比较透。我估计你考虑vue-cli是看上了它的图形化管理界面,但是使用vue-cli确实代价比较大。如果你webapck掌握还行可以自己构建一个。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题