wujingjing
2024-08-30 85cb0a27c886a82b08f80d42f17a24d5b8389259
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
<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';
 
// 定义父组件传过来的值
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;
        };
    }, 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>