xboot-front icon indicating copy to clipboard operation
xboot-front copied to clipboard

keep-alive在部分页面失效

Open eggangel opened this issue 6 years ago • 5 comments

部分页面下,页面缓存失效,如 定时任务、操作日志管理、SQL监控、接口文档等

eggangel avatar Jan 23 '19 09:01 eggangel

如题,为验证是否生效,定时任务、操作日志管理等列表页修改显示条目数,页面切换后再返回该页面,会发现条目数又变为10条/页;

http://xboot.exrick.cn测试页面下,操作日志管理又可以被正常缓存

eggangel avatar Jan 24 '19 00:01 eggangel

sys/monitor/monitor组件由于页面复用,使用iframe显示的页面均无法缓存

eggangel avatar Jan 30 '19 00:01 eggangel

monitor缓存版本,可参考

<style lang="less">
    @import "./monitor.less";
</style>

<template>
    <div>
        <Row>
            <Col>
                <Card>
                    <Row>
                        <Form
                                ref="searchForm"
                                inline
                                :label-width="70"
                                class="search-form"
                                @keydown.enter.native="handleGo"
                                @submit.native.prevent
                        >
                            <Form-item label="链接地址" prop="url">
                                <Input
                                        type="text"
                                        v-model="urls[currentIndex]"
                                        placeholder="http://"
                                        clearable
                                        style="width: 350px"
                                />
                            </Form-item>
                            <Form-item style="margin-left:-50px;">
                                <Button @click="handleGo" type="primary" icon="ios-send" style="margin-right:5px">前往
                                </Button>
                                <Button @click="handleOpen" icon="md-open">新窗口中打开</Button>
                            </Form-item>
                        </Form>
                    </Row>
                    <Divider style="margin-top:-10px;margin-bottom:0;"/>
                    <Row>
                        <div id="iframe-div" style="position:relative;">
                            <Spin fix size="large" v-if="loading"></Spin>
                        </div>
                    </Row>
                </Card>
            </Col>
        </Row>
    </div>
</template>

<script>
    import axios from "axios";

    export default {
        name: "monitor",
        data() {
            return {
                loading: false,
                urls: [],
                currentIndex: 0,
                deviceHeight: 0
            };
        },
        computed: {},
        methods: {
            initUrl() {
                let url = this.$route.meta.url;
                if (url !== null && url !== undefined) {
                    let index = this.contains(this.urls, url);
                    if (index === -1) {
                        let div = document.getElementById("iframe-div");
                        this.currentIndex = this.urls.length;
                        this.urls.push(url);

                        let newIframe = "<iframe id='iframe{0}' src={1} frameborder='0' width='100%' height='{2}' scrolling='auto'></iframe>".format(this.currentIndex, this.urls[this.currentIndex], this.deviceHeight - 160 - 57);
                        let buf = document.createElement("div");
                        buf.innerHTML = newIframe;
                        div.appendChild(buf.childNodes[0]);

                        this.loadIframe();
                    } else {
                        this.currentIndex = index;
                    }
                    // 刷新显示的iframe
                    this.refreshUrls();
                }
            },
            handleGo() {
                let iframe = document.getElementById("iframe" + this.currentIndex);
                iframe.src = this.urls[this.currentIndex];
                this.loadIframe();
            },
            handleOpen() {
                window.open(this.urls[this.currentIndex]);
            },
            // 判断iframe是否加载完毕
            loadIframe() {
                let iframe = document.getElementById("iframe" + this.currentIndex);
                this.loading = true;
                let that = this;
                // 判断iframe是否加载完毕
                if (iframe.attachEvent) {
                    iframe.attachEvent("onload", function () {
                        //iframe加载完成后你需要进行的操作
                        that.loading = false;
                    });
                } else {
                    iframe.onload = function () {
                        //iframe加载完成后你需要进行的操作
                        that.loading = false;
                    };
                }
            },
            contains(arr, obj) {
                let index = arr.length;
                while (index--) {
                    if (arr[index] === obj) {
                        return index;
                    }
                }
                return -1;
            },
            refreshUrls() {
                let length = this.urls.length;
                for (let i = 0; i < length; i++) {
                    let iframe = document.getElementById("iframe" + i);
                    if (this.currentIndex === i) {
                        iframe.style.display = "block";
                    } else {
                        iframe.style.display = "none";
                    }
                }
            },
            changeHeight() {
                let length = this.urls.length;
                for (let i = 0; i < length; i++) {
                    const oIframe = document.getElementById('iframe' + i);
                    this.deviceHeight = document.documentElement.clientHeight;
                    oIframe.style.height = (Number(this.deviceHeight) - 160 - 57) + 'px'; //数字是页面布局高度差
                }
            },
            getDeviceHeight() {
                this.deviceHeight = document.documentElement.clientHeight;
            },
        },
        watch: {
            $route(to, from) {
                this.initUrl();
                this.changeHeight();
            },
            deviceHeight() {
                this.changeHeight();
            },
        },
        mounted() {
            this.initUrl();
            this.changeHeight();
            window.addEventListener("resize", this.getDeviceHeight);
        },
        beforeDestroy() {
            window.removeEventListener("resize", this.getDeviceHeight);
        }
    };
</script>

<style>
</style>

eggangel avatar Jan 30 '19 02:01 eggangel

实际测试发现iframe页面和非iframe页面间切换,iframe页面的缓存会失效,以下是解决方案:

修改Main.vue

......
// keep-alive 加上include会造成部分页面无法缓存,具体原因不明,有知道的同学请留言
<keep-alive>
    <router-view v-if="!$route.meta.iframe"></router-view>
</keep-alive>
<Monitor v-show="$route.meta.iframe" ></Monitor>

......
import Monitor from "./sys/monitor/monitor.vue";
......

修改src/router/index.js

router.beforeEach((to, from, next) => {
    if (to.meta.url !== undefined && to.meta.url !== null) {
        to.meta.iframe = true;
    } else {
        to.meta.iframe = false;
    }
......
}

eggangel avatar Feb 01 '19 09:02 eggangel