在当前快速变化的数字化时代,企业对系统定制化的需求越来越多。传统的方式就是从基础的代码编写到复杂的业务逻辑去实现。但是,一旦业务需求发生变更,修改和迭代的过程就更加繁琐。
在JVS低代码开发中,它可以通过可视化配置和少量代码快速实现,让前端页面定制变得简单灵活。
今天我以这个系统为例,分享它如何从零开始创建自定义前端页面并接入现有系统的完整流程。
第一步:创建逻辑标识接口
- 登录后台管理系统
- 创建以事件触发的逻辑并配置逻辑
- 创建源码标识,例如:/demo/student/count
- 请求逻辑接口:/rule/openapi/appIdentificationname/demo/student/count
这一步的目的是创建业务逻辑接口,用于前端页面调用获取数据或执行业务操作。




# 测试请求
curl 'http://localhost:9999/rule/openapi/appIdentificationname/demo/student/count' \
-H 'Authorization: Bearer Vk_tLc1nYRwqm8ksuJQ30tUrwlzauXQRtZHrammOyqkxFunTDlNV8oE83qpYpPBZcPu5kwHzlpuJjlnChZmD2r_Zi1doywRIzPUOIq6IUpYFv1qwfMrsHrrYLuDVyBkB' \
-H 'MODE: DEV'
#返回数据
{"code":0,"msg":"success","data":2,"timestamp":1761293844018}
第二步:创建前端项目
可以直接下载示例项目进行复制,直接运行即可。下载
npm install
npm run dev
Token配置(axios.js)
// 本地调试固定Token,与登录用户的 token保持一致进行调试, 部署前请将此处注释
config.headers["Authorization"] = 'Bearer Vk_tLc1nYRwqm8ksuJQ30tUrwlzauXQRtZHrammOyqkxFunTDlNV8oE83qpYpPBZcPu5kwHzlpuJjlnChZmD2r_Zi1doywRIzPUOIq6IUpYFv1qwfMrsHrrYLuDVyBkB';
// 本地添加调试模式,部署后自动获取
config.headers["MODE"] = 'DEV';
环境要求
- Node.js 16.0.0+
项目初始化
# 创建项目目录
mkdir appIdentificationdemo
cd appIdentificationdemo
# 初始化项目
npm init -y
# 安装必要依赖
npm install vue@^2.6.10 vue-router@^3.1.3 axios@^0.19.0 element-ui@^2.13.0
npm install -D @vue/cli-service@^3.11.0 sass@^1.87.0 sass-loader@^8.0.0
项目结构示例
appIdentificationdemo/
├── public/
│ └── index.html
├── src/
│ ├── router/
│ │ ├── axios.js
│ │ ├── router.js
│ │ └── views/
│ │ └── index.js
│ ├── views/
│ │ ├── api/
│ │ │ └── index.js
│ │ └── demo/
│ │ └── index.vue
│ ├── App.vue
│ └── main.js
├── vue.config.js
└── package.json
第三步:开发页面
1. 配置请求拦截器 (src/router/axios.js)
import axios from 'axios'
// 设置超时时间
axios.defaults.timeout = 30000;
// HTTP request拦截器
axios.interceptors.request.use(
config => {
// 本地开发配置临时Token 可以直接连接部署环境进行调试查看
config.headers["Authorization"] = 'Bearer [临时token]';
config.headers["MODE"] = 'DEV';
return config;
},
error => {
return Promise.reject(error);
}
);
// HTTP response拦截器
axios.interceptors.response.use(
res => {
return res;
},
error => {
return Promise.reject(new Error(error));
}
);
export default axios;
2. 创建API接口 (src/views/api/index.js)
import request from "@/router/axios"
// 分页查询数据
export const queryPage = (modelIdentification,) => {
return request({
url: `/jvs-design/app/identification/use/dynamic/data/query/page/${modelIdentification}`,
method: "post",
data: data
})
}
// 查询单条数据
export const getSingle = (modelIdentification,) => {
return request({
url: `/jvs-design/app/identification/use/dynamic/data/query/single/${modelIdentification}/${dataId}`,
method: "get"
})
}
// 新增数据
export const addSingle = (modelIdentification,) => {
return request({
url: `/jvs-design/app/identification/use/dynamic/data/save/${modelIdentification}`,
method: "post",
data: data
})
}
// 修改数据
export const editSingle = (modelIdentification, data,) => {
return request({
url: `/jvs-design/app/identification/use/dynamic/data/update/${modelIdentification}/${dataId}`,
method: "post",
data: data
})
}
// 删除数据
export const deleteData = (modelIdentification,) => {
return request({
url: `/jvs-design/app/identification/use/dynamic/data/delete/${modelIdentification}/${dataId}`,
method: "delete"
})
}
// 获取业务逻辑数据
export const getUserCount = () => {
return request({
url: `/rule/openapi/appIdentificationname/demo/student/count`,
method: "get"
})
}
3. 创建页面组件 (src/views/demo/index.vue)
<template>
<div class="demo-list">
<div class="top-bar">
<el-button type="primary" @click="addEditViewRow(null, 'add')">新增</el-button>
<div>
<span style="font-size: 12px;">调用逻辑示例</span>
<el-tag style="margin-left: 10px;">当前用户总人数: {{userTotal}}</el-tag>
</div>
</div>
<el-table :data="tableData" style="width:">
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="age" label="年龄"></el-table-column>
<el-table-column prop="id" label="学号"></el-table-column>
<el-table-column label="操作" width="140">
<template slot-scope="scope">
<el-button type="text" size="small" @click="addEditViewRow(scope.row, 'edit')">编辑</el-button>
<el-button type="text" size="small" @click="addEditViewRow(scope.row, 'view')">查看</el-button>
<el-button type="text" size="small" style="color: #F56C6C;" @click="deleteRow(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件和表单弹窗 -->
</div>
</template>
<script>
import {queryPage, getSingle, addSingle, editSingle, deleteData, getUserCount} from '@/views/api/index'
export default {
data() {
return {
routeQuery: {
dataModelId: 'student_demo'
},
page: {
total: 0,
currentPage: 1,
pageSize: 20,
},
tableData: [],
userTotal: 0,
}
},
created() {
this.getListHandle()
getUserCount().then(res => {
if (res.data && res.data.code == 0) {
this.userTotal = res.data.data
}
})
},
methods: {
getListHandle() {
let query = {
current: this.page.currentPage,
size: this.page.pageSize
}
queryPage(this.routeQuery.dataModelId, query).then(res => {
if (res.data && res.data.code == 0) {
this.page.total = res.data.data.total
this.page.currentPage = res.data.data.current
this.tableData = res.data.data.records
}
})
},
addEditViewRow(row,) {
// 实现新增、编辑、查看逻辑
},
deleteRow(row) {
// 实现删除逻辑
}
}
}</script>
4. 配置路由 (src/router/views/index.js)
一个项目可以配置 N个路由,对应多个应用
let base = process.env.NODE_ENV === 'production' ? '/app/source/appIdentificationdemo' : ''
export default [
{
path: base + '/list',
name: '应用详情',
component: () => import('@/views/demo/index'),
meta: {
keepAlive: true,
isTab: false,
isAuth: false
}
}
]
5. 配置构建设置 (vue.config.js)
const url = "http://gateway:10000" // 网关地址
// 基础路径,发布前修改这里
let path = "appIdentificationdemo";
module.exports = {
// 项目路径地址
publicPath: process.env.NODE_ENV === 'production' ? "/app/source/" : "/",
// 静态资源文件地址
assetsDir: path + "/static",
// 静态资源文件
indexPath: path + "/index.html",
outputDir: path,
lintOnSave: true,
productionSourceMap: false,
// 配置转发代理
devServer: {
port: 9999,
disableHostCheck: true,
proxy: {
"^/jvs": {
target: url,
ws: true,
pathRewrite: {
"^/jvs": "/jvs"
}
},
"^/rule": {
target: url,
ws: true,
pathRewrite: {
"^/rule": "/rule"
}
},
}
},
};
构建项目时输出目录路径需要以项目路径命名,如:appIdentificationdemo 静态资源由于是通过 nginx 固定地址代理所以需要将 build 路径也调整为对应的项目路径下
第四步:添加权限标识
- 登录轻应用管理后台
- 找到对应的轻应用
- 在权限管理中添加自定义权限标识
- 为需要访问该页面的用户或角色分配相应权限
权限标识与轻应用中的使用权限配置保持一致,用户可以手动添加权限标识。页面在初始化时会根据对应的版本渲染加载,判断是否显示隐藏权限。
权限说明如下:
1. 权限标识文件配置
1.1 文件创建
需要创建一个与项目名一致的JSON文件,例如项目名为appIdentificationdemo,则权限标识文件应命名为appIdentificationdemo.json,必须以.json为后缀。
1.2 文件位置
权限标识文件应放置在项目的public目录下,打包后会自动复制到输出目录中。以下示例是以 vue 项目为例
1.3 文件格式示例
{
"/app/source/appIdentificationdemo/list": [
{
"name": "统计人数",
"permission": "jvs_count",
"url": [
{
"url": "/rule/openapi/appIdentificationname/demo/student/count",
"type": "GET"
}
]
},
{
"name": "删除学生",
"permission": "jvs_delete_user",
"url": [
{
"url": "/jvs-design/app/identification/use/dynamic/data/{modelIdentification}/{dataId}",
"type": "DELETE"
}
]
}
]
}
注意:路径需要与路由配置中的一致,例如在src/router/views/index.js中配置的路径。
2. 权限标识接口调用
2.1 接口地址
权限标识接口地址固定为:
/jvs-design/base/app/design/permission/{应用标识}
其中{应用标识}需要在应用标识管理页面查看并替换。
2.2 调用方式
此接口必须最先请求且同步调用,确保在页面渲染前获取到权限信息。
在项目中,该接口在src/views/api/common.js中定义:
async created () {
// 同步获取权限接口 避免页面显示时会展示没有权限的内容
const permissionListRes = await getAppPermission('appIdentificationname')
if(permissionListRes.data.code==0){
this.permissionsList = permissionListRes.data.data
}
// 其他初始化代码
}
2.3 调用时机
在Vue组件的created或mounted生命周期中调用,确保权限信息在页面渲染前获取完成。
示例代码:
async created () {
// 同步获取权限接口 避免页面显示时会展示没有权限的内容
const permissionListRes = await getAppPermission('appIdentificationname')
if(permissionListRes.data.code==0){
this.permissionsList = permissionListRes.data.data
}
// 其他初始化代码
}
3. 接口返回格式
权限接口返回的数据格式如下:
{
"code": 0,
"msg": "success",
"data": [
"jvs_count",
"jvs_delete_user"
],
"timestamp": 1761462391384
}
其中data字段为权限标识数组。
4. 权限使用方式
4.1 在模板中使用
使用v-if指令根据权限列表判断是否显示按钮或其它界面元素:
<el-button type="primary" @click="addEditViewRow(null, 'add')">新增</el-button>
<div v-if="permissionsList.includes('jvs_count')">
<span style="font-size: 12px;">调用逻辑示例</span>
<el-tag style="margin-left: 10px;">当前用户总人数: {{userTotal}}</el-tag>
</div>
<!-- 在表格操作列中使用 -->
<el-button
type="text"
size="small"
style="color: #F56C6C;"
v-if="permissionsList.includes('jvs_delete_user')"
@click="deleteRow(scope.row)">删除</el-button>
4.2 在方法中使用
可以在JavaScript方法中判断权限:
methods: {
someMethod() {
if (this.permissionsList.includes('some_permission')) {
// 有权限时执行的操作
} else {
// 无权限时的处理
this.$message.warning('您没有执行此操作的权限');
}
}
}
5. 注意事项
- 权限标识文件名必须与项目名一致,且以.json为后缀
- 权限接口必须在页面初始化时最先同步调用
- 权限标识需要在应用标识管理页面预先配置
- 使用v-if而非v-show来控制权限元素的显示,避免无权限时元素仍然存在于DOM中
- 权限标识应具有良好的命名规范,建议使用有意义的英文命名
6. 权限标识命名规范
建议权限标识采用以下命名规范:
- 使用英文小写字母和下划线组合
- 命名应具有语义化,能够明确表示权限的作用
- 可以采用功能_操作的形式,例如user_create、user_delete
- 与业务相关的权限可以加上业务前缀,例如student_manage、teacher_query
这个文档详细说明了如何在项目中添加和使用权限标识,包括权限文件的配置、接口调用、返回格式以及使用方式。您可以根据项目实际情况对文档进行调整。
第五步:对接挂载页面
1. 项目打包
npm run build

2. 部署文件
按照以下步骤完成部署:
- 在原有容器中将目录挂载到本地:
本地创建./data/app/source文件夹
2.3 挂载 jvs-ui项目
2.4 挂载 jvs-design-ui项目
- ./data/app/source:/usr/share/nginx/html/app/source/
- 将打包后的项目文件夹(如appIdentificationdemo)复制到./data/app/source路径下

验证访问路径地址 http://gateway:10000/app/source/appIdentificationdemo/list 示下图:

3. 配置菜单挂载
- 登录系统管理后台
- 进入菜单管理模块
- 添加新菜单项,设置菜单名称和图标
- 配置菜单路径为: /app/source/appIdentificationdemo/list
- 为菜单项分配相应的权限标识
开发环境示例:

部署环境示例:

4. 验证访问
- 使用具有相应权限的用户账号登录系统
- 点击新添加的菜单项
- 确认页面正常加载并能正确显示数据

接口规范参考
基础路径
/jvs-design/app/identification/use/dynamic/data
功能与接口对照表
其它接口说明 包含数据模型的新增修改删除导出等,对模型操作的接口和自定义逻辑编排接口的操作。
功能与接口对照表
|---------------|----------------------------------------------------------------------------------------------------------|
| 功能 | 接口地址 |
| (通用)批量删除数据 | DELETE /jvs-design/app/identification/use/dynamic/data/{modelIdentification}/batch/delete |
| (通用)删除单条数据 | DELETE /jvs-design/app/identification/use/dynamic/data/{modelIdentification}/{dataId} |
| (通用)查询字段值 | GET /jvs-design/app/identification/use/dynamic/data/{modelIdentification}/{dataId} |
| (通用)查询全部数据 | GET /jvs-design/app/identification/use/dynamic/data/list/{modelIdentification}支持 POST 请求方式 |
| (通用)分页查询 | POST /jvs-design/app/identification/use/dynamic/data/query/page/${modelIdentification} |
| (通用)查询单条原始数据 | GET /jvs-design/app/identification/use/dynamic/data/single/{modelIdentification}/{dataId} |
| (通用)查询单条转换后数据 | GET /jvs-design/app/identification/use/dynamic/data/single/transformation/{modelIdentification}/{dataId} |
| (通用)新增/修改数据 | POST /jvs-design/app/identification/use/dynamic/data/save/{modelIdentification} |
| 自定义 调用业务逻辑 | POST /rule/openapi/{appIdentification}/{ruleIdentify}需配置事件触发方式逻辑 |
标识说明:
{appIdentification} 应用标识(需在应用中心维护源码标识){modelIdentification} 模型标识(需在应用中心维护源码标识){ruleIdentify} 逻辑标识(支持 / 开头的动态路径)
注意事项
- 确保网络连接正常,能够访问网关地址
- 正确配置Token,确保接口调用权限
- 部署时保持路径一致性
- 合理设置权限标识,确保安全性
- 在生产环境中移除调试用的临时Token
- 业务逻辑创建时选择事件触发
通过以上五个步骤,您就可以成功创建一个自定义前端页面并将其接入到现有系统中。


在线demo:https://app.bctools.cn