使用window.open打开多个子窗口,实现父子窗口之间数据通讯

最终页面效果

 需求描述:用户需要给当前科技树的节点身上绑定其他科技树的支线数据,这就需要在当前页面中能够有新的弹窗支出用户浏览科技树并选择某个节点后将数据传递出来。当科技树实现关联后就会出现一种套娃现象,节点身上还会有第三层、第四层的关联数据,这就需要能一层一层的展示出绑定的数据。

技术:一开始想用iframe实现的,但是iframe存在一个问题,当我打开第二层关联后页子窗口页面不加载了。有更换成了window.open的方式。

window.open用法

window.open常用来在新的window或新的tab页打开一个页面或文件(如图片、PDF等),它支持三个参数:

strUrl:要打开的页面或资源的url地址。
strWindowName:窗口的名字,用于后续对该窗口的引用,不是窗口的标题。
strWindowFeatures:窗口的描述参数,如尺寸、位置、是否启用工具栏等。
该方法的返回值是新打开的窗口的引用,也就是新窗口的window对象。在遵循同源策略的情况下,可以直接通过该对象访问被打开的页面;即使在跨域的情况下,也可以通过window.postMessage向其发消息。

 父窗口

打开窗口1(branchBindEdit)         查看科技树,选中节点进行关联操作

 // 打开某个科技树的详情页 支持查看 选中节点后绑定数据
openBindNode(row) {
  this.bindMindTree = row;
  let url = this.IFRAMEHOST + 'branchBindEdit?mindId=' + row.id;
  let tempwindow = window.open(url, uuid.v1(), 'height=700,width=1000,top=0,left=0,toolbar=no,menubar=no,scrollbars=no, resizable=no,location=no, status=no');
   tempwindow.location = url;
},

 在父窗口中接收子窗口1传回的数据

 mounted() {
    let _this = this;
    window.addEventListener('message', function (data) {
      //console.log("打印", _this.getBindMindTree(), data.data)
      let bindMindTreeData = _this.getBindMindTree()
      let branchNode = data.data;
      if (bindMindTreeData && branchNode) {
        _this.technologyTreeList.push({
          'branchId': branchNode.branchId,
          'branchText': branchNode.branchText,
          'mindId': bindMindTreeData.id,
          'mindName': bindMindTreeData.mindName,
        });
      }
    })
  },
  methods: {
    getBindMindTree() {
      this.treeBindingDialog = false;//关闭科技树展示列表
      if (this.bindMindTree)
        return { 'id': this.bindMindTree.id, 'mindName': this.bindMindTree.mindName }
      return null
    },
 }

补充: 由于我在接收到子窗口数据后还需要this.bindMindTree的数据进入其他操作,但是我在mouted中直接使用this.bindMindTree打印出来的是空数据,因在写了一个返回该数据的方法,在mouted中调用该方法

打开窗口2(branchBindView)     查看已关联的科技树支线数据

 // 查看已绑定的科技树
ViewBindingTree(row) {
      let url = this.IFRAMEHOST + 'branchBindView?branchNodeId=' + row.branchId + '&bindMindTreeId=' + row.mindId
      let tempwindow = window.open(url, uuid.v1(), 'height=700,width=1000,top=0,left=0,toolbar=no,menubar=no,scrollbars=no, resizable=no,location=no, status=no');
      tempwindow.location = url;
},

window.open的第二个参数,窗口名称使用的是uuid。 原因是查看数据时需要打开多层嵌套的窗口,如果名称一致的话,使用同一个窗口名称是无法继续打开新窗口的,使用uuid可以打开多层嵌套的窗口。

vue 中使用uuid

下载

npm i -S vue-uuid

局部引入

import { uuid } from 'vue-uuid';

使用

 uuid.v1()

子窗口1 branchBindEdit

用户选中节点后点击按钮,保存选中的节点数据并关闭子窗口

<template>
  <div id="editDetail" style="width:100%;height:100%" v-loading="loading" element-loading-background="rgba(0, 0, 0, 0.8)">
    <div>
      <el-button type="primary" @click="closeWindow">选 择 关 联</el-button>
    </div>
    <VueTestcaseMinderEditor :initJson="initJson" ref="minderEditor" :allowEditPriority="editMode" :allowEditLabel="editMode" :allowEditResult="editMode" :allowEditNode="editMode">
    </VueTestcaseMinderEditor>
  </div>
</template>

在vue页面中 的mouted函数中 截取url地址上的参数 

  mounted() {
    let _this = this;
    //console.log("window.location.href", _this.getParams(window.location.href))
    const paramsObj = _this.getParams(window.location.href);
    _this.mindId = paramsObj.mindId;
    _this.getDetailInfo();
  },
 methods: {
    getParams(url) {
      //我们只要问号后面的字符串
      var arr = url.split('?')
      var params = arr[1];
      //console.log(params);    //branchNodeId=1631188692729548802 & bindMindTreeId=17
      var arr1 = params.split('&');
      var params = {}
      //因为arr1里面有多个元素,都要切割,所以我们需要遍历循环。
      for (var i = 0; i < arr1.length; i++) {
        var newArr = arr1[i].split('=');
        params[newArr[0]] = newArr[1];
      }
      return params;
    },
    getDetailInfo(){
       //......获取关联科技树支线的数据
    },


    closeWindow() {
      //取到用户选中的节点数据
      let nodes = this.$refs.minderEditor.minder.getSelectedNodes();
      let data = {
        'branchId': nodes[0].data.id,
        'branchText': nodes[0].data.text,
      }
      //将数据传递给父窗口
      window.opener.postMessage(data, '*');
      //
      window.close()
    },
},

子窗口2branchBindView

<template>
  <div id="editDetail" style="width:100%;height:100%" v-loading="loading">
    <VueTestcaseMinderEditor :initJson="initJson" ref="minderEditor" :allowEditPriority="editMode" :allowEditLabel="editMode" :allowEditResult="editMode" :allowEditNode="editMode">
    </VueTestcaseMinderEditor>
  </div>
</template>

在vue页面中 的mouted函数中 截取url地址上的参数

  mounted() {
    let _this = this;
   // console.log("window.location.href", _this.getParams(window.location.href))
    const paramsObj = _this.getParams(window.location.href);
    _this.branchNodeId = paramsObj.branchNodeId;
    _this.bindMindTreeId = paramsObj.bindMindTreeId;
    _this.getDetailInfo();

  },
 methods: {
    getParams(url) {
      //我们只要问号后面的字符串
      var arr = url.split('?')
      var params = arr[1];
      //console.log(params);    //branchNodeId=1631188692729548802 & bindMindTreeId=17
      var arr1 = params.split('&');
      var params = {}
      //因为arr1里面有多个元素,都要切割,所以我们需要遍历循环。
      for (var i = 0; i < arr1.length; i++) {
        var newArr = arr1[i].split('=');
        params[newArr[0]] = newArr[1];
      }
      return params;
    },
    getDetailInfo(){
       //......获取关联科技树支线的数据
    },
},

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值