前言:最近遇到了一个需求:在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:
<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函数')}
}