發(fā)布于:2021-01-29 14:09:13
0
96
0
盡管React.js在最新的JavaScript框架浪潮中引起了很多關(guān)注,但Vue.js悄然成為許多開發(fā)人員的最愛,他們發(fā)現(xiàn)React過于復(fù)雜并且不想使用webpack工具。有了Vue,您只需在頁面中包含Vue JavaScript文件,創(chuàng)建一些模板,就可以了–與原始JavaScript框架時代相反。
Cloudinary是一種出色的媒體存儲和交付服務(wù),它幾乎以每種語言提供API,以幫助開發(fā)人員使用其服務(wù),包括Node.js,Python,PHP,React等。我一直在探究Vue,并思考了什么。比借助Cloudinary API創(chuàng)建以媒體為中心的組件更好的方法。我的目標(biāo)是創(chuàng)建一個視頻組件,以反映您在許多以視頻為中心的網(wǎng)站上看到的內(nèi)容:加載縮略圖,懸停時播放預(yù)覽,最后在單擊時播放視頻。
Vue組件
我想要創(chuàng)建一個組件是因為,就像React一樣,它們很容易包含和重用。讓我們開始看一下組件模板。
組件模板
看到HTML框架將提供對我們將要操作的內(nèi)容的深入了解:
<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狀態(tài)顯示或顯示的元素,以及SVG“播放”圖標(biāo)。狀態(tài)為:
(默認(rèn))顯示視頻的縮略圖/海報圖像
(懸停)顯示拼接的匯總視頻預(yù)覽(非常類似于此帖子)
(有效)顯示整個視頻
這些狀態(tài)將通過更改根元素state 屬性的組件方法來操縱。它們的可見性將通過與每個狀態(tài)匹配的CSS選擇器進(jìn)行操作。
組件屬性
為了使該組件保持簡單,我將屬性的數(shù)量限制為僅真正需要的那些屬性:
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的轉(zhuǎn)換API是如此強(qiáng)大,以至于我可以添加數(shù)十個屬性來利用其所有功能,但是這篇文章會膨脹成一本小說!還有一些其他屬性需要基于簡單屬性的計算值,因此讓我們創(chuàng)建它們:
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`;
}
},
計算屬性可以引用簡單屬性,我在此組件中大量使用了這些屬性。
組成方法
組件的方法將在我們的組件被用來觸發(fā)功能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();
}
},
當(dāng)我確實(shí)使用該屬性時state ,請意識到我沒有使用Flux或任何其他狀態(tài)管理實(shí)用程序-該屬性僅表示應(yīng)顯示或隱藏這三個組件狀態(tài)中的哪一個。
組件CSS
這個組件所需的CSS看起來很多,但是它主要管理簡單的布局以及“狀態(tài)”:根據(jù)需要顯示和隱藏每個組件子元素:
.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除了媒體別名之外,每個道具都 包含一個默認(rèn)值,組件的用法可以很簡單:
<!-- 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媒體創(chuàng)建Vue.js組件非常容易!
閉幕
創(chuàng)建使用多種類型生成的媒體的來自單個源的Vue的成分是容易由于Cloudinary。Cloudinary生成了示例圖像,視頻海報,預(yù)覽視頻,并快速交付了這些資源以及源視頻。Vue的簡單API使創(chuàng)建Cloudinary組件變得有趣而又缺乏代碼。我期待與Vue和Cloudinary合作,制作一些真正強(qiáng)大的媒體組件!