初探 BEM:构建抖音生态实时视频播放器
引言
在前端开发中,相信绝大部分小伙伴都不会在页面结构上有太大问题,但被取类名问题困扰很久呢?取的类名简短又难以明其意,取的长又繁琐,抑或取的类名元素之间不关联,每个取独立的名字呢?由此,本文将介绍一种清新脱俗的国际命名规范BEM,并带领实战一个抖音实时视频播放器。
目录
1. 什么是BEM
2.BEM的规范
3.如何使用BEM命名
4.实战项目
5.总结
什么是BEM
BEM 是一种简单直观的命名规范,它将页面分解为独立的块(Block)、元素(Element)和修饰符(Modifier),并使用双下划线(__)和双连字符(--)来表示它们之间的关系。BEM规定是块和元素之间用—连接,元素和修饰符之间用_连接。通过 BEM 规范,我们可以清晰地了解各个元素之间的关联,从而更轻松地编写和维护代码。
BEM 的规范
-
Block(块) :块是页面上的独立的功能单元,它可以是任何可重复使用的组件或模块。在我们的实时视频播放器项目中,
.live-play
就是一个块,表示整个播放器组件。 -
Element(元素) :元素是块的组成部分,它们只能在块的上下文中使用,并且与块紧密相关。在我们的项目中,
.live-play__player
表示视频播放器,.dyui-btn
表示控制按钮。 -
Modifier(修饰符) :修饰符用于修改块或元素的外观或行为。它们可以是可选的,并且可以与块或元素结合使用。例如,
.dyui-btn__play
表示播放按钮,.dyui-btn__mute
表示静音按钮。
如何使用 BEM 规范命名?
在编写代码时,我们应该遵循以下几个原则:
- 使用语义化的命名:命名应该清晰、具有描述性,能够准确地表达元素的作用和含义。
- 避免嵌套过深:尽量保持命名的简洁明了,不要过度嵌套,以免造成不必要的复杂性。
- 使用双下划线和双连字符:在块和元素之间使用双下划线,块或元素与修饰符之间使用双连字符,以确保命名的一致性和可读性。
实战项目
我们学会了基础的BEM规范,接下来就来完成一个抖音的实时视频播放器小组件。
首先我先简单介绍一下组件的概念。
组件是指可重用、独立、封装了特定功能的代码单元。它将相关的 HTML、CSS 和 JavaScript 代码组合在一起,形成一个独立的功能单元,可以在不同的页面或应用中重复使用。举个不恰当的比喻就是
HTML
中的标签就是士兵,而组件就是一支队伍。
在我们的实时视频播放器项目中,我们将遵循以上的 BEM 规范,为各个组件和元素命名
- Block(块) :在代码中,
.live-play
就是一个块,代表了整个视频播放器的容器。这个块包含了播放器的标题、视频播放区域和控制按钮。 - Element(元素) :在
.live-play
块内部,我们使用了.live-play__hd
和.live-play__bd
,它们分别代表播放器的头部和主体部分。另外,.live-play__title
代表了播放器标题,.live-play__player
代表了视频播放器,.live-play__controls
则代表了控制按钮区域。 - Modifier(修饰符) :在按钮的类名中,我们使用了修饰符来表示不同的状态或样式。例如,
.dyui-btn__play
表示播放按钮,.dyui-btn__stop
表示停止按钮,.dyui-btn__mute
表示静音按钮,.dyui-btn__object-fit
表示全屏按钮。
源项目可参考抖音开发者平台
详细代码如下
<div id="app">
<div class="live-play">
<div class="live-play__hd">
<div class="live-play__title">实时视频播放器</div>
</div>
<div class="live-play__bd">
<div class="live-play">
<video class="live-play__player" id="myLive" controls>
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
<div class="live-play__controls">
<button class="dyui-btn dyui-btn__play" @click="livePlay">开始播放 play</button>
<button class="dyui-btn dyui-btn__stop" @click="liveStop">停止播放 stop</button>
<button class="dyui-btn dyui-btn__mute" @click="liveMute">{{ muted ? '取消静音' : '静音' }}</button>
<button class="dyui-btn dyui-btn__object-fit" @click="toggleFullScreen">{{ isFullScreen ? '退出全屏' : '全屏' }}</button>
</div>
</div>
</div>
</div>
</div>
body, html {
margin: 0;
padding: 0;
height: 100%;
overflow: auto;
}
.live-play {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
background-color: #f5f5f5;
min-height: 100%;
overflow-y: auto;/*page 一屏高度,用滚动条*/
-webkit-overflow-scrolling: touch;/*滚动如丝般顺滑*/
}
.live-play__title {
font-size: 24px;
color: #333;
margin-top: 20px;
}
/* Block */
.live-play {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 90%;
max-width: 600px;
margin: auto;
padding: 20px;
background-color: #f5f5f5;
border-radius: 8px;
box-sizing: border-box;
}
/* Element: 视频播放器 */
.live-play__player {
width: 100%;
height: 50vw;
max-height: 70vh;
background-color: #000;
border-radius: 8px;
overflow: hidden;
}
/* Element: 控制按钮 */
.live-play__controls {
display: flex;
flex-direction: column;
width: 100%;
margin-top: 20px;
}
/* Modifier: 控制按钮样式 */
.dyui-btn {
width: 100%;
padding: 12px 24px;
font-weight: 500;
font-size: 17px;
text-decoration: none;
color: #fff;
line-height: 1.4118;
border-radius: 8px;
-webkit-user-select: none;
user-select: none;
margin-bottom: 10px;
border: none;
cursor: pointer;
}
.dyui-btn__play {
background-color: #07c160;
}
.dyui-btn__stop {
background-color: rgba(0, 0, 0, 0.5);
}
.dyui-btn__mute {
background-color: #fa5151;
}
.dyui-btn__object-fit {
background-color: #999;
}
new Vue({
el: '#app',
data: {
autoplay: true,
objectFit: 'contain',
muted: false,
player: null,
isFullScreen: false,
originalWidth: 'auto',
originalHeight: 'auto'
},
methods: {
livePlay() {
console.log('开始调用播放:', this.player);
if (this.player) {
this.player.play();
}
},
liveStop() {
if (this.player) {
this.player.pause();
}
},
liveMute() {
this.muted = !this.muted;
if (this.player) {
this.player.muted = this.muted;
}
},
toggleFullScreen() {
this.isFullScreen = !this.isFullScreen;
if (this.isFullScreen) {
this.originalWidth = this.player.offsetWidth;
this.originalHeight = this.player.offsetHeight;
this.player.style.width = '100%';
this.player.style.height = '100%';
} else {
this.player.style.width = this.originalWidth + 'px';
this.player.style.height = this.originalHeight + 'px';
}
},
},
mounted() {
this.player = document.getElementById('myLive');
}
});
总结
通过本文的介绍,现在应该对什么是 BEM、BEM 的规范以及如何使用 BEM 规范去命名有了一定的了解。记住,在实际项目中,遵循良好的命名规范能够提高代码的可读性和可维护性,同时也能更好地与团队合作,共同构建出优秀的前端应用!
转载自:https://juejin.cn/post/7373592723864174607