亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

在Vue中實(shí)現(xiàn)不刷新的iframe頁面的方案

 更新時間:2025年01月12日 08:18:14   作者:Luckily_BAI  
在Vue項(xiàng)目中,我們可能會遇到這樣的需求:需要在應(yīng)用中嵌入iframe頁面,并且要求在路由切換的過程中,iframe的內(nèi)容不會被刷新,本文將介紹如何解決這個問題,并給出具體的實(shí)現(xiàn)方案,需要的朋友可以參考下

引言

在Vue項(xiàng)目中,我們可能會遇到這樣的需求:需要在應(yīng)用中嵌入iframe頁面,并且要求在路由切換的過程中,iframe的內(nèi)容不會被刷新。實(shí)現(xiàn)這一需求時,Vue自帶的keep-alive并不適用,因?yàn)樗墓ぷ髟聿⒉贿m用于iframe元素。本文將介紹如何解決這個問題,并給出具體的實(shí)現(xiàn)方案。

Vue的keep-alive原理

首先,我們需要理解為什么Vuekeep-alive對于iframe不起作用。keep-alive的工作原理是把組件的VNode(虛擬DOM節(jié)點(diǎn))緩存到內(nèi)存中,在需要渲染時直接從緩存中提取,而不是重新渲染組件??墒?,iframe里的內(nèi)容并不屬于Vue的VNode的一部分,因此keep-alive無法保留iframe的狀態(tài)。當(dāng)頁面切換時,iframe會被重新加載,導(dǎo)致其內(nèi)容被刷新。

為了實(shí)現(xiàn)iframe的內(nèi)容不刷新的效果,我們需要采取一種不同的方式,避免依賴keep-alive

實(shí)現(xiàn)思路

考慮到iframe的狀態(tài)難以通過keep-alive保存,我想到了一種基于路由切換方式的解決方案??梢岳?code>v-show來切換iframe的顯示與隱藏,從而確保iframe始終在頁面中存在,而不被銷毀。具體思路如下:

  • 非iframe頁面:使用Vue的路由切換機(jī)制來切換頁面內(nèi)容。
  • iframe頁面:通過v-show來控制iframe組件的顯示與隱藏,而不讓其從DOM中刪除。這樣,當(dāng)路由切換時,iframe頁面的內(nèi)容不會被重新加載。

解決方案

我們可以將iframe頁面的渲染與Vue的路由機(jī)制結(jié)合起來,并封裝成一個通用的組件。下面是具體的實(shí)現(xiàn)步驟。

1. 配置路由

首先,我們在main.js中配置路由,使用一個iframeComponent屬性來標(biāo)識哪些頁面是包含iframe的頁面。此屬性將存儲iframe組件的引用。

import Vue from 'vue';
import App from './App.vue';
import VueRouter from 'vue-router';

// 引入需要展示的iframe組件
import F1 from './components/F1.vue';
import F2 from './components/F2.vue';

Vue.use(VueRouter);

// 配置路由
const routes = [
  {
    path: '/f1',
    name: 'f1',
    iframeComponent: F1, // 該頁面包含iframe
  },
  {
    path: '/f2',
    name: 'f2',
    iframeComponent: F2, // 該頁面包含iframe
  },
  {
    path: '/index',
    component: { template: '<div>Index Page</div>' }
  }
];
?
const router = new VueRouter({
  routes
});
?
new Vue({
  render: h => h(App),
  router
}).$mount('#app');

2. 封裝iframe-router-view組件

我們需要一個新的組件來處理iframe頁面的顯示與隱藏。這個組件會監(jiān)聽路由變化,并根據(jù)路由路徑動態(tài)決定哪些iframe頁面應(yīng)該渲染。

創(chuàng)建iframe-router-view.vue:

<template>
  <div>
    <!-- Vue的router-view -->
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
?
    <!-- 動態(tài)渲染iframe頁面 -->
    <component
      v-for="item in hasOpenComponentsArr"
      :key="item.name"
      :is="item.name"
      v-show="$route.path === item.path"
    ></component>
  </div>
</template>
?
<script>
import Vue from 'vue/dist/vue.js';
?
export default {
  data() {
    return {
      componentsArr: [] // 存儲所有含有iframe的頁面
    };
  },
  created() {
    // 獲取路由配置中的iframe頁面,并注冊組件
    const componentsArr = this.getComponentsArr();
    componentsArr.forEach((item) => {
      Vue.component(item.name, item.component);
    });
    this.componentsArr = componentsArr;
    this.isOpenIframePage(); // 檢查當(dāng)前路由是否是iframe頁面
  },
  watch: {
    $route() {
      // 路由變化時更新顯示的iframe頁面
      this.isOpenIframePage();
    }
  },
  computed: {
    // 實(shí)現(xiàn)懶加載,只渲染已打開過的iframe頁面
    hasOpenComponentsArr() {
      return this.componentsArr.filter(item => item.hasOpen);
    }
  },
  methods: {
    // 判斷當(dāng)前路由是否是iframe頁面,并設(shè)置`hasOpen`標(biāo)志
    isOpenIframePage() {
      const target = this.componentsArr.find(item => item.path === this.$route.path);
      if (target && !target.hasOpen) {
        target.hasOpen = true;
      }
    },
    // 獲取所有路由配置中含有iframeComponent的頁面
    getComponentsArr() {
      const router = this.$router;
      const routes = router.options.routes;
      const iframeArr = routes.filter(item => item.iframeComponent);
      
      return iframeArr.map((item) => {
        const name = item.name || item.path.replace('/', '');
        return {
          name: name,
          path: item.path,
          hasOpen: false, // 是否已打開過
          component: item.iframeComponent // iframe組件引用
        };
      });
    }
  }
};
</script>

3. 更新根組件

在根組件中,替換原本的router-view,使用我們封裝的iframe-router-view組件來替代。

<template>
  <div id="app">
    <div class="nav">
      <router-link class="router" to="/f1">Go to F1</router-link>
      <router-link class="router" to="/f2">Go to F2</router-link>
      <router-link class="router" to="/index">Go to Index</router-link>
    </div>

    <!-- 使用新的iframe-router-view組件 -->
    <iframe-router-view></iframe-router-view>
  </div>
</template>

<script>
import F1 from './components/F1';
import F2 from './components/F2';
import IframeRouterView from './components/iframe-router-view.vue';

export default {
  name: 'App',
  components: {
    F1,
    F2,
    IframeRouterView
  }
};
</script>

4. 進(jìn)一步優(yōu)化

  • 懶加載:通過hasOpen標(biāo)志,我們確保只有在用戶訪問過對應(yīng)的iframe頁面時,iframe組件才會被渲染。這是一個簡易的懶加載機(jī)制,可以提升性能,避免不必要的資源浪費(fèi)。
  • 動態(tài)注冊:我們通過動態(tài)生成的組件數(shù)組來注冊iframe頁面,無需每次新增iframe頁面時都手動修改根組件或main.js。
  • 在關(guān)閉tab或其他業(yè)務(wù)場景下,移除對應(yīng)的iframe,防止內(nèi)存溢出。

動態(tài)創(chuàng)建iframe的解決方案

class IframeManager {
  constructor() {
    if (IframeManager.instance) {
      return IframeManager.instance;
    }
    this.iframes = new Map();
    IframeManager.instance = this;
    return this;
  }

  /**
   * 創(chuàng)建 iframe
   * @param {string} id - 唯一標(biāo)識符 必填
   * @param {string} src - iframe 的 URL 必填
   * @param {Object} styles - 自定義樣式  可選
   */
  createIframe(id, src, styles = {}) {
    if (this.iframes.has(id)) {
      const iframe = this.iframes.get(id);
      iframe.style.display = 'block';
      return;
    }
    const iframe = document.createElement('iframe');
    iframe.id = id;
    iframe.src = src;
    iframe.frameBorder = '0';

    const defaultStyles = {
      position: 'absolute',
      top: '113px',
      right: '0',
      width: 'calc(100% - 210px)',
      height: 'calc(100% - 113px)',
      overflowY: 'auto',
      borderRadius: '10px 0 0 10px',
      zIndex: '1000',
      display: 'block',
    };

    Object.assign(iframe.style, { ...defaultStyles, ...styles });
    document.body.appendChild(iframe);
    this.iframes.set(id, iframe);
  }

  /**
   * 隱藏 iframe
   * @param {string} id - iframe 的唯一標(biāo)識符 必填
   */
  hideIframe(id) {
    const iframe = this.iframes.get(id);
    if (iframe) {
      iframe.style.display = 'none';
    }
  }

  /**
   * 銷毀 iframe
   * @param {string} id - iframe 的唯一標(biāo)識符
   */
  destroyIframe(id) {
    const iframe = this.iframes.get(id);
    if (iframe) {
      iframe.remove();
      this.iframes.delete(id);
    }
  }

  /**
   * 銷毀所有 iframe
   */
  destroyAllIframes() {
    this.iframes.forEach((iframe, id) => {
      iframe.remove();
      this.iframes.delete(id);
    });
  }
}
const iframeManager = new IframeManager();
export default iframeManager;

上述代碼中,我們采用了單例模式來確保實(shí)例唯一,可在多個頁面進(jìn)行統(tǒng)一的管理,頁面中的使用不再過多贅述,調(diào)用上述方法即可。

結(jié)語

通過以上方法,我們實(shí)現(xiàn)了一個可以在路由切換時保持iframe內(nèi)容不刷新的解決方案。我們利用Vue的v-show來控制iframe的顯示和隱藏,而非通過重新渲染整個iframe元素來避免刷新。

這種方式不僅簡化了代碼,還能確保應(yīng)用的性能與體驗(yàn)不受影響。如果你有更好的優(yōu)化方法或遇到了其他問題,歡迎與我交流討論!

以上就是在Vue中實(shí)現(xiàn)不刷新的iframe頁面的方案的詳細(xì)內(nèi)容,更多關(guān)于Vue不刷新iframe頁面的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解vue中使用transition和animation的實(shí)例代碼

    詳解vue中使用transition和animation的實(shí)例代碼

    這篇文章主要介紹了詳解vue中使用transition和animation的實(shí)例代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Vue中Table組件Select的勾選和取消勾選事件詳解

    Vue中Table組件Select的勾選和取消勾選事件詳解

    這篇文章主要為大家詳細(xì)介紹了Vue中Table組件Select的勾選和取消勾選事件詳解,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • Vue.js進(jìn)階知識點(diǎn)總結(jié)

    Vue.js進(jìn)階知識點(diǎn)總結(jié)

    給大家分享了關(guān)于Vue.js想成為高手的5個總要知識點(diǎn),需要的朋友可以學(xué)習(xí)下。
    2018-04-04
  • 大前端代碼重構(gòu)之事件攔截iOS?Flutter?Vue示例分析

    大前端代碼重構(gòu)之事件攔截iOS?Flutter?Vue示例分析

    這篇文章主要為大家介紹了大前端代碼重構(gòu)之事件攔截iOS?Flutter?Vue示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • vue3+vite+ts使用require.context問題

    vue3+vite+ts使用require.context問題

    這篇文章主要介紹了vue3+vite+ts使用require.context問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Vue3 響應(yīng)式 API 及 reactive 和 ref 的用法示例詳解

    Vue3 響應(yīng)式 API 及 reactive 和 ref&

    響應(yīng)式是一種允許以聲明式的方式去適應(yīng)變化的編程范例,這篇文章主要介紹了關(guān)于Vue3響應(yīng)式API及reactive和ref的用法,需要的朋友可以參考下
    2023-06-06
  • Vue中渲染系統(tǒng)模塊的實(shí)現(xiàn)詳解

    Vue中渲染系統(tǒng)模塊的實(shí)現(xiàn)詳解

    想要實(shí)現(xiàn)一個簡潔版的Mini-Vue框架,應(yīng)該包含三個模塊:分別是:渲染系統(tǒng)模塊、可響應(yīng)式系統(tǒng)模塊、應(yīng)用程序入庫模塊,本文主要介紹的是渲染系統(tǒng)模塊的實(shí)現(xiàn),需要的可以參考一下
    2023-07-07
  • vue?Echarts實(shí)現(xiàn)儀表盤案例

    vue?Echarts實(shí)現(xiàn)儀表盤案例

    這篇文章主要為大家詳細(xì)介紹了vue?Echarts實(shí)現(xiàn)儀表盤案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 解析Vue2 dist 目錄下各個文件的區(qū)別

    解析Vue2 dist 目錄下各個文件的區(qū)別

    本篇文章主要介紹了解析Vue2 dist 目錄下各個文件的區(qū)別,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • vue 清空input標(biāo)簽 中file的值操作

    vue 清空input標(biāo)簽 中file的值操作

    這篇文章主要介紹了vue 清空input標(biāo)簽 中file的值操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07

最新評論