Test.js 在iframe内的html页面引入

// 在iframe子页面引入该js
window.addEventListener ('message', function(event) {
    /**
     * 可以在这个地方调用HTML
     */
    console.log('调用HTML')
    if (event&&event.data){
        console.log(event.data)
        console.log('开始执行调用HTML')
        //ifream加载完成时调用vue中的load方法,将父组件的所有方法告诉ifream中的页面
        event.data.parentFunctions&&event.data.parentFunctions.forEach(key=>{
            this.__proto__[key]=function (params) {
                //调用父类
                window.parent.postMessage ({functionName:key,params:params}, '*');
            }
        })
        //vue页面传入数据如果是调用html方法 则使用此方法
        event.data.functionName&&this[event.data.functionName](event.data.params)
    }
});

child2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="Test.js"></script>
    <script>
        function lodaTable(data) {
            this.skipHtml({name:'test01',functionName:'changge',params:{personName:'张三'}})
            console.log('name---->'+data)
        }
    </script>
</head>
<body>
<button onclick="lodaTable()">打开下一页</button>
<h1>首页</h1>
</body>
</html>

404.html 页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>404</h1>
</body>
</html>

Home.vue 

<template>
  <div class="iframestyleset">
    <button @click="invokeHtmlMethod({
        name:'test01',
        url:'static/test01.html'
      })">调用html方法
    </button>
    <a href="https://www.baidu.com/">打开百度</a>
    <button @click="goBack()">回退</button>
    <iframe style="background-color: #42b983" v-for="(item,index) in cachePath " name="iframeMap" :id="item.name"
            :src="item.url" width="100%" height="200px" @load="load(item)" frameborder="0" scrolling="no"
            ref="iframeDom"></iframe>
  </div>
</template>
<script>
export default {
  data() {
    return {
      getPageUrl: 'static/child2.html',
      currentPages: [{
        name: 'test01',
        url: 'static/test01.html'
      }, {
        name: 'test02',
        url: 'static/test02.html'
      }, {
        name: 'test03',
        url: 'static/test03.html'
      }],
      cachePath: [{
        name: 'child2',
        url: 'static/child2.html'
      }]
    }
  },
  created() {
    // 绑定监听,主要是为了接收html页面发来的消息
    window.addEventListener('message', event => {
      console.log('html子页面传来的数据')
      console.log(event)
      //执行子页面想要调用的方法
      if (event && event.data) {
        event.data.functionName && this[event.data.functionName](event.data.params)
      }
    })
  },
  mounted() {
    let jz = this.cachePath.findIndex(item => item.name == 'child3')
    console.log('jz===>' + jz)
  },
  methods: {
    skip(page={name:undefined,functionName:undefined,params:undefined,type:undefined}) {
      if (page.type === 'html' || page.type == '1') {
        this.skipHtml(page)
      } else if (page.type === 'vue' || page.type == '2') {
        this.skipVue(page)
      } else {
        throw Error('page type no null (缺少type参数 vue | html | 1 | 2)')
      }
    },
    /**
     * vue 跳转
     * {name:vue名称,params:要传入的数据}
     */
    skipVue(page={name:undefined,params:undefined}) {
      // {name: "deepReadingDetail", params: {'id': data.id, 'title': data.title}}
      console.log('跳转Vue:' + page)
      this.$router.push(page)
    },
    /**
     * html 跳转
     *  {name:html名称,functionName:要调用的函数名称,params:要调用的函数要传入的数据}
     */
    skipHtml(page={name:undefined,functionName:undefined,params:undefined}) {
      console.log('跳转html:' + JSON.stringify(page))
      alert('跳转html:' + JSON.stringify(page))
      //1.首先判断这个地址是否存在
      let currentPage = this.currentPages.find(item => item.name == page.name)
      if (currentPage) {
        //2.判断是否已经加载过
        let jz = this.cachePath.findIndex(item => item.name == page.name)
        Object.assign(page, currentPage)//合并对象
        alert('page--->' + JSON.stringify(page))
        if (jz > -1) {
          //已经记载 则置顶
          alert('已经记载 则置顶'+jz)
          if (!(jz>=this.cachePath.length-1)){
            alert(5555555)
            this.cachePath.push(this.cachePath.splice(jz, 1)[0])
          }
          this.load(page)
        } else {
          alert('没有加载过 则添加')
          //没有加载过 则添加
          this.cachePath.push(page)
        }
      } else {
        if (this.cachePath[this.cachePath.length-1].name!='404'){
          this.cachePath.push({name: '404',url: 'static/404.html'})
        }
      }
    },

    invokeHtmlMethod(page) {
      let frame = document.getElementById(page.name)
      frame.contentWindow.postMessage(page, '*');
    },

    load(page) {
      this.$nextTick(() => {
        //1.获取到iframe对象
        let frame = document.getElementById(page.name)
        //2.给对象的contentWindow添加监听事件 parentFunctions(当前vue页面中的方法不要以$和_开头)
        let parentFunctions = Object.keys(this).filter(key => {
          if (!key.startsWith('$') && !key.startsWith('_') && typeof this[key] === 'function') {
            return key
          }
        })
        //3.告诉html页面 上个页面 要对他进行的操作 {parentFunctions:当前vue页面中的方法集合(必传),
        // functionName:要调用的html中的方法(可空),
        // params:要调用的html中的方法所传的参数(可空)
        // }
        //在将要进入的页面 可以直接使用this.方法名(参数)使用当前vue页面中的所有方法
        frame.contentWindow.postMessage(Object.assign({parentFunctions: parentFunctions},page), '*');
      })
    },
    goBack() {
      if (this.cachePath.length>1){
        this.cachePath.pop()
      }
    }
  }
}
</script>

Vue目录结构

 

Logo

前往低代码交流专区

更多推荐