发布于:2021-01-29 14:09:13
0
84
0
尽管React.js在最新的JavaScript框架浪潮中引起了很多关注,但Vue.js悄然成为许多开发人员的最爱,他们发现React过于复杂并且不想使用webpack工具。有了Vue,您只需在页面中包含Vue JavaScript文件,创建一些模板,就可以了–与原始JavaScript框架时代相反。
Cloudinary是一种出色的媒体存储和交付服务,它几乎以每种语言提供API,以帮助开发人员使用其服务,包括Node.js,Python,PHP,React等。我一直在探究Vue,并思考了什么。比借助Cloudinary API创建以媒体为中心的组件更好的方法。我的目标是创建一个视频组件,以反映您在许多以视频为中心的网站上看到的内容:加载缩略图,悬停时播放预览,最后在单击时播放视频。
Vue组件
我想要创建一个组件是因为,就像React一样,它们很容易包含和重用。让我们开始看一下组件模板。
组件模板
看到HTML框架将提供对我们将要操作的内容的深入了解:
<div v-on:mouseenter="showPreview()" v-on:mouseleave="hidePreview()" class="cloudinary-video-item" :style="dimensions">
<div class="cloudinary-video-item-image">
<img :src="poster" :width="width" :height="height" alt="Video Preview">
</div>
<div class="cloudinary-video-item-active">
<video ref="previewVideo" autoplay loop :width="width" :height="height"></video>
</div>
<div class="cloudinary-video-item-video">
<video ref="fullVideo" autoplay controls :width="width" :height="height"></video>
</div>
<svg
v-on:click="play()"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="play-icon"
version="1.1"
height="50"
width="50"
viewBox="0 0 1200 1200">
<path
d="M 600,1200 C 268.65,1200 0,931.35 0,600 0,268.65 268.65,0 600,0 c 331.35,0 600,268.65 600,600 0,331.35 -268.65,600 -600,600 z M 450,300.45 450,899.55 900,600 450,300.45 z"
id="path16995" />
</svg>
</div>
我们的组件具有四个直接子元素:三个基于CSS状态显示或显示的元素,以及SVG“播放”图标。状态为:
(默认)显示视频的缩略图/海报图像
(悬停)显示拼接的汇总视频预览(非常类似于此帖子)
(有效)显示整个视频
这些状态将通过更改根元素state 属性的组件方法来操纵。它们的可见性将通过与每个状态匹配的CSS选择器进行操作。
组件属性
为了使该组件保持简单,我将属性的数量限制为仅真正需要的那些属性:
Vue.component('cloudinary-video', {
props: {
account: { type: String, required: true, default: 'david-wash-blog' },
alias: { type: String, required: true },
// These can be strings as they come in as attributes
width: { type: String, default: 400 },
height: { type: String, default: 300 }
},
意识到Cloudinary的转换API是如此强大,以至于我可以添加数十个属性来利用其所有功能,但是这篇文章会膨胀成一本小说!还有一些其他属性需要基于简单属性的计算值,因此让我们创建它们:
computed: {
dimensions: function() {
return `width:${this.width}px; height:${this.height}px;`;
},
poster: function() {
return `http://res.cloudinary.com/${this.account}/video/upload/${this.alias}.jpg`;
},
preview: function() {
return `http://res.cloudinary.com/${this.account}/video/upload/so_0,du_2/l_video:${this.alias},fl_splice,so_12/du_2/fl_layer_apply/l_video:${this.alias},fl_splice,so_24/du_2/fl_layer_apply/l_video:${this.alias},fl_splice,so_36/du_2/fl_layer_apply/l_video:${this.alias},fl_splice,so_48/du_2/fl_layer_apply/l_video:${this.alias},fl_splice,so_80/du_2/fl_layer_apply/${this.alias}.mp4`;
},
fullVideo: function() {
return `http://res.cloudinary.com/${this.account}/video/upload/${this.alias}.mp4`;
}
},
计算属性可以引用简单属性,我在此组件中大量使用了这些属性。
组成方法
组件的方法将在我们的组件被用来触发功能mouseenter,mouseleave和click 事件:
methods: {
play: function () {
// Hide the preview
this.hidePreview();
// Set the state to "play" to show full video element
this.$el.setAttribute('state', 'playing');
// Set the full video element src
this.$refs.fullVideo.src = this.fullVideo;
},
showPreview: function() {
// If the full video is loaded and playing, ignore this event
if(this.$el.getAttribute('state') === 'playing') {
return;
}
// Update state for CSS / component's child element visibility
this.$el.setAttribute('state', 'preview');
// Set the preview video source
this.$refs.previewVideo.src = this.preview;
},
hidePreview: function() {
// If the full video is loaded and playing, ignore this event
if(this.$el.getAttribute('state') === 'playing') {
return;
}
// Update state for CSS / component's child element visibility
this.$el.setAttribute('state', '');
// Stop the video
this.$refs.previewVideo.pause();
}
},
当我确实使用该属性时state ,请意识到我没有使用Flux或任何其他状态管理实用程序-该属性仅表示应显示或隐藏这三个组件状态中的哪一个。
组件CSS
这个组件所需的CSS看起来很多,但是它主要管理简单的布局以及“状态”:根据需要显示和隐藏每个组件子元素:
.cloudinary-video-item {
position: relative;
}
.cloudinary-video-item > div {
position: absolute;
top: 0;
left: 0;
}
.cloudinary-video-item img {
display: block;
}
.cloudinary-video-item svg {
position: absolute;
top: 40%;
left: 45%;
cursor: pointer;
opacity: 0.6;
}
.cloudinary-video-item svg:hover {
opacity: 0.9;
}
/* Default / image only state */
.cloudinary-video-item .cloudinary-video-item-active,
.cloudinary-video-item .cloudinary-video-item-video {
display: none;
}
/* Preview state */
.cloudinary-video-item[state=preview] .cloudinary-video-item-active {
display: block;
}
.cloudinary-video-item[state=preview] .cloudinary-video-item-image {
display: none;
}
/* Playing state */
.cloudinary-video-item[state=playing] .cloudinary-video-item-video {
display: block;
}
.cloudinary-video-item[state=playing] .cloudinary-video-item-image,
.cloudinary-video-item[state=playing] .cloudinary-video-item-active,
.cloudinary-video-item[state=playing] svg {
display: none;
}
那里有很多,但缩小后几乎不会留下足迹!
使用组件
props除了媒体别名之外,每个道具都 包含一个默认值,组件的用法可以很简单:
<!-- simplest usage -->
<cloudinary-video alias="cartoon"></cloudinary-video>
<!-- customized usage -->
<cloudinary-video
account="david-wash-blog"
alias="cartoon"
width="640"
height="360">
</cloudinary-video>
最后添加一个new Vue 电话以启动所有操作:
new Vue({ el: '#video-holder' })
为您的Cloudinary媒体创建Vue.js组件非常容易!
闭幕
创建使用多种类型生成的媒体的来自单个源的Vue的成分是容易由于Cloudinary。Cloudinary生成了示例图像,视频海报,预览视频,并快速交付了这些资源以及源视频。Vue的简单API使创建Cloudinary组件变得有趣而又缺乏代码。我期待与Vue和Cloudinary合作,制作一些真正强大的媒体组件!
作者介绍