前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >技术分享 | 【工程化】越抽象,越通用

技术分享 | 【工程化】越抽象,越通用

原创
作者头像
Ar-Sr-Na
修改2023-10-30 14:29:41
6570
修改2023-10-30 14:29:41
举报
文章被收录于专栏:Ar-Sr-NaAr-Sr-Na

以下内容比较抽象,均为理论内容,对于喜欢看代码的也不妨驻足,对代码规范可能有所帮助

导言

作为天天和js打交道的前端开发,组件一定是不少用的东西,如果你是写组件的,免不了考虑多种多样的场景。

由于我的文章5000多字,突然被清空了,气死我了,所以直接从一个案例开始讲起,不必要分开了。

从案例出发

甲方有个文章推广用的小程序,简单来说小程序核心部分发布推广需求有如下功能

  1. 需求标题
  2. 预期需求
  3. 推广平台
  4. 平台uid
  5. 推广内容

以3个月前的使用来看,暂时没有出现问题,大部分用户都用得好好的,但是越往后面,因为个别平台出了新的政策,例如A平台不给用户开放uid展示了,B平台不只是可以发表文字了,C平台未来对流量考核方式变了......这时候,原先的4满足不了A平台,5满足不了B平台,2满足不了C平台,作为尽职尽责的程序员,我们总不能让用户自适应吧,但是那个老六外包公司,做完之后没给源码,导致该动起来基本没办法,只能推倒重做了,抓包发现前后端交换的数据结构已经写死,没有办法通过前端更改数据结构的方式来改变整个应用的主要问题。

出现了什么问题

简单来说,就是数据和渲染不够“抽象”,他们把最底层的东西写死了,封成了一个几乎没法改动的成品数据,而渲染他们的组件也过于表层,想要实现功能却被组件限制住了。

什么是“抽象”

在以前,前端能实现的动画效果不是很多,有人想要五彩斑斓的背景渐变色,css就加入了linear-gradient;又有人想要毛玻璃,就有了backdrop-filter;这还没完,客户是上帝,又有人想要各种五彩斑斓且背景多变甚至随机根据光线变化的渐变,css可撑不住了,因为再加更多的特性,也满足不了客户的欲望,所以这时候canvas出现了,要做什么用户自己来定,我可不管了。

这个例子,就说明css还不够抽象,canvas比css在某些方面更加抽象,因为可定义的更多。

一般来说,越底层越抽象,如果一个html页面上全是canvas,确实挺抽象,因为你不懂这页面要干什么,而这个页面又可以实现各种各样的功能,比如绘制一个矩形,一个圆形,甚至往里面渲染3d模型,3d动画,渲染一个游戏等等等等,这样巨高度的定制化,就很“抽象”。

怎么“抽象”它

前端

回到甲方的需求,B平台既然可以发表图文并茂的内容,5就不止局限于<textarea />组件,仔细想一下,一个编辑器,一定就是textarea,input吗?

例如腾讯云的这个编辑器

它是一个span标签。为了实现输入功能,加入了可以编辑的属性contenteditable,作为开发者,我们也应该有这样的思路,既然不局限于文字,是不是可以从最本质的div,span等基本标签入手,用这些最基本的标签来实现该有的功能

简单复现一下甲方的代码:

代码语言:jsx
复制
function App() {
    return (<>
        <Editor />
    </>);
}

function Editor() {
    return (<>
        <Input color="xxxx" width="xxxx" value={<>我永远<p color="red">喜欢</p><b>爱莉希雅</b></>} />
    </>);
}

function Input({ color, width, value }) {
    return (<input type="text"
        style={{
            color, width
        }}
        value={value}
    />);
}

App里面只有一个编辑器,而这个编辑器因为所有的页面都是一样的,所以当时就写死了,再往深层剖析

  • Editor是更深一层的抽象,表明了这个编辑器由一个输入框组件来实现
  • 输入框是Input,又是更深一层的抽象,里面的组件<input />就是html最基础的元素,用来实现表单输入

可以看出,越抽象的地方,代码越接多,这些代码是为了实现功能而一层层封装的。

只不过甲方没有考虑到项目的未来,把第二层抽象Editor部分完全写死了

后端

前后端数据交换是必不可少的部分,开始之初错误的估量,会引导整个项目错误的偏向

比如他们的数据

代码语言:javascript
复制
const data={
    title:'我最喜欢的角色',
    content:'菲谢尔',
    uid:123456,
    satisfaction:1000,
    platform:'tencent',
    text:'大家都知道\n我永远喜欢菲谢尔\n但是为了模拟数据,我不得不喜欢',
}

因为在开始之初就认为所有平台的数据模板都是这样,导致了出现了麻烦,title,content等全部只能输入字符串,没有为富文本考虑

  • title一定只能是纯字符吗?我可不可以让某个字换颜色显示?
  • content和text一定是纯文本吗?可以不可以添加多媒体?甚至往里面加入其他页面iframe?
  • uid只能是纯数字吗?有些平台没有uid怎么办?
  • satisfaction一定是预期的“阅读量”吗?有些平台是阅读时间呢?或者是预期收入呢?
  • platform一定只有一个吗?

这些问题,是在项目初期就得要考虑到的,要结合项目的过去,现在和未来考虑,因为前后端交换数据是更抽象的问题,前端页面你可以一个人改,后端如果不是你负责,万一哪天想要改动数据结构,让你的几十个同事半夜加班动服务器,这一动,有可能在线的客户都要受影响。

所以我的考虑就是让数据结构变成这样

代码语言:jsx
复制
const data = {
    title: {
        jsx: false,
        content: '我最喜欢的角色'
    },
    uid: {
        disableInput: ['arsrnairs'],
        map: {
            'tencent': 12345,
            'arsrna': 123456
        }
    },
    content: {
        jsx: true,
        content: <>我永远<p color="red">喜欢</p><b>菲谢尔</b></>
    },
    satisfaction: 1000,
    platform: ['tencent', 'arsrnairs', 'arsrna'],
    text: {
        jsx: true,
        content: (
            <>
                大家都知道<br />我永远喜欢<i>菲谢尔</i><br />但是为了模拟数据,我不得不喜欢
                 <img src="......"/>
                <Footer /><OtherContent {...someArgs} />
            </>
        )
    },
}

我不知道甲方原先是不是jsx写的页面,但是既然项目都要重写了,而且我喜欢jsx的语法,那就这么定了。

可以看到数据量大了不少,而且能定义的东西更多,至于多了什么,自己看吧。

如果嫌每次都要写这么多数据比较麻烦,还可以简单封装,比如ABCDE平台都是这一个模板,就可以写一个生成数据的函数

代码语言:javascript
复制
function getData({
    title = "我喜欢谁",
    uidList,
    content,
    satisfaction,
    text
}) {
    const data = {
        title: {
            jsx: false,
            content: title
        },
        uid: {
            disableInput: [],
            map: uidList
        },
        content: {
            jsx: true,
            content
        },
        satisfaction,
        platform: ['tencent'],
        text: {
            jsx: true,
            content: text
        },
    }
    return data;
}

只用简单输入几个数据就能生成整个数据,而且不影响下一层抽象的功能,一举两得。

学会留空间

我的这个用了4年的ppt,顶部和背景从未变过,变的只有内容

可以想象成一堆抽象的元素,除了顶部和背景是写死的,其他地方是抽象的,因为我不知道未来会有什么,可以自由发挥,自由定制。

通用框架为什么能流行起来?

像react的脚手架create react app,你可以用react写出各种各样的页面不受影响,你可以做成游戏,也可以做成企业官网,甚至腾讯云的控制台

这些都是由你来决定,但是因为它不是最深层的抽象,你无法实现一些更深层的功能,例如polyfill,一些浏览器可能不支持es6的新特性时,没有polyfill就没法弥补这些功能。

再比如Antd,tdesign,jQuery,bootstrap,moment,lodash等等无论是ui库还是函数库,他们都有共同的特点,那就是可以随意定制,Modal模态框组件,弹出来的窗口不一定只能是文字,你可以弹视频,弹音频,弹广告等;moment.js的format函数不一定让你一定得是unix时间戳输入,你可以定制HH-mm-ss,也可以mm-ss-HH,一切由你决定。

用户是上帝

假设有一天,react来了个逆天举措,把audio封成了一个播放器组件,这个音频组件东西可多了,有歌词,有进度条,有控制器,均衡器,音效面板等等等等,这时候你页面上乱七八糟的audio,又是歌词又是音效的,我们根本不需要这么多,但是人家封死了你不得不用那么多,或者我用上了歌词,但是我想改变颜色,但没有接口,这下可就麻烦了。

多留空间给用户,你可以默认,但不能写死,用户写什么就是什么,用户不写我就默认。

我们留给其他开发操作的空间,绝不仅限于一两句数据,该抽象还得抽象

嫌麻烦可以封装,但是要保证最基本的方法是可改的。

总结

好的工程一定会考虑明天,而工程化里的组件通用化只是整个项目的小部分,各种代码规范等一起完善起来,才能让项目持久发展。

我的5年老站,毫不夸张地说,直到今年才逐渐从jQuery转为react

这些效果也是jQuery来实现的

jQuery一个近20年的框架,在今天仍然影响着大部分前端框架的发展,因为它操作dom的思想很超前,用本文的话说就是“抽象”,它很简单,但是可以组合成很复杂的工程,只不过在今天它很难满足日益增长的需求,各种新框架应运而生,仍然可以看到里面有jQuery的身影,这些框架部分代码,其实就是把jQuery封装了起来,变成浅一层抽象的组件,给用户使用。


感谢您阅读至此

Ar-Sr-Na 未经允许禁止转载

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导言
  • 从案例出发
  • 出现了什么问题
    • 什么是“抽象”
      • 怎么“抽象”它
        • 前端
        • 后端
    • 学会留空间
      • 通用框架为什么能流行起来?
        • 用户是上帝
        • 总结
        相关产品与服务
        云开发 CloudBase
        云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
        http://www.vxiaotou.com