前端为实现UI效果统一和代码复用使用,在组件原子化、模块化、自动化,智能化方向的探索,实现前端提效。
前端项目的开发过程中,开发者需要投入大量的时间、精力去进行基础代码的初始化; 在共建项目中,也会出现代码风格不统一的情况,维护成本提高; 前端为了实现UI效果统一,代码复用使用,我们将组件进行原子化、模块化封装,那么在自动化,智能化方向,我们还能做一些什么去实现前端提效呢? 基于简单的配置自动生成可用的业务逻辑代码呢? 在时间/统一性提效层面,总结了下面几种小方法,既能保证风格统一,又能避免“复制粘贴”,也能节省共建的小伙伴开发时间。
1、基于vsCode的自定义代码片段snippets,使用频率🌟🌟🌟🌟🌟, 几乎每天都会用到。
适用场景:比较适合基础代码的构建,可以是页面,也可以是代码块;可以根据自己的个人使用习惯定义代码片段;
vscode插件库也提供了vue2,vue3相关snippets插件,可以下载使用
{
"Print to console": {
"prefix": "list",
"body": [
"<template>",
" <div class='box-container'>\n",
" </div>",
"</template>",
"<script>",
"export default {",
" components: {\n",
" },",
" mixins: [],",
" props: {\n",
" },",
" watch: {\n",
" },",
" data() {",
" return {\n",
" };",
" },",
" computed: {\n",
" },",
" created() {\n",
" },",
" mounted() {\n",
" },",
" methods: {\n",
" },",
"};",
"</script>\n",
"<style scoped lang=\"${1:scss}\">\n",
"</style>\n",
],
"description": "Create vue list"
}
}
2、基于plop插件,实现基础代码的批量生成,使用频率🌟🌟, 初始化新功能代码必用。
// eslint-disable-next-line func-names
module.exports = function (plop) {
plop.setGenerator('generator', {
description: '创建列表模板', // 这里是对这个plop的功能描述
prompts: [{
type: 'input', // select
message: '请输入模块名称如system(可省略)',
name: 'modeName',
default: '',
}, {
type: 'input',
name: 'apiName',
message: '接口和存储的名称',
},
{
type: 'confirm',
name: 'hasCreate',
message: '是否需要创建页面',
default: this.hasCreate,
}],
actions: (data) => {
const { hasCreate } = data;
const routePath = "{{modeName}}";
console.log(hasCreate, 'dsdsdsdsd');
const actions = [{
type: 'add',
path: 'src/pages/{{modeName}}/list.vue',
templateFile: 'plop-templates/list/list.hbs', // 模板文件
}, {
type: 'add',
path: 'src/pages/{{modeName}}/components/config.js', // 文件存放路径
templateFile: 'plop-templates/list/components/config.js', // 模板文件
}, {
type: 'add',
path: 'src/pages/{{modeName}}/components/mixins.vue', // 文件存放路径
templateFile: 'plop-templates/list/components/mixins.js', // api
}, {
// 配置路由文件
type: 'modify',
path: 'src/router/index.js',
pattern: /\/\/ generator import/,
template: "import {{modeName}} from './modules/{{modeName}}';\n// generator import", //增加标记,下次填充的时候匹配到这个关键字部分
}, {
// 配置路由文件
type: 'modify',
path: 'src/router/index.js',
pattern: /\/\/ generator router/,
template: `{\n...{{modeName}},\n},\n// generator router`,
}, {
type: 'add',
path: 'src/router/modules/{{apiName}}.js', // 文件存放路径
templateFile: 'plop-templates/list/route.js', // api
}, {
type: 'add',
path: 'src/api/{{apiName}}.js', // 文件存放路径
templateFile: 'plop-templates/api/demo.js', // 文件夹下的modules.ts
}, {
type: 'add',
path: 'src/store/modules/{{apiName}}/index.js', // 文件存放路径
templateFile: 'plop-templates/store/index.js', // 文件夹下的modules.ts
}, {
type: 'add',
path: 'src/store/modules/{{apiName}}/db.json', // 文件存放路径
templateFile: 'plop-templates/store/db.json', // 文件夹下的modules.ts
}];
if (hasCreate) {
actions.push({
type: 'add',
path: 'src/pages/{{modeName}}/create.vue', // 文件存放路径
templateFile: 'plop-templates/list/create.vue', // 模板文件
});
}
return actions;
},
});
};
{
"posts": [
{ "id": 1, "title": "json-server", "author": "swj8" }
],
"comments": [
{ "id": 1, "body": "some comment", "postId": 1 }
],
"profile": { "name": "typicode" }
}
设计结构图如下, 比较粗糙,关于字段定义渲染页面的配置可以简单看下,业务逻辑相关代码就不做展示了。
import {formatArrayToObj} from '@/utils/index.js';
const permissionOptions = [
{label: '公有', value: 'PUBLIC', default: '', type: 'primary'},
{label: '私有', value: 'PRIVATE', default: '', type: 'warning'},
];
const permissionOptionsObj = formatArrayToObj(permissionOptions, 'value');
const searchFormJson = {
title: '列表的查询条件',
tabs: [{label: '我创建的', value: 'creator'}, {label: '全部', value: 'all'}],
elements: {
name: {
label: '数据名称',
component: 'el-input',
default: '',
attrs: {
style: {
width: '200px',
},
},
},
auth: {
label: '权限范围',
component: 'pul-select',
default: '',
attrs: {
options: permissionOptions,
style: {
width: '200px',
},
},
},
creator: {
label: '创建人',
component: 'pul-erp',
default: {},
hidden: true,
attrs: {
placeholder: '请精确搜索创建人',
style: {
width: '200px',
},
},
},
},
formAttrs: {
labelWidth: '90px',
labelWidthBorder: false,
inline: true,
class: 'fold-form-item',
},
feature: {
hasSearchBtn: true,
},
};
const createDataForm = {
title: '创建数据',
elements: {
name: {
label: '数据名称',
// required: true,
component: 'el-input',
default: '',
rule: [
{ required: true, message: '请输入数据名称', trigger: 'change' }],
attrs: {
placeholder: '请输入英文、数字、下划线',
maxlength: "30",
'show-word-limit': true,
},
},
desc: {
label: '数据描述',
component: 'el-input',
default: '',
attrs: {
type: "textarea",
autosize: { minRows: 2, maxRows: 4},
},
},
auth: {
label: '权限范围',
labelDesc: '若生效范围为私有,则仅用户自己可以查看使用;若生效范围为公有,则其他用户也可查看和引用',
component: 'pul-select',
required: true,
default: 'PUBLIC',
attrs: {
options: permissionOptions,
style: {
display: 'inline-block',
width: '100%',
},
},
},
},
formAttrs: {
labelWidth: '120px',
labelWidthBorder: false,
inline: true,
'label-position': 'right',
class: 'fold-form-item',
},
feature: {
hasSearchBtn: false,
},
};
export {
permissionOptionsObj,
searchFormJson,
createDataForm,
};
编排基础页面展示:
除了编排和执行,我们还提供了操作记录查询、工具生成的历史数据查询;整个的数据结构也都是复用编排的数据结构。
{
"activeTabId": 0, //展开即可定位到当前激活的tab
"description": "注册京东账号",
"environment": "test",
"tabInfos": [
{
"allBlocks": [
{
"blockId": 1226,
"blockModules": [
{
"chosenTemplateId": 0,
"interfaceId": 0,
"modules": [
{
"approveConfig": null,
"associateInfo": null, //接口信息
"paramConfig": {
"max": 0,
"min": 0,
...组件参数配置
},
"paramInfos": [],
"required": false,
"stepValue": "",
"styleProperties": { //组件样式信息
"background": "#fef0f0",
"customRow": 4
},
"tabId": 115,
"templateIds": [],
"toolId": 11,
"type": 7,
"typeName": "使用说明",
"updateTime": 1698924413000
}
],
"styleProperties": null,
"templateSelectId": 0,
"templateSelectName": "",
"templateSelects": [ //支持模版绑定切换组件
{
"moduleIds": [
{
"defaultValue": "test0001pin",
"id": 1230
},
{
"defaultValue": "18801333",
"id": 1877
},
{
"defaultValue": "test0001pin",
"id": 1232
}
],
"templateId": 44,
"templateName": "普通账号"
}
]
}
],
"category": "desc",
"styleProperties": {
"formLabelWidth": "auto",
"formCompWidth": "auto",
"formItemWidth": "100%"
}
},
],
"createTime": 1698924413000,
"description": "",
"groupId": 16,
"groupName": "xx",
"id": 115,
"modifier": null,
"name": "xx",
"sequence": 1,
"status": 3,
"statusName": "成功",
"toolId": 11,
"updateTime": 1698924413000
}
],
"toolId": 11,
"toolName": "xx"
}
上述代码配置,只适用于测试物料生成吗?并非如此,目前物料平台关于按钮级别的操作,后端直接下发工具,前端已经无需参与开发了;后期规划:后期考虑将前端渲染逻辑进一步封装为插件,类似的功能就可以实现跨平台复用。