wujingjing
2025-03-19 a193888380872e0c9d44a27b896d26a30f39df32
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<template>
    <div class="layout-padding layout-padding-unset layout-iframe">
        <div class="layout-padding-auto layout-padding-view">
            <div class="w100" v-for="v in setIframeList" :key="v.path" v-loading="v.meta.loading" element-loading-background="white">
                <transition-group :name="name">
                    <iframe
                        :src="v.meta.isLink"
                        :key="v.path"
                        frameborder="0"
                        height="100%"
                        width="100%"
                        style="position: absolute"
                        :data-url="v.path"
                        v-if="getRoutePath === v.path"
                        @load="iframeLoad"
                        ref="iframeRef"
                    />
                </transition-group>
            </div>
        </div>
        <AmisPageOptDlg v-model="amisPageShow" :item="amisPageMapRow" @insert="amisPageInsert" @update="amisPageUpdate" />
    </div>
</template>
 
<script setup lang="ts" name="layoutIframeView">
import { computed, watch, ref, nextTick } from 'vue';
import { useRoute } from 'vue-router';
import AmisPageOptDlg from '/@/views/project/yw/lowCode/sqlAmis/optDlg/OptDlg.vue';
import emitter from '/@/utils/mitt';
 
// 定义父组件传过来的值
const props = defineProps({
    // 刷新 iframe
    refreshKey: {
        type: String,
        default: () => '',
    },
    // 过渡动画 name
    name: {
        type: String,
        default: () => 'slide-right',
    },
    // iframe 列表
    list: {
        type: Array,
        default: () => [],
    },
});
 
// 定义变量内容
const iframeRef = ref();
const route = useRoute();
 
// 处理 list 列表,当打开时,才进行加载
const setIframeList = computed(() => {
    return (<RouteItems>props.list).filter((v: RouteItem) => v.meta?.isIframeOpen);
});
// 获取 iframe 当前路由 path
const getRoutePath = computed(() => {
    return route.path;
});
// 关闭 iframe loading
const closeIframeLoading = (val: string, item: RouteItem) => {
    nextTick(() => {
        if (!iframeRef.value) return false;
        iframeRef.value.forEach((v: HTMLElement) => {
            if (v.dataset.url === val) {
                v.onload = () => {
                    if (item.meta?.isIframeOpen && item.meta.loading) item.meta.loading = false;
                };
            }
        });
    });
};
// 监听路由变化,初始化 iframe 数据,防止多个 iframe 时,切换不生效
watch(
    () => route.fullPath,
    (val) => {
        const item: any = props.list.find((v: any) => v.path === val);
        if (!item) return false;
        if (!item.meta.isIframeOpen) item.meta.isIframeOpen = true;
        closeIframeLoading(val, item);
    },
    {
        immediate: true,
    }
);
// 监听 iframe refreshKey 变化,用于 tagsview 右键菜单刷新
watch(
    () => props.refreshKey,
    () => {
        const item: any = props.list.find((v: any) => v.path === route.path);
        if (!item) return false;
        if (item.meta.isIframeOpen) item.meta.isIframeOpen = false;
        setTimeout(() => {
            item.meta.isIframeOpen = true;
            item.meta.loading = true;
            closeIframeLoading(route.fullPath, item);
        });
    },
    {
        deep: true,
    }
);
 
const iframeLoad = () => {
    setTimeout(() => {
        window.frames[0].openOptAmisPageDlg = () => {
            amisPageShow.value = true;
        };
        window.frames[0].updatePublished = (id, published) => {
            emitter.emit('supervisor.publish', {
                id,
                published,
            });
        };
    }, 0);
};
 
//#region ====================== iframe 交互 ======================
const amisPageShow = ref(false);
const amisPageMapRow = ref(null);
 
const amisPageInsert = (...params) => {
    window.frames?.[0]?.amisPageInsert?.(...params);
};
 
const amisPageUpdate = (...params) => {
    window.frames?.[0]?.amisPageUpdate?.(...params);
};
 
//#endregion
</script>