跳到主要内容
版本:Next

前端架构说明文档

目录

|- public
|- script
|- src
|----api
|----assets //资源
|----cms //cms sdk依赖
|----libs
|--------Create //创建对象
|--------Base //基础模块
|--------Permission // 权限
|--------Store //公共数据
|--------Language //多语言
|----components //cms sdk依赖
|------BaseDialog //封装的弹窗,样式统一
|------Table//封装的表格,样式统一
|------other...//其他
|----provider //全局注入,element命名空间
|------provider.ts // h
|------provider.vue // render组件
|----utils //工具
|------enum //枚举
|----widgets //组件
|------hook.ts //钩子
|------...
index.html

前端组件开发按照MVC的设计模式来进行开发,分别为Controlls、Models、Views

text

Controller为业务控制端,在代码中可理解为hook,关联models的数据模型,最终影响View端的视图展示。 在代码结构中如以下展示

text

保证一个View,对应一个Model,对应一个Controller Model 每个Model所对应在全局组件下,都是可以访问的,可单独访问一个model,也可以访问全局model,保证数据模型的共用

import { injectModel, injectModels } from '@/libs/Provider/Provider'

// 单独模型
...
const myEntityName = injectModel<MyEntityName>('myEntityName')
...
//全局模型数据
...
const models = injectModels()

可自行打印结果查看其结构

text

每个组件Model中可传入对象,可通过面向对象的方式拿取使用。

export class MyEntityName extends Base<{ [key: string]: any }> {
constructor() {
super({
data: [],
custom: {}
})
}

getList() {
}
...
}

// 使用myEntityName的数据
myEntityName.data.value
myEntityName.custom.value
myEntityName.getList()

View

相比较之前的开发,view更多是跟Controll打交道,所以不要将方法放到view文件中。 保证代码清爽。

text

Controller

保证组件hook和models的 正确使用,其他使用参考组件文档(information-ui)

Permission权限

针对之前的权限不好使用,比较杂乱的问题,统一进行整改,使用vue指令进行权限校验。 需要在组件根目录组件中进行引入,包括权限体系

import { usePermission } from '@/libs/Permission/Permission'
...

export default defineComponent({
name: 'MyPluginName',

setup(props, ctx: SetupContext) {
useProvideModels()
usePermission(props, permissionCodes)
...

在需要使用权限的地方引入权限指令
import { vPermission } from '@/libs/Permission/Permission'

...

export default defineComponent({
name: 'MyEntityName',
directives: {
permission: vPermission,
},
...

<IconButton
v-permission="myEntityName-add"
icon="add-p"
onClick={onAddMyEntityName}
type="primary"
>
添加
</IconButton>

支持在线生成开发模版CURD

图片

通过点击添加组件,配置组件名与组件ID,点击确定后,会在本地src/widgets目录下生成一个基础组件,具备增删改查的能力,需要根据接口定义,更改接口字段即可。

图片

图片

支持配置组件设置及属性

图片

通过在代码中配置[widgetName].settings.vue|tsx 配置右侧设置面板,提升开发效率。

图片

显示效果及输出结果保证与客户端统一

支持本地调试多语言配置,增加可选多语言,提升开发效率

可以根据自己需要,在代码中更改多语言配置文件

图片

图片

图片

启动

开发环境和生产编译,都可通过安装以下配置来最快完成配置


yarn add -D lmes

dev环境下,默认配置如下:

import VitePluginDevelopmentFilter from './script/plugins/vite-plugin-development-filter'

const tag = 'information-debugger'
const prodTag = 'information-prod'
import run from 'lmes'
export default run({
plugins: [VitePluginDevelopmentFilter({ prodTag, tag })],
})

prod编译环境下,配置如下:

import VitePluginWidgetProvider from './script/plugins/vite-plugin-widget-provider'
import VitePluginDevelopmentFilter from './script/plugins/vite-plugin-development-filter'

const tag = 'information-debugger'
import build from 'lmes'
export default build({
plugins: [
VitePluginWidgetProvider(),
VitePluginDevelopmentFilter({ tag, prodTag: 'information-prod' }),
],
esbuild: {
drop: ['debugger', 'console'],
},
})

关于information-debuggerinformation-prod标签,这个两个属于自定义标签,可以用于本地展示,线上环境不显示,通过npm run build,会把关于嵌套在information-debugger中的代码都删除,线上代码实际不存在。 例子:

 const Widget: any = SopWidgetMap[widgetMode.value]
return (
<div class={styles.sop}>
{opConfig.value.hasPermission &&
widgetMode.value !== 'Process' &&
running && (
<div
title={opConfig.value.title || undefined}
class={styles.mask}
></div>
)}
<information-prod>
<Widget node={props.node} widgetId={widgetMode.value} />
</information-prod>
<information-debugger>
{sopList.map((item: any) => {
const Widget: any = SopWidgetMap[item.value] || h('div')
return (
<div style={{ height: '350px', overflow: 'auto' }}>
<span style={{ color: 'red' }}>
{widgetMap[item.value].label}
</span>
{<Widget node={props.node} widgetId={item.value} />}
</div>
)
})}
</information-debugger>
</div>
)

该功能是通过vite插件的方式实现的,通过在vite不同生命周期内处理模版代码完成功能


/**
* 增加debugger组件
* @param option
* @returns
*/
export default function VitePluginDevelopmentFilter(option: {
tag: string
prodTag: string
}): any {
return {
name: 'vite-plugin-development-filter',
transform(code, id) {
const { tag, prodTag } = option
const regexWithCapture = new RegExp(
`<${tag}>([\\s\\S]*?)<\\/${tag}>`,
'g'
)
const regexWithCaptureProd = new RegExp(
`<${prodTag}>([\\s\\S]*?)<\\/${prodTag}>`,
'g'
)
if (regexWithCapture.test(code)) {
if (process.env.NODE_ENV === 'production') {
const newCode = code.replaceAll(regexWithCapture, '')
return newCode
.replaceAll(`<${prodTag}>`, '')
.replaceAll(`</${prodTag}>`, '')
}
}
if (regexWithCaptureProd.test(code)) {
if (process.env.NODE_ENV === 'development') {
const newCode = code.replaceAll(regexWithCaptureProd, '')
return newCode
}
}
return code
},
}
}

ts配置如下,最新版本lmes仅支持ESM开发模式

tsconfig.json

{
"compilerOptions": {
"experimentalDecorators": true,
"skipLibCheck": true,
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": false,
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"jsx": "preserve",
"jsxImportSource": "vue",
"allowSyntheticDefaultImports": true,
"noEmit": true,
"allowImportingTsExtensions": true,
"baseUrl": ".",
"types": ["element-plus/global"],
"plugins": [{ "name": "@vue/typescript-plugin" }],
"paths": {
"@/*": ["src/*"],
"components/*": ["src/components/*"]
}
},
"files": ["./src/index.d.ts"],
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"src/**/*.js"
],
"exclude": ["node_modules", "dist"]
}