一、最早的灵感
最早的灵感来自sprider / 网络爬虫 / 爬虫配置,在爬虫爬取网站文章时候,会输入给爬虫一个配置文件,里边的内容是一个json对象。里边包含了所有想要抓取的页面的信息。爬虫通过这个配置就可以抓取目标网站的数据。其实本文要引出的配置就类似爬虫的配置,一模一样。只是我们把配置输入给了前端的组件,数据从接口直接获取。本质上是一模一样的。相比较爬虫配置我们会定义的更加细致而已,以满足需求。
爬虫配置
{
"url": "https://example.com", // 目标网页的URL
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
},
title: 'js代码获取title', // 这里就类似本文的组件
content: 'js代码获取content', // 这里就类似本文的组件
......
"timeout": 10, // 请求超时时间(秒)
"max_retries": 3 // 最大重试次数
}
爬虫通过配置爬取到数据后,会把数据输入到模板页面,模板页面会承载所有的数据,前端会以富文本的形式得到模板页面,在页面展示出来。
或者以接口的形式给到前端也是同理的。
这里的重点是一个配置文件,驱动爬虫抓取了目标页面的所有信息。
我们的配置从某种意义上和爬虫配置是一样的。
本文的重点是类似爬虫配置一样,给前端组件输入一个配置从而形成一个基础的页面。
二、配置工程师的玩笑
有一个玩笑的话,前端开发工程师是配置工程师。我作为前端开发工程师可以这么玩笑的说,别人不能对我这么说,因为我们定义配置是对业务和技术的升华形成了配置。别人对我这么说我认为你只看到了前端努力后简洁明快的结果,没有看到努力的过程,我会不高兴,刚过元旦,我只能祝你元旦快乐,洗洗睡吧。
三、理解配置驱动开发
很长时间在团队里强调,业务开发与组件开发分离。为什么?因为业务开发往往比较紧急,往往在代码逻辑上不够细致,在UI上也不够完美,规范性难以保证,多方人员的情绪接踵而来。所以我强调业务开发与组件分离。
我这么强调和引导,并不是想要开发组件成为少数人所谓在团队中的专利和壁垒,我在倡导业务开发与组件开发分离的同时我积极引导团队每一个成员开发组件,给予机会,并引导帮助迭代。
那么组件化之后会带来哪些变化,为什么组件化是前端工程化的重要组成,简单讲就是,"输入配置,输出结果"。大大提升了生产力。甚至一套配置驱动多端(pc端/小程序端/等,再有其他端也是同理),这里就引出的本文的主题"配置"。
随着我团队组件化的丰富,基本做到了配置驱动开发。由业务和技术我们定义配置,由配置驱动开发。采用这种方式后,团队成员开发效率和积极性有明显提高。技术水平在开发组件过程中也得到提升。在定义配置的过程中/伴随对业务的研究-业务水平也得到提升。
我一直相信要有开放包容的心态,积极努力的过程中带动一帮人,这样的努力更有意义,独学而无友,则孤陋而寡闻,这也是我博客的初衷。
四、配置驱动开发的前提
组件化、模块化,以此产生了配置,以配置的规范性/统一性来驱动多端
五、展示表单页面
如图展示的内容均可轻易通过配置的方式轻松实现
六、定义配置
// 字段命名要显性命名,不能产生歧义
// 每一个对象是一个模块
// 再有更多的模块类型也是同理,再有更多的表单类型也是同理
// 涉及到从接口获取数据的/比如select-remote,输入接口即可,若输入数据,那么配置小的变化就需要全量的处理
// 本文第五条展示的内容合理的配置都可以输出
export const config = {
id: 'contract',
title: 'contract',
list: [{
id: '',
type: 'buttons',
title: '',
list: [
{
type: 'add',
id: '1',
name: '新增',
code: '001',
event: () => {},
disabled:false,
more: {}
},
{
type: 'edit',
id: '2',
name: '编辑',
code: '002',
event: () => {},
disabled:false,
more: {}
},
{
type: 'details',
id: '3',
name: '详情',
code: '003',
event: () => {},
disabled:false,
more: {}
},
// ...
],
more: {}
},
{
id: '',
type: 'form',
title: '',
list: [ // form配置项
{
type: 'title'
label: "title",
},
{
type: 'input'
label: "姓名",
fieldName: '',
fieldValue: '', // 可能没有
disabled:false,
},
{
type: "select",
label: "收货地址",
fieldName: "",
fieldValue: '',
required: true,
disabled:false,
attrs: {
placeholder: "请选择收货地址",
disabled:false,
options: [
{label:'北京', value: 1},
{label:'上海', value: 2},
],
},
more: {}
},
{
type: "select-remote",
label: "负责人",
fieldName: "personInChargeName",
fieldValue: "personInChargeId",
required: true,
url: '/m-a-center/api/v1/a/pageList',
method: 'get',
res: ['res', 'payload', 'content'],
map: [
{
key: 'label',
target: 'userName',
},
{
key: 'value',
target: 'id',
},
],
params: {
query: 'keyword',
default:{
companyId: uni.getStorageSync('company-id'),
page: 1,
pageSize: 20,
},
},
attrs: {
placeholder: "请选择负责人",
disabled:false,
options: [],
},
more: {}
},
// ...
],
values: {}, // 数据
event: () => {},
more: {}
},
{
id: '',
type: 'table',
title: '',
list: [[ // table配置项
{
type: 'title'
label: "title",
},
{
type: 'input'
label: "姓名",
fieldName: '',
fieldValue: '', // 可能没有
disabled:false,
},
{
type: "select",
label: "收货地址",
fieldName: "",
fieldValue: '',
required: true,
disabled:false,
attrs: {
placeholder: "请选择收货地址",
disabled:false,
options: [
{label:'北京', value: 1},
{label:'上海', value: 2},
],
},
more: {}
},
{
type: "select-remote",
label: "负责人",
fieldName: "personInChargeName",
fieldValue: "personInChargeId",
required: true,
url: '/m-a-center/api/v1/a/pageList',
method: 'get',
res: ['res', 'payload', 'content'],
map: [
{
key: 'label',
target: 'userName',
},
{
key: 'value',
target: 'id',
},
],
params: {
query: 'keyword',
default:{
companyId: uni.getStorageSync('company-id'),
page: 1,
pageSize: 20,
},
},
attrs: {
placeholder: "请选择负责人",
disabled:false,
options: [],
},
more: {}
},
// ...
]],
values: [{}, {}], // table 数据
buttons: [
{
type: 'add',
id: '1',
name: '新增',
code: '001',
event: () => {},
more: {}
},
{
type: 'edit',
id: '2',
name: '编辑',
code: '002',
event: () => {},
more: {}
},
{
type: 'details',
id: '3',
name: '详情',
code: '003',
event: () => {},
more: {}
},
// ...
]
event: () => {},
more: {}
}],
more: {}
}
七、一套配置实现多端开发
核心思想:组件和配置结合起来驱动开发、让组件有秩序
八、定义规范配置模板
前端工程化:plop自动生成文件(快速开发,创建模板文件)_前端自动化生成文件-CSDN博客
九、写在最后
做这份工作我们是想实现减少重复的工作,以提高效率。
并不是以所谓配置为名,进行工作转移,比如把前端工作转移给后端,这样违背了分工的意义/专业的人做专业的事情
如果配置走的极端一点,通过url的参数识别业务,在页面请求接口,接口返回左右的页面结构和数据以及交互规则,那么这样前端无需做任何工作,即可实现,那么这是提高效率了吗,并没有,反而很大程度增加了工作量,降低了效率,为什么,因为这个过程中工作量没有减少,只是进行了转移,把前端的工作全部转移给了后端去做,让不擅长的人做不擅长的工作,这个与初衷是违背的。并且失去了灵活性,不利开发。