在 web 頁面開發中,經常會有這樣的需求:
在當前頁面內打開一個外部頁面。
若是僅僅是跳轉到外部頁面,對於有經驗的開發者來講,應該沒有什麼難度。但經常,須要打開的頁面僅僅是當前已有頁面的一部分,即須要嵌套到當前頁面內,每每就不太好實現了。
使用 iframe 加載外部頁面。css
html 頁面內嵌套 iframe,並將 iframe 的 src 屬性綁定爲目標外部頁面連接。html
<div id="iframe-container"> <iframe :src="iframeSrc" scrolling="auto" frameborder="0" id="iframe"></iframe> </div>
需求: 點擊電商導航內菜單,打開相應頁面,在新開頁面中,顯示頁面加載狀態,能夠回退和直接關閉新開頁面。vue
分析:git
實現:
Tips: 本例基於 vue + vue-router + vuex + vant 實現github
圖一頁面佈局:web
<div class="module-box"> <div class="module-title">電商導航</div> <van-grid :column-num="3"> <van-grid-item v-for="(item,index) in eShopNavItems" :key="index" :icon="item.iconPath" :text="item.name" @click="gotoPage(item.path)" /> </van-grid> </div>
js 部分:vue-router
<script> export default { components: {}, props: {}, data() { return { eShopNavItems: [ { name: '京東', iconPath: require('../../../assets/images/lifeServices/index/jd.png'), path: '/home/lifeServices/jd', }, <!-- 其餘菜單配置 --> ] } }, methods: { onClickLeft() { this.$router.go(-1) }, gotoPage(path) { this.$router.push(path) <!-- 存儲目標外鏈的url及要顯示的標題 --> <!-- 這部分寫在路由配置裏的meta參數下 --> this.$store.state.iframeSrc = this.$route.meta.link this.$store.state.iframeTitle = this.$route.meta.title } } } </script>
路由配置:vuex
const routes = [{ path: '/home/lifeServices/externalLink', name: 'externalLink', component: LinkHome, children: [ { path: '/home/lifeServices/jd', meta: { link: 'https://m.jd.com/', title: '京東(jd.com)' } }, ];
接下來關鍵的實現,也是最核心的點在於「LinkHome」組件的實現。佈局
LinkHome.vueui
<template> <div class="link-home"> <div class="header"> <van-nav-bar :title="$store.state.iframeTitle" left-arrow @click-left="onClickLeft" ></van-nav-bar> <van-icon name="cross" class="close" @click="closeTab" /> </div> <div id="iframe-container"> <iframe :src="$store.state.iframeSrc" scrolling="auto" frameborder="0" id="iframe"></iframe> </div> </div> </template> <script> import NProgress from 'nprogress' export default { mounted() { let iframe = document.getElementById('iframe') NProgress.start() iframe.onload = function() { NProgress.done() } }, methods: { onClickLeft() { this.$router.go(-1) NProgress.done() }, closeTab() { this.$router.replace('/home/lifeServices/index') NProgress.done() } } } </script> <!-- css樣式省略 -->
給 iframe 的 src 屬性綁定值,且爲目標外部頁面地址。便可嵌套加載外部頁面。
頁面加載狀態使用NProgress。
在 vue.js 的 mounted 生命週期內,開始加載進度條。
NProgress.start()
獲取 iframe 元素,當 iframe 頁面加載完成後,關閉進度條。
iframe.onload = function() { NProgress.done() }
當後退或者關閉當前頁面時,也應該一併關閉進度條提示。由於當頁面尚未加載完時,後退或者關閉頁面,將會致使進度條一直存在。
特別提示: 關閉頁面,即回到主頁時,應使用 this.$router.replace
而不是 this.$router.push
,這兩個一樣是跳轉到指定的 url,可是 this.$router.replace
不會向 history 裏面添加新的記錄。回到主頁,再後退,應該是回到進入主頁的上一個頁面,而不是剛纔打開的外部頁面。