创建Cloudinary Vue组件

发布于:2021-01-29 14:09:13

0

84

0

Cloudinary Vue Reactjs JavaScript

尽管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合作,制作一些真正强大的媒体组件!