前言

​ 本篇文章主要记录个人在公司项目开发中所遇问题,主要内容:在vue项目开发过程中需要将原有的jsp页面以及其关联的js,css原封不动的移植到vue项目中。

如果文章有歧义,请各位大佬指出,避免误导更多的人!!

正文

起因

​ 在新的vue项目开发中,用到了老项目的重点技术;重头翻新为ant-design-vue页面工作量过大!那么就有以下问题:

  1. vue项目怎么访问展示jsp页面?
  2. jsp页面中的js,css怎么引入?
  3. jsp页面初始化时所需的参数怎么获取,原有的Ajax请求怎么处理?

在vue页面使用iframe内嵌jsp/html页面(解决提出的问题1 和 2)

  1. 将原有的jsp页面(ConfigurationEditing.html),js,css等相关的资源放到vue项目的静态资源文件夹下:
    在这里插入图片描述

  2. jsp页面所有引入的js,css等都不用改变:(但注意路径的变化,具体根据自己项目进行调整)

  3. 在src文件夹创建对映的ConfigurationEditing.vue,用于内嵌原jsp/html页面。然后在vue项目中配置对映的访问路由以便展示ConfigurationEditing.vue页面内容。

  4. 在ConfigurationEditing.vue中创建iframe组件内嵌jsp/html页面:

<template>
  <div>
    <iframe
      name="iframeChild"
      id="configFrame"
      src="/jsp/ConfigurationEditing.jsp"
      width="100%"
      height="800px" 
      frameborder="0"
      scrolling="no"
      ref="iframeDom"
    ></iframe>
    <upload-material-modal ref="uploadModal" @konvaOk="konvaOk"></upload-material-modal>
  </div>
</template>

vue与iframe中的内容如何相互传值(解决提出的问题3)

一.使用postMessage(obj, …)向iframe中传递值(进行通讯)

  1. vue页面向iframe传值:
methods: {
      konvaOk () {
        var param = {
          type: 'uploadOk'
        }
        this.sendMesForIframe(param)
      },
      // 获取iframe实例, postMessage传值
      sendMesForIframe (value) {
        const mapFrame = this.$refs['iframeDom']
        const iframeWin = mapFrame.contentWindow
        iframeWin.postMessage(value, '*')
      }
},
  1. iframe中的jsp/html页面接收vue传的值:
$(function () {
    
    // 监听vue页面传递过来的值
    window.addEventListener('message', messageEvent => {
        // 判断是不是父窗口传来的值
        if (messageEvent.source !== window.parent.window.parent) return
        console.log(messageEvent.data,'vue页面所传的值')
        if (messageEvent.data.type === 'uploadOk') {
            // 判断传来值的类型后执行其他函数
            resetModalMaterialList()
        }
    })
    
})
  1. iframe中的jsp/html向vue传值:
	/**
     * 图片上传
     */
     $('#ssi-upload').click(function () {
        var labelId = 1
        var message = {
            type: 'uploadClick',
            labelId: labelId
        }
        window.parent.postMessage(message, '*') // 向vue传值
     })
  1. vue接收iframe传的值:
mounted: function () {
        var that = this
        window.addEventListener('message', function (e) {
            var message = e.data
			console.log(message, 'iframe传递过来的数据')
            if (message.type === 'uploadClick') {
                var labelId = message.labelId
                console.log(labelId)
            }
        })
    },

二.在vue页面创建vue实例挂载到window对象上,iframe内嵌的页面通过window.parent.vue实例 来获取vue页面的值。(方法2)

  1. vue页面的代码:(在vue生命周期创建时,创建vueThis实例)
<script>
  export default {
    name: 'ConfigurationEditing',
    data () {
      return {
        lang: Vue.ls.get(APP_LANGUAGE), // 请求的语言zh -CN
        reqPath: process.env.VUE_APP_API_BASE_URL_NEW, // 用于内嵌jsp页面的Ajax的路径
        regionId: 1
      }
    },
    methods: {
        showID (id) {
            console.log(id)
        }
    },
    // 计算属性
    computed: {
        ...mapState({
            userToken: (state) => state.user.token // 计算属性也可以被内嵌的jsp/html获取
        })
    },
    created () {
      window.vueThis = this // 挂载vue实例
    }
  }
 </script>
  1. 内嵌的jsp/html页面通过window.parent.vueThis 可以获取到vue中定义的变量和函数:(从vue中获取值)
$(function () {
    var lang = window.parent.vueThis.lang
    var rePath = window.parent.vueThis.rePath
    var regionId = window.parent.vueThis.regionId
    var userToken = window.parent.vueThis.userToken // 获取到的token可以用于内嵌的jsp/html页面的ajax请求头中
    window.parent.vueThis.showID(regionId) // 调用vue中函数
    
})

同样vue页面也可以通过iframe实例获取其中的值或者调用其中的函数:

// 方法
iframeOK (res) {
    var switchFrame = this.$refs['iframeDom']
    var switchIframeWin = switchFrame.contentWindow // 获取到iframe窗口实例

    switchIframeWin.StageObj.prototype.saveConfiguration(1) // 调用iframe中jsp/html页面定义的函数
},

其他问题

1.内嵌后jsp页面的Ajax请求可以正常使用!

​ 注意:ajax请求中的请求一些相关参数可以通过上面所述的方法获取,例如:请求头(例:token,lang等)、请求参数、以及请求路径。

2.vue页面内嵌jsp页面时,把jsp页面放在静态文件夹时将后缀改为.html (不能使用.jsp结尾);对jsp页面没有影响!

原因:在本地vue项目iframe内嵌jsp页面貌似没有什么问题!但是当vue项目部署到服务器因为jsp页面是存放在静态文件夹中的静态资源,在使用iframe时不行预览其中的jsp页面而是当做静态文件下载下来。

解决:iframe可以预览图片、pdf、html文件类型,所以将.jsp文件后缀改为.html后缀的文件再部署到服务器。

Logo

前往低代码交流专区

更多推荐