| 导语   直播页面是一个功能丰富且复杂的页面,整个页面几乎全部由若干个功能组件构成,在这样一个背景下,如何通过前期的合理设计来接入这些功能组件,同时提高页面的扩展性和可维护性。

一、背景

开播了鹅是手Q今年上线的一个直播带货平台。

图片来源:直播截图

在实现上,我们采用的是客户端+h5模式,底层的视频流属于客户端逻辑,顶层的各种挂件属于h5逻辑。去掉视频流之后,也就是右边这张图,就是一个纯h5页面。

二、功能模块划分

在h5页面里面,总的来说可以分成两大块,一块是各种类型的挂件,比如礼物动画,商品橱窗,另一块则是一些公共基础逻辑,比如消息轮询,挂件接入等。

挂件这里其实跟我们普通开发功能组件没有多大的区别,这里就不展开描述了。而如何把各种类型的挂件组织到一个h5页面上,就是我们的挂件体系需要考虑的。

三、目标

我们在设计这套体系的时候,设置了几个目标。

  1. 高内聚,低耦合。插件在接入这套体系之后,插件和插件之前是耦合开的,不会相互影响。

  2. 可维护。由于直播项目工程比较大,希望这套体系能承接住近一两年的需求。特别如果涉及到技术栈的迁移,能够尽可能减少代码的重构。

  3. 可扩展。目标是能够接入各种各样功能的插件,避免因为某个插件不适配需要重构这套体系。

  4. 方便接入。因为在开发插件的时候,任何人都可能会来参与开发。那么我们要保证对于插件开发者来说,只关注自身插件的逻辑,尽量少的去写公共逻辑。

四、解决方案

  • 方案一:vue组件开发

大致思路是一个挂件即一个组件,所有挂件以vue组件的形式开发。这套方案跟我们平时开发的思路是差不多的。但是会有以下几个问题:

  1. 强依赖vue。后续如果迁移vue3.0或者react,那么整个直播页面需要重做,包括所有插件。

  2. 生存周期不好统一。vue虽然有一套生命周期,但这套生命周期是由组件自己控制的,如果我们想让某个组件初始化或者销毁,其实是不太好做的。

  3. 公共文件大量修改。有过开发vue组件的开发者都比较清楚,我们开发完一个vue组件的时候,需要在父级组件里面引入,如果涉及到数据交互或者样式调整,也需要在父级修改。如果组件少还好维护,一旦组件增加之后,这个公共文件就会变得越来越臃肿,并且还有可能导致组件与组件之间相互影响。

  4. 布局不好实现。这点我们放到后面的布局方案讲。

基于以上几点考虑,我们就舍弃了这个方案。然后就有了方案二。

  • 方案二:自定义插件体系

这套方案有以下几个特点。

  1. 自定义一套生命周期。我们参考了vue的生命周期,自定义一套。提供了拥有初始化,更新,销毁等功能。把渲染时机交给插件体系来控制,这样的话渲染机制就由黑盒变成白盒。而开发者只需要在对应的钩子函数里面添加自己的逻辑即可

import { util } from '@tencent/qlib';

// 插件体系模块,与直播插件独立

import { BasePlugin, Subscriber, LAYOUT_TYPE, LAYOUT } from

'@packages/basePlugin';

// 插件自身的逻辑组件
import audienceInfo from './src/AudienceInfo.vue';
import storeConfig from './store';
class AudienceInfo extends BasePlugin {
init(): void {
const MyComponent = this.RootVue.extend(audienceInfo);
// 注册状态管理器
this.rootStore.registerModule(storeConfig.name, storeConfig);
const componentEl = new MyComponent({
store: this.rootStore,
data: {
uid: 111,
},
}).$mount();
// layer由插件体系分配,把生成的DOM插入到layer里面即可完成渲染,这里

不限制语言框架,只要提供html即可
this.layer.appendChild(componentEl.$el);
}
getLayout(): LAYOUT {
return {
width: '100w',
offsetBottom: '0',
zIndex: 3,
layoutType: LAYOUT_TYPE.LEFTBOTTOM,
};
}
subscribeMsg(): Array {
return [];
}
dismiss(): void {

// 销毁内容
this.rootStore.unregisterModule(storeConfig.name);
}
}
export default AudienceInfo;

  1. 2.

  2. 核心逻辑全部用TS编写。也就是前面代码里面的@packages/basePlugin,我们全部采用TS来编写,确保不依赖第三方框架,方便以后做技术重构。

  3. 中心管理。布局,轮询,状态管理统一收归到插件体系,插件开发不需要关注如何内部实现,只需要调用具体的方法即可。

  4. 基类继承。所有插件继承一个公共的基类,保证插件的规范性。

  • 补充:布局

然后再来分析下插件布局,目前把插件分为三类:可交互的UI组件,弹窗类型组件,纯展示不可交互组件。首先我们做了一个分层处理,把弹窗类型组件放在了最顶层,可交互的UI组件放在第二层,纯展示的放在最底层,如图:

确认好层次之后,再确认每一层的布局。目标是每一层的布局模式都保持一致。

以第二层为例,这里面的组件虽然在页面的任何一个地方,比较杂乱。但仔细观察,还是有一定的规律的。第二层所有的组件都是从某个角出发,向不同的两个方向排列的。如下图所示,比如分享插件,在左下角向右排列,消息组件,在左下角向上排列。

图片来源:直播截图

找到规律之后,我们就可以去布局了。

我们分析了主流的布局方案:

布局类型

特点

block

需要组件管理自己的位置信息,一旦组件膨胀将难以维护

flex

侧重一维布局,难以处理复杂的层级关系,不方便精准定位

grid

写法复杂,不方便精准定位,还有兼容性问题(iOS10)

绝对定位

精准定位,但需要大量计算

发现都有优缺点。最后我们选择了第四种方案,绝对定位布局。

这个方案需要解决的最大问题就是位置计算,如果把这个计算交给插件做的话,每个插件接入进来都需要去计算当前已有的插件的位置,势必会把插件开发变得更复杂。所以我们把这套计算交给了插件体系去做。

插件体系在这八个方位里面分别用一个变量来存储当前方位已经占据的空间,当下一个插件接入进来的时候,根据对应的方位里面的数据来确定位置,同时把当前插件的位置信息更新到对应的变量里面。

对于插件开发者来说,只需要声明具体的方位,以及自身需要的宽高(上面代码里面的getLayout方法),插件体系就可以给插件分配好具体的位置了(上面代码里面的this.layer)。

五、目标

这套插件体系已经在直播这边平稳的使用了快半年,也从刚开始的几个插件到现在的30多个插件,到目前位置,不管收到什么样类型的需求挂件,这套体系基本都能够承接住。也从侧面看出来这套体系是基本合格的。而这篇文章的目的,还是希望在遇到类似场景的需求的时候,能给大家一些参考。

数据分析方法入门

从0开始打造UI框架:动态化框架Scrollview物理学算法解析

算力时代将至——我们是否已经做好准备

batchplot 3.6.2 插件_直播插件体系设计相关推荐

  1. java中jsp时间插件_日期插件 - WEB源码|JSP源码/Java|源代码 - 源码中国

    日期插件\My97DatePicker\calendar.js 日期插件\My97DatePicker\lang\en.js 日期插件\My97DatePicker\lang\zh-cn.js 日期插 ...

  2. whmcs对接ep插件_金盾插件对接whmcs

    DCIM允许客户端使用金盾插件,下载.安装并配置whcms插件,然后激活后客户也可使用金盾插件. 注:需先在DCIM系统激活启用金盾插件.详情请参看:>> DCIM设置金盾插件 一.whm ...

  3. obs多路推流插件_直播教程 | OBS主播如何解锁虎牙直播全部的功能玩法?

    OBS虚拟摄像头使用教程 OBS主播日常苦恼: 好想玩玩虎牙的小程序,心愿榜.你画我猜.小虎弟,还有这个那个! 好想用虎牙的连麦PK和小姐姐连麦! 好想拥有新出的智能助手旺财! ... ... 其实现 ...

  4. 全注解怎么使用分页插件_分页插件使用的方式

    分页插件使用的方式 修改 pom 文件,添加分页 jar 包依赖 修改 mybatis.xml 文件 UserDao 接口,UserMapper.xml 添加对应方法与实现 sql 对应 UserSe ...

  5. vscode卸载background插件_使用插件一键启用 Visual Studio Code 的毛玻璃效果

    本文原文发布于我的博客 https://eyhn.in 上一次 我介绍了使用 "Custom CSS and JS Loader" 插件为 MacOS 开启毛玻璃效果.现在我把它做 ...

  6. 定义跳转插件_虚幻插件Review:Logic Driver Pro 终极状态机插件

    获取与安装 虚幻商城Logic Driver Pro地址 这是老王在虚幻商城出的第一滴血,99.99大刀,这个插件还有一个Lite版34.99刀.昨天刚购入,目前研究了一下基本工作逻辑,感觉还是很满意 ...

  7. java圆饼图插件_饼图----插件

    (function( w ) { // 角度转换为弧度 function angleToRadian( angle ) { return Math.PI / 180 * angle; } /* * c ...

  8. STS插件_ springsource-tool-suite插件各个历史版本

    目前spring官网(http://spring.io/tools/sts/all)上可下载的spring插件只有:springsource-tool-suite-3.8.4(sts-3.8.4).但 ...

  9. cad通过钢筋大样生成钢筋明细表插件_各位做室内外设计的朋友,告别CAD单线画图,用天正建筑更方便...

    本人以前是做室内设计的,接触最多的就是CAD画平面方案.施工图,因为以前做家装比较多,画的图纸相对比较简单.很多刚开始接触室内装修设计的朋友基本上都是采用CAD2007-CAD2016来制作各种平面. ...

最新文章

  1. etcd 笔记(08)— 基于 etcd 实现分布式锁
  2. 过关斩将打进Kaggle竞赛Top 0.3%,我是这样做的
  3. kafka原理_Kafka动态配置实现原理解析
  4. 学会python之后-python学会基础语法之后,如何提高?
  5. LeetCode Wiggle Sort II(快排)
  6. for循环只执行一次_Python中for循环和while循环有什么区别?
  7. 异步和同步区别是什么_一次相亲经历,我彻底搞懂了什么叫阻塞非阻塞,同步异步...
  8. boost::graph::distributed::distributed_queue用法的测试程序
  9. Modelsim 后仿真操作步骤之二——用Modelsim单独进行后仿真
  10. mysql学习【第2篇】:基本操作和存储引擎
  11. 浅谈C/C+内存管理、内存泄漏、堆栈
  12. Arduino ISP下载接口
  13. bootstrap-treeview树形图参数详解
  14. 数字中国城市巡礼之开封:千年古都的智慧新生
  15. 【漏洞学习——SQL】华图教育某分站SQL注入漏洞
  16. aptx与ldac音质区别_搞清楚LDAC、aptX这些蓝牙编码都有啥区别
  17. 《信息系统安全》第二章 信息安全模型 作业
  18. iphone文件访问ftp服务器,ipad ftp服务器 iPhone/iPad访问FTP服务器设置步骤
  19. Leveldb学习笔记:leveldb的使用与原理探究
  20. 杨鹏:17天搞定gre单词的方法

热门文章

  1. 报错,Exception: Required request body is missing: public org.springframework.ui.ModelMap cn.yihuazt.co
  2. Part Ⅳ Shopping 购物??
  3. 安卓案例:标准化测试
  4. C++模板类与Java泛型类
  5. pygame为游戏添加背景_用 Python 制作飞机大战小游戏
  6. 【英语学习】【Python】Programming in Python 3 的目录
  7. eclipse--基本配置
  8. python bootstrap安装_Python+Django+Bootstrap 框架环境搭建
  9. 瀑布流式页面布局_微信小程序——实现简单的瀑布流式布局
  10. gp3688 uhf2扩频_摩托罗拉GP3688对讲机(VHF、UHF)对讲机维修