vue3+ts跨窗口触发事件

本文讲述了如何在Vue3环境下,通过window对象的自定义方法,实现从B页面点击后刷新A页面列表数据,同时仅更新列表部分,避免全页面刷新。涉及到的技术包括事件监听、TS类型系统和组件间通信的最佳实践。
摘要由CSDN通过智能技术生成

前言:最近遇到了一个需求:在A页面点击,在新的窗口打开一个页面(B页面),然后在B页面可能会有一个按钮,点击后不仅关闭B页面,还需要刷新一下A页面中的列表数据

首先就简单的点击B页面按钮时,A页面整个刷新

//A页面
<template>
    <button @click="Btn(464)"></button>
    <ul>
        <li v-for="item in data" :key="item.id">{{item.title}}</li>
    </ul>
</template>

<script setup lang='ts'>
    import {ref} from 'vue'

    const data = ref<any>([])
    const getData = () => {  //获取数据函数
      ....
      data.value = ...
    }
    getData()

    const Btn = (id: number) => {  //跳转事件,新窗口打开
      let routeData = router.resolve({
        path: '/doc/doc_edit',
        query: {
          docId: id
        }
      })
      window.open(routeData.href, '_blank');
    }

</script>
//B页面
<template>
    <button @click="Btn"></button>
</template>

<script setup lang='ts'>

    const Btn = () => {  //跳转事件,新窗口打开
        window.opener.location.reload(); //A页面整个刷新
        self.close(); //关闭B页面 || calcelEvent()
    }

    const calcelEvent = () => {
      window.location.href="about:blank";
      window.close();
    }
</script>

但是A页面只需要刷新一下列表,而整个页面刷新是不是感觉小题大做了

于是小编就想需要有个东西,当点击B页面按钮时,能够触发A页面列表重新加载

尝试了mitt,但触发不了(小编想要么是它本身的bug,要么就是这种跨窗口的它不适用)

然后就想着说在window上动手脚

//A页面
<template>
    <button @click="Btn(464)"></button>
    <ul>
        <li v-for="item in data" :key="item.id">{{item.title}}</li>
    </ul>
</template>

<script setup lang='ts'>
    import {ref} from 'vue'

    const data = ref<any>([])
    const getData = () => {  //获取数据函数
      ....
      data.value = ...
    }
    getData()

    onMounted(() => {  // ------------新增,在window上自定义方法-------------
      (window as any).getRefresh = () => {
        getData()
      }
    })

    const Btn = (id: number) => {  //跳转事件,新窗口打开
      let routeData = router.resolve({
        path: '/doc/doc_edit',
        query: {
          docId: id
        }
      })
      window.open(routeData.href, '_blank');
    }

</script>
//B页面
<template>
    <button @click="Btn"></button>
</template>

<script setup lang='ts'>

    const Btn = () => {  //跳转事件,新窗口打开
        window.opener.getRefresh() // ------------改动,调用在window上设置的方法------------
        self.close(); //关闭B页面
    }

    //如果要检测window上是否具有getRefresh方法
    //if(window.opener.hasOwnProperty('getRefresh')) {  
       // window.opener.getRefresh()
    //} 

</script>

于是就完美结束了

题外话1:

这种在window上设置方法的方式,感觉对于跨组件(非父子组件)也是很方便的(至少目前我这样使用还没遇见有什么问题)

// vue3 + ts + setup语法糖 设置页面 A.vue
onMounted(() => {
    (Window as any).setEventOnWindow = () => {
        console.log('这是设置方法到window上')
    }
})


// vue3 + ts + setup语法糖 调用页面 B.vue
// 在调用之前需要判断window上是否具有这个方法
if(window.hasOwnProperty('setEventOnWindow')) {  
    (Window as any).setEventOnWindow()
} 


判断window上是否具有某个方法或属性,可以参考这位博主的:

判断js对象中是否存在某个方法或者属性(以window为例)_异世城的博客-CSDN博客_js判断对象是否有某个方法

题外话2:

js刷新当前页面-太平洋IT百科

<html>
    <head>
        <!-- 页面自动刷新:每隔 5 秒刷新一次页面-->
        <meta http-equiv="refresh" content="5">
    </head>
    <body></body>
</html>

题外话3:

js判断某个函数是否存在

$(function() {
	isWritecont1()
    isWritecont2()
    isWritecont3()
})

function fn1() {
	console.log('这是一个函数')
}
var fn2 = 'hhh'

// 这种方式也兼容ie
// 分别将fn1,fn2,fn3去做判断,以下console的就是js执行会分别进入的地方
function isWritecont1() {
	try {
		if(typeof(eval('fn1'))=="function") {
			console.log('fn1存在,并是个函数')
		}
	}catch(e) {}
}

function isWritecont2() {
	try {
		if(typeof(eval('fn2'))=="function") {
			
		}else {
			console.log('fn2存在,但不是个函数')
		}
	}catch(e) {}
}

function isWritecont3() {
	try {
		if(typeof(eval('fn3'))=="function") {
			
		}
	}catch(e) {console.log('不存在fn3函数')}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值