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

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.pswp.cn/diannao/85864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

板凳-------Mysql cookbook学习 (十)

5.6 改变字符串的字符集或字符排序 mysql> set s1 my string; Query OK, 0 rows affected (0.01 sec)mysql> set s2 convert(s1 using utf8); Query OK, 0 rows affected, 1 warning (0.00 sec)mysql> select charset(s1), charset(s2); -------------------------…

使用nginx配置反向代理,负载均衡

首先啥叫反向代理 咋配置呢&#xff0c;那当然是在nginx目录下改conf文件了 具体咋改呢&#xff0c;那就新增一个新的server配置&#xff0c;然后在location里新增你想代理的服务器 实际上负载均衡也就是根据反向代理的思路来的&#xff0c;如下所示 配置的话实际上也与上…

嵌入式开发之STM32学习笔记day20

STM32F103C8T6 PWR电源控制 1 PWR简介 PWR&#xff08;Power Control&#xff09;电源控制单元是STM32微控制器中一个重要的组成部分&#xff0c;它负责管理系统的电源管理功能&#xff0c;以优化功耗并提高效率。PWR负责管理STM32内部的电源供电部分&#xff0c;可以实现可编…

Spring AI(10)——STUDIO传输的MCP服务端

Spring AI MCP&#xff08;模型上下文协议&#xff09;服务器Starters提供了在 Spring Boot 应用程序中设置 MCP 服务器的自动配置。它支持将 MCP 服务器功能与 Spring Boot 的自动配置系统无缝集成。 本文主要演示支持STDIO传输的MCP服务器 仅支持STDIO传输的MCP服务器 导入j…

Java八股文——集合「Set篇」

Set集合有什么特点&#xff1f;如何实现key无重复的&#xff1f; 面试官您好&#xff0c;Set 集合是 Java 集合框架中的一个重要接口&#xff0c;它继承自 Collection 接口&#xff0c;其最显著的特点和设计目标就是存储一组不重复的元素。 一、Set集合的主要特点&#xff1a…

「数据分析 - NumPy 函数与方法全集」【数据分析全栈攻略:爬虫+处理+可视化+报告】

- 第 104 篇 - Date: 2025 - 06 - 05 Author: 郑龙浩/仟墨 NumPy 函数与方法全集 文章目录 NumPy 函数与方法全集1. 数组创建与初始化基础创建序列生成特殊数组 2. 数组操作形状操作合并与分割 3. 数学运算基础运算统计运算 4. 随机数生成基础随机分布函数 5. 文件IO文件读写 …

报表/报告组件(二)-实例与实现解释

上篇《报表/报告组件(一)-指标/属性组件设计》介绍了组件核心指标/属性设计&#xff0c;本文以实例介绍各个特性的实现和效果&#xff0c;实例是多个报告融合&#xff0c;显示所有的特性。 设计 指标/属性组件是报告/报表关键部分&#xff0c;上篇已介绍过&#xff0c;本节回顾…

Flutter嵌入式开发实战 ——从树莓派到智能家居控制面板,打造工业级交互终端

一、为何选择Flutter开发嵌入式设备&#xff1f; 1. 跨平台能力降维打击 特性传统方案Flutter方案开发效率需分别开发Android/Linux一套代码多端部署内存占用200MB (QtWeb引擎)<80MB (Release模式)热重载支持不支持支持 2. 工业级硬件支持实测 树莓派4B&#xff1a;1080…

[蓝桥杯]机器人塔

题目描述 X 星球的机器人表演拉拉队有两种服装&#xff0c;A 和 B。 他们这次表演的是搭机器人塔。 类似&#xff1a; A B B A B A A A B B B B B A B A B A B B A 队内的组塔规则是&#xff1a; A 只能站在 AA 或 BB 的肩上。 B 只能站在 AB 或 BA 的肩上。 你的…

语雀文档保存失败URI malformed

原因 原因未知&#xff0c;我用deekseek将回答的答案复制到语雀文档时出现了这个异常&#xff0c;在知识库里面一直保存失败 语雀文档保存失败URI malformed 解决方案 使用小记&#xff0c;将里面的内容转移到小记里&#xff0c;将小记移到知识库中即可

小明的Java面试奇遇之互联网保险系统架构与性能优化

一、文章标题 小明的Java面试奇遇之互联网保险系统架构与性能优化&#x1f680; 二、文章标签 Java,Spring Boot,MyBatis,Redis,Kafka,JVM,多线程,互联网保险,系统架构,性能优化 三、文章概述 本文模拟了程序员小明在应聘互联网保险系统开发岗位时&#xff0c;参与的一场深…

从零开始的嵌入式学习day33

网络编程及相关概念 UDP网络通信程序 UDP网络通信操作 一、网络编程及相关概念 1. 网络编程概念&#xff1a; 指通过计算机网络实现程序间通信的技术&#xff0c;涉及协议、套接字、数据传输等核心概念。常见的应用场景包括客户端-服务器模型、分布式系统、实时通信等。…

Kotlin 1. 搭建Kotlin开发环境

本实战概述旨在指导用户搭建Kotlin开发环境&#xff0c;并进行简单的编程实践。首先&#xff0c;用户需安装IntelliJ IDEA&#xff0c;并进行基本设置&#xff0c;如选择主题、调整字体和安装插件等。接着&#xff0c;创建Kotlin项目&#xff0c;设置项目名称、位置和JDK版本&a…

Mysql的B-树和B+树的区别总结

B 树也称 B- 树&#xff0c;全称为 多路平衡查找树&#xff0c;B 树是 B 树的一种变体。B 树和 B 树中的 B 是 Balanced&#xff08;平衡&#xff09;的意思。 目前大部分数据库系统及文件系统都采用 B-Tree 或其变种 BTree 作为索引结构。 B 树& B 树两者有何异同呢&…

COMSOL学习笔记-静电场仿真

最近在学习COMSOL&#xff0c;做了一个静电场仿真的例子&#xff0c;分享一下。 参考了下面的官方案例 计算电容 电容式位置传感器的边界元建模 三维模型 首先对静电测试仪进行三维建模。 Comsol静电场仿真 使用comsol进行静电场仿真&#xff0c;控制方程为泊松方程&#…

JavaScript 循环方法对比指南

JavaScript 循环方法对比指南 1. 标准 for 循环 语法&#xff1a; for (let i 0; i < arr.length; i) {console.log(arr[i]); }优点 ✅ 完全控制索引&#xff0c;适合需要精确控制遍历顺序或步长的场景。 ✅ 性能最优&#xff0c;在超大规模数据遍历时比高阶方法&#x…

【快餐点餐简易软件】佳易王快餐店点餐系统软件功能及操作教程

一、软件概述与核心优势 &#xff08;一&#xff09;试用版获取方式 资源下载路径&#xff1a;进入博主头像主页第一篇文章末尾&#xff0c;点击卡片按钮&#xff1b;或访问左上角博客主页&#xff0c;通过右侧按钮获取详细资料。 说明&#xff1a;下载文件为压缩包&#xff…

智慧园区数字孪生全链交付方案:降本增效30%,多案例实践驱动全周期交付

在智慧园区建设浪潮中&#xff0c;数字孪生技术正成为破解传统园区管理难题的核心引擎。通过构建与物理园区1:1映射的数字模型&#xff0c;实现数据集成、状态同步与智能决策&#xff0c;智慧园区数字孪生全链交付方案已在多个项目中验证其降本增效价值——某物流园区通过该方案…

从0开始学vue:Element Plus详解

一、核心架构解析二、技术实现指南三、高级特性实现四、性能优化方案五、生态扩展方案六、调试与测试七、版本演进路线 Element Plus 是专为 Vue 3 设计的桌面端 UI 组件库&#xff0c;基于 Vue 3 的 Composition API 重构&#xff0c;在保持与 Element UI 兼容性的同时&#x…

Ubuntu系统配置C++的boost库(含filesystem模块)的方法

本文介绍在具有sudo权限的Ubuntu操作系统中&#xff0c;配置C 的boost库的方法。 boost库是一个广受欢迎的C 库集合&#xff0c;提供了许多强大的功能扩展——例如其中的filesystem模块&#xff0c;可简化文件和目录操作&#xff0c;让开发者可以轻松处理跨平台的文件系统任务。…