欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 会展 > 让Erupt框架支持.vue文件做自定义页面模版

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

2024/11/6 8:56:58 来源:https://blog.csdn.net/WLPJLP/article/details/143473753  浏览:    关键词:让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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com