让Erupt框架支持.vue文件做自定义页面模版

Erupt是什么?

Erupt 是一个低代码 全栈类 框架,它使用 Java 注解 动态生成页面以及增、删、改、查、权限控制等后台功能。

零前端代码、零 CURD、自动建表,仅需 一个类文件 + 简洁的注解配置,快速开发企业级 Admin 管理后台。

提供企业级中后台管理系统的全栈解决方案,大幅压缩研发周期,专注核心业务。

官网:https://www.erupt.xyz

官方文档:https://www.yuque.com/erupts/erupt

在Erupt框架中如果需要自定义页面时,我们就需要自己写一下html的页面内容和逻辑代码,习惯了写vue的小伙伴们在写Html的页面是不是感觉有点烫手了,那下面我们就来让Erupt支持使用.vue的文件方式自定义页面内容以及业务逻辑,项目中用的 vue3-sfc-loader 这个js依赖实现vue模版的加载渲染的。

一、搭建初始化Erupt的基础项目

我们直接参考Erupt的官方文档创建一个简单的SpringBoot项目,我这里是使用了Gradle的方法去管理依赖的,和使用Maven管理是一样的,贴上我的项目整体结构如下:

项目使用到的依赖:

二、下载需要的js依赖

我在项目中没有使用Erupt中提供个UI组件,我是自己去下载的比较新的ui组件,因为我觉得Erupt提供的UI组件的版本有点低,所以我就自己去下载了一些新版的ui组件及vue3

  • Vue3    v3.5.8    文档:https://cn.vuejs.org
  • Element-plus  v2.8.3    文档:https://element-plus.org/zh-CN
  • Less   v4   文档:https://less.bootcss.com
  • Unocss  v0.62.4   文档:https://unocss.jiangruyi.com
  • Vue3-sfc-loader   v0.9.5  文档:https://gitcode.com/gh_mirrors/vu/vue3-sfc-loader

以上就是我项目中使用到的js依赖了,我这边使用的是vue3的所以对应的vue-sfc-loader 就是vue3-sfc-loader ,如果你用的是vue2 就选择vue2-sfc-loader。

ui组件我这边选的是element-plus,当然也可以使用其他的UI组件,使用的方式都是差不多的。

三、创建自定义页面

因为我这边使用的模版解析的引擎是 freemarker, 所以我的页面模版的文件是以 .ftl 结尾的,它就是一个freemarker的模版文件。模版的文件需要放在项目的 resource/tpl 文件夹下,这个是Erupt 默认要求这么放的,不然做映射是访问不到的。

1. 常规写法

demo.ftl 是常规的写法,没有使用vue3-sfc-loader,具体内容如下

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><meta content="width=device-width, initial-scale=1.0, user-scalable=no" name="viewport"/><title>demo</title><link href="${base}/components/element-plus/css/index.css" rel="stylesheet"><link href="${base}/css/loading.css" rel="stylesheet">
</head>
<body>
<!-- loading  start -->
<div id="loader"><div class="rotate-loading"></div><b> 页面数据加载中 。。。</b>
</div>
<!-- loading end -->
<div id="app" un-cloak><div class="p3 text-2xl text-center">{{message}} &nbsp;&nbsp;---->>&nbsp;&nbsp; {{count}}</div><div class="p3"><el-card><template #header>element-plus 展示</template><div class="mb-4"><el-button>Default</el-button><el-button type="primary">Primary</el-button><el-button type="success">Success</el-button><el-button type="info">Info</el-button><el-button type="warning">Warning</el-button><el-button type="danger">Danger</el-button></div><div class="p3"><el-button circle><el-icon><Search/></el-icon></el-button><el-button type="primary" circle><el-icon><Edit/></el-icon></el-button><el-button type="success" circle><el-icon><Check/></el-icon></el-button><el-button type="info" circle><el-icon><Message/></el-icon></el-button><el-button type="warning" circle><el-icon><Star/></el-icon></el-button><el-button type="danger"><el-icon class="mr1"><Delete/></el-icon>删除</el-button></div></el-card></div>
</div>
</body><#-- freemarker 服务端变量获取 -->
<script type="application/javascript">var base = "${base}";var user = "${user}";console.log(base);console.log(user);function onloadRun() {// loading 隐藏window.onload = function() {// 页面加载后执行的代码let elementId = document.getElementById("loader");if (elementId) {elementId.style.display = "none";}};}
</script><#-- unocss 原子样式 https://unocss.jiangruyi.com -->
<script src="${base}/components/unocss/runtime.js"></script><#-- vue3 https://cn.vuejs.org -->
<script src="${base}/components/vue3/index.js"></script><#-- element-plus https://element-plus.org/zh-CN -->
<script src="${base}/components/element-plus/index.js"></script><#-- element-plus 图标 -->
<script src="${base}/components/element-plus/icons.js"></script><#-- element-plus 国际化修改为中文 -->
<script src="${base}/components/element-plus/zh_cn.js"></script><#-- 使用vue3 模板语法加载页面样例 -->
<script type="module">const {createApp, ref, reactive} = Vue;onloadRun();const app = createApp({setup() {const count = ref(1);const message = reactive("测试");return {message,count};}})// 引入ElementPlus组件app.use(ElementPlus, {locale: ElementPlusLocaleZhCn});// 引入ElementPlus图标for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component);}app.mount("#app")
</script>
</html>

2. vue模版加载的写法 

vue3-sfc-loader-demo.ftl 是使用了vue3-sfc-loader去加载一个.vue模板文件的写法,具体的使用方法在官方文档里面都是有的,有兴趣的可以去看看,官方有很多的例子可以参考的很详细,下面是我自己写的,页面的具体内容:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><meta content="width=device-width, initial-scale=1.0, user-scalable=no" name="viewport"/><title>vue3-sfc-loader-demo</title><link href="${base}/components/element-plus/css/index.css" rel="stylesheet"><link href="${base}/css/loading.css" rel="stylesheet">
</head>
<body>
<!-- loading  start -->
<div id="loader"><div class="rotate-loading"></div><b> 页面数据加载中 。。。</b>
</div>
<!-- loading end --><div id="app" un-cloak><vue-component></vue-component>
</div>
</body><#-- freemarker 服务端变量获取 -->
<script type="application/javascript">var base = "${base}";var user = "${user}";console.log(base);console.log(user);function onloadRun() {// loading 隐藏window.onload = function () {// 页面加载后执行的代码let elementId = document.getElementById("loader");if (elementId) {elementId.style.display = "none";}};}
</script><#-- unocss 原子样式 https://unocss.jiangruyi.com -->
<script src="${base}/components/unocss/runtime.js"></script><#-- vue3 https://cn.vuejs.org -->
<script src="${base}/components/vue3/index.js"></script><#-- 加载vue3-sfc-loader https://gitcode.com/gh_mirrors/vu/vue3-sfc-loader -->
<script src="${base}/components/vue3-sfc-loader/index.js"></script><#-- less 依赖 https://less.bootcss.com -->
<script src="${base}/components/less/index-v4.js"></script><#-- element-plus https://element-plus.org/zh-CN -->
<script src="${base}/components/element-plus/index.js"></script><#-- element-plus 图标 -->
<script src="${base}/components/element-plus/icons.js"></script><#-- element-plus 国际化修改为中文 -->
<script src="${base}/components/element-plus/zh_cn.js"></script><#-- 使用 vue3-sfc-loader 加载页面样例 -->
<script type="module">const {createApp, defineAsyncComponent} = Vue;const {loadModule} = window['vue3-sfc-loader'];onloadRun();// 必要的参数:// vue 用来加载vue的模块,在vue模版中使用如: import { computed, onDeactivated, onMounted, ref } from "vue";// element-plus 用来加载element-plus的模块  在vue模版中使用如:import { button } from "element-plus";// 自定义的:// less 用来加载less的样式解析模块(模版使用了less就需要给定此参数)在vue模版中使用如:<style scoped lang="less"></style>const options = {moduleCache: {vue: Vue,"element-plus": ElementPlus,less: less},async getFile(url) {return await fetch(url).then(res => {if (!res.ok) throw Object.assign(new Error(res.statusText + " " + url), {res});return {getContentData: asBinary => asBinary ? res.arrayBuffer() : res.text()};});},addStyle(textContent) {const style = Object.assign(document.createElement("style"), {textContent});const ref = document.head.getElementsByTagName("style")[0] || null;document.head.insertBefore(style, ref);}};const tmpPath = top.location.pathname + "templates/myComponent.vue"const app = createApp({components: {'my-component': defineAsyncComponent(() => loadModule(tmpPath, options))},template: '<my-component></my-component>'});// 引入ElementPlus组件app.use(ElementPlus, {locale: ElementPlusLocaleZhCn});// 引入ElementPlus图标for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component);}app.mount("#app")
</script>
</html>

四、映射页面地址

@TplAction(value = "demo", path = "/tpl/demo/demo.ftl")// value 是访问的值,可以在菜单的配置的值
// path 是页面的路径

五、创建访问菜单

1. 普通自定义页面

2. vue模版自定义页面

六、访问页面

七、扩展点

使用一个freemarker模版文件就可以加载所有指定名字的vue模版文件了,具体的操作案例如下:

1. 创建一个freemarker模版文件

内容:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><meta content="width=device-width, initial-scale=1.0, user-scalable=no" name="viewport"/><title>公共页面模板</title><link href="${base}/components/element-plus/css/index.css" rel="stylesheet"><link href="${base}/css/loading.css" rel="stylesheet">
</head>
<body>
<!-- loading  start -->
<div id="loader"><div class="rotate-loading"></div><b> 页面数据加载中 。。。</b>
</div>
<!-- loading end --><div id="app" un-cloak><vue-component></vue-component>
</div>
</body><#-- freemarker 服务端变量获取 -->
<script type="application/javascript">// 获取指定的vue模板名称var vue_tmp_name = "${vue_tmp_name}";function onloadRun() {// loading 隐藏window.onload = function () {// 页面加载后执行的代码let elementId = document.getElementById("loader");if (elementId) {elementId.style.display = "none";}};}
</script><#-- unocss 原子样式 https://unocss.jiangruyi.com -->
<script src="${base}/components/unocss/runtime.js"></script><#-- vue3 https://cn.vuejs.org -->
<script src="${base}/components/vue3/index.js"></script><#-- 加载vue3-sfc-loader https://gitcode.com/gh_mirrors/vu/vue3-sfc-loader -->
<script src="${base}/components/vue3-sfc-loader/index.js"></script><#-- less 依赖 https://less.bootcss.com -->
<script src="${base}/components/less/index-v4.js"></script><#-- element-plus https://element-plus.org/zh-CN -->
<script src="${base}/components/element-plus/index.js"></script><#-- element-plus 图标 -->
<script src="${base}/components/element-plus/icons.js"></script><#-- element-plus 国际化修改为中文 -->
<script src="${base}/components/element-plus/zh_cn.js"></script><#-- 使用 vue3-sfc-loader 加载页面样例 -->
<script type="module">const {createApp, defineAsyncComponent} = Vue;const {loadModule} = window['vue3-sfc-loader'];onloadRun();// 必要的参数:// vue 用来加载vue的模块,在vue模版中使用如: import { computed, onDeactivated, onMounted, ref } from "vue";// element-plus 用来加载element-plus的模块  在vue模版中使用如:import { button } from "element-plus";// 自定义的:// less 用来加载less的样式解析模块(模版使用了less就需要给定此参数)在vue模版中使用如:<style scoped lang="less"></style>const options = {moduleCache: {vue: Vue,"element-plus": ElementPlus,less: less},async getFile(url) {return await fetch(url).then(res => {if (!res.ok) throw Object.assign(new Error(res.statusText + " " + url), {res});return {getContentData: asBinary => asBinary ? res.arrayBuffer() : res.text()};});},addStyle(textContent) {const style = Object.assign(document.createElement("style"), {textContent});const ref = document.head.getElementsByTagName("style")[0] || null;document.head.insertBefore(style, ref);}};const tmpPath = top.location.pathname + "templates/" + vue_tmp_name + ".vue"const app = createApp({components: {'my-component': defineAsyncComponent(() => loadModule(tmpPath, options))},template: '<my-component></my-component>'});// 引入ElementPlus组件app.use(ElementPlus, {locale: ElementPlusLocaleZhCn});// 引入ElementPlus图标for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component);}app.mount("#app")
</script>
</html>

2. 创建两个vue模版文件用了测试

路径是按照上面的 tmp.ftl 里面的第104行定义的,如果你不想放这里相放在其他的地方,就可以修改这个路径

3. 在Erupt实体模型中使用

在这个模型中定义了两个按钮,点击按钮就会访问特定的页面文件,让后通过配置的 params 这个名字,页面就能拿到‘vue_tmp_name’ 的名字去加载指定的vue文件了

4. 访问页面

以上就是整个的使用过程,不明白的可以去拉取代码自己运行即可。

八、 源代码

代码路径:https://gitee.com/shareloke/erupt-vue3-sfc-loader-demo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/884837.shtml

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

相关文章

如何优雅处理异常?处理异常的原则

前言 在我们日常工作中&#xff0c;经常会遇到一些异常&#xff0c;比如&#xff1a;NullPointerException、NumberFormatException、ClassCastException等等。 那么问题来了&#xff0c;我们该如何处理异常&#xff0c;让代码变得更优雅呢&#xff1f; 1 不要忽略异常 不知…

DBAPI连接阿里云 maxcompute 报错

使用正确的驱动包 访问以下链接寻找驱动包 https://github.com/aliyun/aliyun-odps-jdbc/releases/tag/v3.4.3 注意要使用odps-jdbc-3.4.3-jar-with-dependencies.jar &#xff0c;这个是完整的jar包 不要使用odps-jdbc-3.4.3.jar&#xff0c;这个不是完整的&#xff0c;它还…

2024最新Python安装教程+Pycharm安装教程【附安装包】

Python安装 1.首先下载好Python安装包 获取方式&#xff1a;点击这里&#xff08;扫描神秘②薇码免下载&#xff09;完全免费&#xff01;&#xff01;&#xff01; 2.打开安装包&#xff0c;先勾选最下面两个选项&#xff0c;再选择第二个自定义安装 3.这里默认全选&#xff…

【数据库】elasticsearch

1、架构 es会为每个索引创建一定数量的主分片和副本分片。 分片&#xff08;Shard&#xff09;&#xff1a; 将索引数据分割成多个部分&#xff0c;每个部分都是一个独立的索引。 主要目的是实现数据的分布式存储和并行处理&#xff0c;从而提高系统的扩展性和性能。 在创建索…

JAVA基础:数组 (习题笔记)

一&#xff0c;编码题 1&#xff0c;数组查找操作&#xff1a;定义一个长度为10 的一维字符串数组&#xff0c;在每一个元素存放一个单词&#xff1b;然后运行时从命令行输入一个单词&#xff0c;程序判断数组是否包含有这个单词&#xff0c;包含这个单词就打印出“Yes”&…

【学习】使用webpack搭建react项目

前言 在日常工作中&#xff0c;我大多是在已有的项目基础上进行开发&#xff0c;而非从头构建项目。因此&#xff0c;我期望通过本次学习能填补我在项目初始化阶段知识的空白&#xff0c;与大家共同进步。在此过程中&#xff0c;我欢迎并感激任何指正或建议&#xff0c;无论是…

什么是人工智能体?

人工智能体&#xff08;AI Agent&#xff09;是指能够感知环境、做出决策并采取行动以实现特定目标的自主实体。以下是对人工智能体的具体介绍&#xff1a; 定义与核心概念 智能体的定义&#xff1a;智能体&#xff0c;英文名为Agent&#xff0c;是指具有智能的实体&#xff0…

【初阶数据结构篇】链式结构二叉树(续)

文章目录 须知 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&#xff1…

二叉树 最大深度(递归)

给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a;root [1,null,2] 输出…

python机器人Agent编程——实现一个本地大模型和爬虫结合的手机号归属地天气查询Agent

目录 一、前言二、准备工作三、Agent结构四、python模块实现4.1 实现手机号归属地查询工具4.2实现天气查询工具4.3定义创建Agent主体4.4创建聊天界面 五、小结PS.扩展阅读ps1.六自由度机器人相关文章资源ps2.四轴机器相关文章资源ps3.移动小车相关文章资源ps3.wifi小车控制相关…

python安装selenium,geckodriver,chromedriver

安装浏览器 找到浏览器的版本号 chrome 版本 130.0.6723.92&#xff08;正式版本&#xff09; &#xff08;64 位&#xff09; firfox 116.0.3 (64 位)&#xff0c;但是后面运行的时候又自动更新到了 127.0.0.8923 安装selenium > pip install selenium > pip show …

基于SSM+uniapp的营养食谱系统+LW参考示例

1.项目介绍 功能模块&#xff1a;用户管理、年龄类型管理、阶段食谱管理、体质类型管理、季节食谱管理、职业食谱管理等系统角色&#xff1a;管理员、普通用户技术栈&#xff1a;SSM&#xff0c;uniapp&#xff0c; Vue等测试环境&#xff1a;idea2024&#xff0c;HbuilderX&a…

python常用的第三方库下载方法

方法一&#xff1a;打开pycharm-打开项目-点击左侧图标查看已下载的第三方库-没有下载搜索后点击install即可直接安装--安装成功后会显示在installed列表 方法二&#xff1a;打开dos窗口输入命令“pip install requests“后按回车键&#xff0c;看到successfully既安装成功&…

vue项目安装组件失败解决方法

1.vue项目 npm install 失败 删除node_modules文件夹、package-lock.json 关掉安装对话框 重新打开对话框 npm install

qt QComboBox详解

QComboBox是一个下拉选择框控件&#xff0c;用于从多个选项中选择一个。通过掌握QComboBox 的用法&#xff0c;你将能够在 Qt 项目中轻松添加和管理组合框组件&#xff0c;实现复杂的数据选择和交互功能。 重要方法 addItem(const QString &text)&#xff1a;将一个项目添…

window 利用Putty免密登录远程服务器

1 在本地电脑用putty-gen生成密钥 参考1 参考2 2 服务器端操作 将公钥上传至Linux服务器。 复制上述公钥到服务器端的authorized_keys文件 mkdir ~/.ssh vi ~/.ssh/authorized_keys在vi编辑器中&#xff0c;按下ShiftInsert键或者右键选择粘贴&#xff0c;即可将剪贴板中的文…

JAVA基础:多重循环、方法、递归 (习题笔记)

一&#xff0c;编码题 1.打印九九乘法表 import java.util.*;public class PanTi {public static void main(String[] args) {Scanner input new Scanner(System.in);for (int i 0; i < 9; i) {//i控制行数/* System.out.println("。\t。\t。\t。\t。\t。\t。\t。\…

微服务系列二:跨微服务请求优化,注册中心+OpenFeign

目录 前言 一、纯 RestTemplate 方案存在的缺陷 二、注册中心模式介绍 三、注册中心技术&#xff1a;Nacos 3.1 Docker部署Nacos 3.2 服务注册 3.3 服务发现 四、代码优化&#xff1a;OpenFeign工具 4.1 OpenFeign快速入门 4.2 连接池的必要性 4.3 抽取服务、最佳实…

国产数据库之Vastbase海量数据库 G100

海量数据库Vastbase是基于openGauss内核开发的企业级关系型数据库。其语法和Oracle数据库很像&#xff0c;基本是从Oracle数据库迁移到海量数据库&#xff0c;以下简单介绍入门的使用 1、建库操作 地址&#xff1a;x.x.x.x root/Qa2021 安装路径&#xff1a;/home/vastbase 创…

爬虫学习4

from threading import Thread#创建任务 def func(name):for i in range(100):print(name,i)if __name__ __main__:#创建线程t1 Thread(targetfunc,args("1"))t2 Thread(targetfunc, args("2"))t1.start()t2.start()print("我是诛仙剑")from …