基于vue3-elemenyui的页面加载及新建浏览页案例

article/2025/6/21 18:59:36

1.参考链接:

基于创建vue3链接:Vue3前端项目创建_vscode创建vue3项目-CSDN博客

基于创建elementui链接:Vue3引入ElementPlus_vue引入element-plus-CSDN博客

2.案例内容

该案例实现了基本的app.vue的路由跳转、新建浏览页参数传入以及浏览页内的iframe容器的应用。点击Previewlist内的单元格,会新建浏览页展示。

3.案例详细内容

3.1  App.vue

搭建路由容器和配置全局的样式。(一定要配置 <router-view />,如果没有,Vue Router 将无法渲染匹配的组件,主要用来装载页面)

<template><!-- 最基本的 App.vue 结构 --><div id="app"><router-view />  <!-- 这里会显示当前路由对应的组件内容 --></div>
</template><script>
export default {name: 'App'
}
</script><style>
/* 全局样式可以放在这里 */
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;color: #2c3e50;margin: 0;padding: 0;
}
</style>

3.2 router\index.js

配置路由,这里配置PreviewList为默认界面,PreviewWindow为新建浏览页的界面。

import { createRouter, createWebHistory } from 'vue-router'// 公共路由
export const constantRoutes = [{path: '/',name: 'PreviewList',component: () => import('@/views/preview/PreviewList.vue'),hidden: true},{path: '/preview/PreviewWindow',name: 'PreviewWindow',component: () => import('@/views/preview/PreviewWindow.vue'),hidden: true}
]const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL || '/'),routes: constantRoutes
})export default router

3.3 PreviewList

<template><div class="app-container"><div style="margin-bottom: 16px; display: flex; align-items: center;"><span style="margin-right: 8px;">公司名称</span><el-select v-model="searchCompany" placeholder="请选择" clearable style="width: 200px; margin-right: 8px;"><el-optionv-for="company in companyList":key="company":label="company":value="company"/></el-select><el-button type="primary" @click="handleSearch">搜索</el-button><el-button @click="handleReset" style="margin-left: 8px;">重置</el-button></div><el-table v-loading="loading" border :data="tableData" style="width: 100%" :header-cell-style="{background:'#f5f7fa',color:'#606266'}"><el-table-column prop="functionName" label="功能名称" width="120" fixed/><el-table-column prop="functionName2" label="功能名称2" width="120" fixed/><!-- 动态渲染测试列(companyList2) --><el-table-column v-for="(label, index) in companyList2" :key="index" :label="label" :width="120"><template v-slot="scope"><div class="clickable-cell2" @click="handleCellClick(scope.row.functionName, label, scope.row[`test${index + 1}`])">{{ scope.row[`test${index + 1}`] || '/' }}</div></template></el-table-column><el-table-column v-for="company in displayCompanyList" :key="company" :label="company" :prop="company"><template v-slot="scope"><div v-if="scope.row[company]" class="clickable-cell" @click="openContentWindow(scope.row.functionName, company, scope.row[company])">{{ scope.row[company] }}</div><div v-else>-</div></template></el-table-column></el-table><router-view /></div>
</template><script>
import { useRouter } from 'vue-router'
import { ElTable, ElTableColumn, ElSelect, ElOption, ElButton } from 'element-plus'export default {name: "FunctionUrlMatrix",components: {ElTable,ElTableColumn,ElSelect,ElOption,ElButton},setup() {const router = useRouter()return { router }},data() {return {loading: false,companyList: [],companyList2: ["测试1", "测试2", "测试3"],functionList: [],rawData: null,searchCompany: '',filteredData: null,displayCompanyList: []}},computed: {tableData() {const data = this.filteredData !== null ? this.filteredData : this.rawDataif (!data || !Array.isArray(data)) return []const allFunctions = new Set()data.forEach(company => {if (company.rpWebShows && Array.isArray(company.rpWebShows)) {company.rpWebShows.forEach(item => {const functionName = Object.keys(item)[0]if (functionName) allFunctions.add(functionName)})}})this.functionList = Array.from(allFunctions)const result = []this.functionList.forEach(func => {const row = { functionName: func, functionName2: `${func}2` }this.companyList2.forEach((label, index) => {const testCompanyData = data.find(item => item.companyName === label)if (testCompanyData && testCompanyData.rpWebShows) {const funcData = testCompanyData.rpWebShows.find(item => Object.keys(item)[0] === func)row[`test${index + 1}`] = funcData ? funcData[func] : null} else {row[`test${index + 1}`] = null}})this.displayCompanyList.forEach(company => {const companyData = data.find(item => item.companyName === company)if (companyData && companyData.rpWebShows) {const funcData = companyData.rpWebShows.find(item => Object.keys(item)[0] === func)row[company] = funcData ? funcData[func] : null} else {row[company] = null}})result.push(row)})return result}},created() {this.loadData()},methods: {loadData() {this.loading = truethis.rawData = [{companyName: "公司A",rpWebShows: [{ "功能1": "https://map.baidu.com/" },{ "功能2": "https://map.baidu.com/" },{ "功能3": "https://map.baidu.com/" }]},{companyName: "公司B",rpWebShows: [{ "功能1": "https://map.baidu.com/" },{ "功能3": "https://map.baidu.com/" },{ "功能4": "https://map.baidu.com/" }]},{companyName: "公司C",rpWebShows: [{ "功能2": "https://map.baidu.com/" },{ "功能3": "https://map.baidu.com/" },{ "功能5": "https://map.baidu.com/" }]},{companyName: "测试1",rpWebShows: [{ "功能1": "https://map.baidu.com/" },{ "功能2": "https://map.baidu.com/" },{ "功能5": "https://map.baidu.com/" }]}]this.companyList = this.rawData.map(item => item.companyName).filter(company => !this.companyList2.includes(company))this.displayCompanyList = [...this.companyList]this.filteredData = this.rawDatathis.loading = false},handleSearch() {if (!this.searchCompany) {this.filteredData = this.rawDatathis.displayCompanyList = [...this.companyList]return}this.filteredData = this.rawData.filter(item => item.companyName === this.searchCompany)this.displayCompanyList = [this.searchCompany]},handleReset() {this.searchCompany = ''this.filteredData = this.rawDatathis.displayCompanyList = [...this.companyList]},openContentWindow(functionName, company, url) {const routeData = this.$router.resolve({name: 'PreviewWindow',query: {company: company,functionName: functionName,url: encodeURIComponent(url)}})window.open(routeData.href, '_blank')},handleCellClick(functionName, company, url) {if (url) {this.openContentWindow(functionName, company, url)}}}
}
</script><style scoped>
.app-container {padding: 5px;
}.el-table {margin-top: 20px;min-height: 300px;
}.clickable-cell, .clickable-cell2 {color: #1890ff;cursor: pointer;text-decoration: underline;
}.clickable-cell:hover, .clickable-cell2:hover {color: #40a9ff;
}
</style>

3.4 PreviewWindow

<template><div class="preview-window"><!-- 顶部控制栏(居中标题+浅灰背景) --><div class="control-bar"><div class="title-wrapper"><span class="title-text">{{ company }} - {{ functionName }}</span></div><el-buttontype="primary"size="small"@click="toggleFullscreen"class="fullscreen-btn">{{ isFullscreen ? '退出全屏' : '全屏显示' }}</el-button></div><!-- 地图容器 --><div class="map-viewport"><iframeref="mapIframe":src="processedUrl"class="baidu-iframe"sandbox="allow-same-origin allow-scripts allow-popups allow-forms"@load="handleIframeLoad"></iframe></div></div>
</template><script>
import { useRoute } from 'vue-router'
import { ElButton } from 'element-plus'export default {name: 'PreviewWindow',components: { ElButton },setup() {const route = useRoute()return { route }},data() {return {company: '',functionName: '',url: '',isFullscreen: false,loading: true}},computed: {decodedUrl() {try {return decodeURIComponent(this.url)} catch {return ''}},processedUrl() {if (!this.decodedUrl) return ''let url = this.decodedUrlif (url.includes('map.baidu.com')) {const separator = url.includes('?') ? '&' : '?'url += `${separator}tn=B_NORMAL_MAP&nn=0&width=${window.innerWidth}`}return url}},mounted() {this.initParams()window.addEventListener('resize', this.handleResize)},beforeUnmount() {window.removeEventListener('resize', this.handleResize)},methods: {initParams() {const { company, functionName, url } = this.route.querythis.company = company || '未指定公司'this.functionName = functionName || '未指定功能'this.url = url || ''},toggleFullscreen() {if (!this.isFullscreen) {this.$refs.mapIframe.requestFullscreen().then(() => this.isFullscreen = true).catch(err => console.error('全屏失败:', err))} else {document.exitFullscreen()}},handleResize() {this.$refs.mapIframe.style.width = `${window.innerWidth}px`this.isFullscreen = !!document.fullscreenElement},handleIframeLoad() {this.loading = falsethis.injectIframeStyles()},injectIframeStyles() {try {const iframeDoc = this.$refs.mapIframe.contentDocumentif (iframeDoc) {const style = iframeDoc.createElement('style')style.innerHTML = `body, #wrapper, #container { margin: 0 !important; padding: 0 !important; left: 0 !important;width: 100% !important;}`iframeDoc.head.appendChild(style)}} catch (e) {console.warn('iframe样式注入失败:', e)}}}
}
</script><style>
/* 全局样式(仅限当前组件) */
.preview-window {position: fixed;top: 0;left: 0;width: 100vw !important;height: 100vh;min-width: 1280px;margin: 0 !important;padding: 0 !important;overflow: hidden;font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
}/* 控制栏样式 - 浅灰背景+居中标题 */
.control-bar {position: relative;z-index: 100;height: 48px;background: #f5f7fa; /* Element Plus浅灰底色 */box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);display: flex;align-items: center;padding: 0 20px;
}/* 标题居中容器 */
.title-wrapper {position: absolute;left: 50%;transform: translateX(-50%);
}/* 标题文字样式 */
.title-text {font-size: 16px;font-weight: 500;color: #606266; /* 中灰色文字 */white-space: nowrap;letter-spacing: 0.5px;
}/* 全屏按钮右对齐 */
.fullscreen-btn {margin-left: auto;background-color: #409eff;border-color: #409eff;
}/* 地图容器 */
.map-viewport {position: absolute;top: 48px; /* 控制栏高度 */left: 0;right: 0;bottom: 0;overflow: hidden;background: #e4e7ed; /* 加载时的背景色 */
}/* iframe样式 */
.baidu-iframe {position: absolute;top: 0;left: 0;width: 100vw !important;height: 100%;border: none;margin: 0 !important;padding: 0 !important;background: white;
}
</style><style scoped>
/* 组件私有样式(无特殊需要可删除) */
</style>

4.效果如下


http://www.hkcw.cn/article/BnWnUTBQbv.shtml

相关文章

详解|证券、基金、期货:银证转账系统

Hi,围炉喝茶聊产品的新老朋友好!在话题未开始之前,先看组见证历史数据:2024年国庆节前,沪深两市成交额连续多日突破万亿。今日开盘后仅20分钟,沪深两市成交额突破1万亿元,刷新此前9月30日创下的历史最快万亿纪录。大量资金需要从银行存管账户转入证券存管账户。银行端和…

香港警方回应恒生银行抢劫案 嫌疑人暂未落网

香港一家恒生银行日前发生持刀抢劫案,持续引发关注。6月2日17时许,一名男子独自进入香港恒生银行沙田第一城分行,坐下约15分钟后突然拿出一把刀,威胁一名女性银行职员,并劫走约30余万港元及少量外币后逃离现场。案件导致一名银行职员颈部受轻伤,送往医院治疗后已出院,其…

政策朝令夕改 美国正在失去方向 关税政策摇摆不定

5月30日,美国总统特朗普宣布将进口钢铝关税上调至50%。短短几天内,美国关税政策再度急转弯,三项法院裁决让白宫主导的关税博弈更加复杂。美国国际贸易法院叫停大多数关税措施后,联邦巡回上诉法院暂时搁置“叫停令”。随后,一家联邦法院裁定总统无权利用“紧急权力”加征关…

雷军发文疑似回应余承东 诋毁即仰望

雷军发文疑似回应余承东 诋毁即仰望。6月1日,小米集团董事长雷军在其社交账号上发文称,公司正全力准备小米yu7的大规模量产,预计7月份开始。他还引用了莫言的一句名言:“诋毁,本身就是一种仰望。”5月31日下午,华为常务董事、终端BG董事长余承东在未来汽车先行者大会上表…

【Linux系列】Gunicorn 进程架构解析:主进程与工作进程

博客目录 引言一、Gunicorn 的基本架构概述二、主进程&#xff08;Master Process&#xff09;的职责分析三、工作进程&#xff08;Worker Process&#xff09;的功能剖析四、主进程与工作进程的交互机制五、多进程架构的优势与挑战六、实际运维中的常见场景分析七、进阶主题&a…

全国范围入户调查已开始 国家统计局发布跟访计划

国家统计局日前发布《致人口固定样本跟访调查对象的一封信》,决定于2025年在全国范围内开展两次人口固定样本跟访调查。这两次调查的标准时点分别是6月1日零时和11月1日零时。调查员将在6月1日至6月25日以及11月16日至12月5日期间入户开展调查工作。责任编辑:zhangxiaohua

女子连吃四天粽子视力骤降 糖尿病患者需谨慎饮食

女子连吃四天粽子视力骤降 糖尿病患者需谨慎饮食!赵女士今年60岁,在端午节期间,她从常去的两家棋牌室和社区活动中领到了不少粽子、咸鸭蛋和绿豆糕。为了防止食物变质,她决定尽快吃完这些食品。然而,在连续吃了四天粽子后,赵女士突然发现自己的左眼变得模糊不清,这让她非…

一文读懂韩国总统选举 五人角逐花落谁家

韩国第21届总统选举于当地时间6月3日上午6时开始正式投票。此次选举在前总统尹锡悦被弹劾后举行,受到各界高度关注。最终有5名候选人参加角逐,分别是共同民主党候选人李在明、国民力量党候选人金文洙、改革新党候选人李俊锡、民主劳动党候选人权英国和无党派候选人宋镇镐。其…

【Hot 100】70. 爬楼梯

目录 引言爬楼梯我的解题代码优化 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;【Hot 100】70. 爬楼梯❣️ 寄语&#xff1a;书到用时方恨少&#xff0c;事非经过不知难&#xff01; 引言 爬楼梯 &…

金饰克价涨至1024元 金饰克价一夜涨20元

6月2日,国际金价大幅走高,现货黄金涨2.8%,报3380.81美元/盎司;COMEX黄金期货涨2.74%,报3406.40美元/盎司。6月3日,国内金饰价格跟涨。周生生足金饰品标价1024元/克,较前一日1004元/克的价格上涨20元/克,2天上涨26元。责任编辑:zx0002

“苏超”缘何盛产热梗 地域文化与经济活力碰撞

江苏省城市足球联赛首次举办,13个设区市各组一支队伍参与角逐。经过三轮比赛后,南通队暂列第一。比赛不仅展现了真实的竞技精神,还激发了大量网络段子和梗文化。无锡队在客场挑战泰州队失利,有人戏称是因为无锡人吃不惯不放糖的汤面导致低血糖。而泰州队的胜利则被归因于主…

一次炸毁俄41架军机?乌如何做到的 特别行动揭秘

乌克兰安全局内部人士透露,代号“蛛网”的特别行动历时18个月的策划和实施,成功摧毁了41架俄军战略轰炸机。此次行动由泽连斯基亲自协调,安全局局长马柳克率队直接实施。知情人士表示,该行动在后勤保障方面极具挑战性。首先通过秘密渠道向俄境内输送FPV无人机,然后转运移动…

2025年人口固定样本跟访调查启动 数据支持人口高质量发展

2025年人口固定样本跟访调查于6月1日正式启动,旨在为加强人口统计和动态监测预警、更好地服务人口高质量发展提供数据支持。今年的调查将在6月1日与11月1日各进行一次,基于第七次全国人口普查结果,共抽取了30万人作为样本,其中6月份调查20万人,11月份调查剩余10万人。调查…

国内油价五连降或迎破灭!车主期待落空

国内油价五连降或迎破灭!车主期待落空。在生活的舞台上,油价的每一次波动都吸引着无数人的目光,尤其是广大车主。过去一段时间里,国内油价经历了连续四个月的下调,92号汽油价格重回“6元时代”,降至近三年以来的新低。按照国六阶段成品油标准品89号汽油价格计算,自2月以…

男子无意发现媳妇袜子收藏柜:她带娃顾家很辛苦

5月31日,辽宁。男子无意发现媳妇的袜子收藏柜,看到满柜的袜子无语笑了,平时别碰驱虫药啥的了,你媳妇可能是蜈蚣允悲。网友:知足吧,你媳妇屯袜子,我媳妇屯鞋子。责任编辑:zx0002

18岁女孩打美容针后全身过敏出红斑住进ICU

6月2日河南新乡,18岁花季少女打水光针,全身过敏出红斑,女儿在医院ICU抢救,妈妈无奈求助,“老板联系不上,想知道打的是什么药!”小莉跟着杨女士前往女儿当时打针的店面,发现门头已经被拆,处于一个未营业的状态。通过民警的帮助,美容店老板出面解释。责任编辑:zx0002

男子开收割机冲进起火麦田抢收 00后勇担责任

男子开收割机冲进起火麦田抢收 00后勇担责任!当20多亩麦田被大火包围时,湖北天门一位00后收割机司机小王毫不犹豫地驾驶收割机冲进火海,在浓烟滚滚中抢收小麦。这一幕比任何超级英雄电影都要震撼人心,展现了新时代年轻人的责任担当。那天下午,湖北天门某村庄里发生了一件让…

Golang——4、数组、切片和map

数组、切片和map 1、数组1.1、数组定义1.2、数组的初始化1.3、数组的遍历1.4、数组是值类型1.5、多维数组 2、切片2.1、切片的定义2.2、关于nil2.3、切片的遍历2.4、基于数组定义切片2.5、基于切片定义切片2.6、关于切片的长度和容量2.7、切片的本质2.8、使用make函数构造切片2…

tmux+minicom工具使用

tmuxminicom工具使用 tmux使用tmux minicom1. 建立会话2. 会话内执行minicom命令3. Ctrl b d 分离会话4. 查看存在的会话5 .重新进入会话6. 即使SSH断开连接 minicom仍以后台运行7. 进入会话翻看历史数据信息内容 Tmux 使用教程 tmux使用 操作流程 新建会话 tmux n…

油价又要涨 加一箱油或将多花近3元 年内第十一次调价

今晚成品油价将迎来年内的第十一次调整。受地缘局势利好支撑,国际油价在本轮周期内有所上涨。隆众资讯预计,每吨汽、柴油价格将分别上调65元和60元,折合每升92号汽油、95号汽油和0号柴油均将上调0.05元。因此,全国大多数地区的92号汽油零售价将升至7.1-7.2元/升。对于油箱容…