Vytvoření komponenty Cloudinary Vue

Zatímco React.js přitáhl velkou pozornost během poslední vlny JavaScriptových frameworků, Vue.js se v tichosti stal oblíbencem mnoha vývojářů, kteří považují React za příliš složitý a nechtějí se zabývat nástroji webpack. S Vue můžete jednoduše zahrnout soubor JavaScript Vue na stránku, vytvořit několik šablon a jste na cestě – návrat z původních dnů frameworku JavaScript.

Cloudinary, úžasná služba pro ukládání a doručování médií, poskytuje rozhraní API téměř ve všech jazycích, aby pomohla vývojářům používat jejich služby, včetně Node.js, Python, PHP, React atd.  Chtěl jsem se podívat na Vue a přemýšlel jsem, co lepší způsob, jak toho dosáhnout, než vytvářet komponenty zaměřené na média s pomocí Cloudinary API. Mým cílem bylo vytvořit video komponentu, která odráží to, co vidíte na mnoha webech zaměřených na video: načtení miniatury, přehrání náhledu po najetí myší a nakonec přehrání videa po kliknutí. Jdeme!

Zobrazit ukázku

Rychlá poznámka:Komponenta Vue.js, kterou pro tento příspěvek vytvářím, by mohla být dále optimalizována (použijte jeden <video> prvek, vyměňte ovládací prvky, animované přechody atd.), ale chci, aby byl tento příspěvek co nejjednodušší a zaměřený. Hlavním cílem je ilustrovat, jak se Cloudinary a Vue.js vzájemně doplňují a oba se neuvěřitelně snadno používají!

Komponenta Vue

Chtěl jsem vytvořit komponentu, protože, podobně jako React, jsou snadno obsaženy a znovu použitelné. Začněme tím, že se podíváme na šablonu komponenty.

Šablona komponenty

Zobrazení kostry HTML nám poskytne přehled o tom, s čím budeme manipulovat:

<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>

Naše komponenta má čtyři bezprostřední podřízené prvky: tři prvky, které se zobrazují nebo zobrazují na základě stavu CSS, a ikonu „přehrát“ SVG. Stavy jsou:

  1. (výchozí) Zobrazit miniaturu/obrázek plakátu k videu
  2. (umístění kurzoru) Zobrazit sešitý agregovaný náhled videa (podobně jako tento příspěvek)
  3. (aktivní) Zobrazí celé video
Tyto stavy budou upraveny metodami komponent, které změní state kořenového prvku atribut; jejich viditelnost bude řízena selektorem CSS odpovídajícím každému stavu.

Vlastnosti součásti

V zájmu zachování jednoduchosti této komponenty omezuji počet vlastností pouze na ty, které jsou skutečně potřeba:

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 }
  },

Uvědomte si, že transformační API Cloudinary je tak výkonné že bych mohl přidat desítky vlastností, abych využil všech jeho schopností, ale tento příspěvek by se změnil na román! Existuje několik dalších vlastností, které vyžadují vypočítané hodnoty založené na jednoduchých vlastnostech, takže je také vytvořte:

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`;
  }
},

Vypočítané vlastnosti mohou odkazovat na jednoduché vlastnosti, které v této komponentě hojně využívám.

Metody komponent

Metody komponent budou použity ke spuštění funkčnosti během mouseenter naší komponenty , mouseleave a click události:

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();
  }
},

I když používám atribut state , uvědomte si, že nepoužívám Flux ani žádný jiný nástroj pro správu stavu – atribut jednoduše představuje, který ze tří stavů komponenty by měl být zobrazen nebo skrytý.

Komponent CSS

CSS požadovaných pro tuto komponentu se zdá být hodně, ale většinou spravuje jednoduché rozvržení i „stav“:zobrazení a skrytí každého podřízeného prvku komponenty podle potřeby:

.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;
}

Je toho tam docela dost, ale zmenšené by stěží zanechaly stopu!

Použití komponenty

S každou rekvizitou v  props obsahující výchozí hodnotu, kromě aliasu média samozřejmě může být použití komponenty jednoduché:

<!-- simplest usage -->
<cloudinary-video alias="cartoon"></cloudinary-video>

<!-- customized usage -->
<cloudinary-video
  account="david-wash-blog"
  alias="cartoon"
  width="640"
  height="360">
</cloudinary-video>

A nakonec přidání new Vue zavolejte, abyste vše spustili:

new Vue({ el: '#video-holder' })

Tak snadné je vytvořit komponentu Vue.js pro vaše Cloudinary média!

Zobrazit ukázku

Zavírání

Vytvoření komponenty Vue, která využívá více typů generovaných médií z jednoho zdroje, bylo díky Cloudinary snadné. Cloudinary vygeneroval ukázkový obrázek, video plakát, náhled videa a rychle dodal tyto zdroje i zdrojové video. Díky jednoduchému API Vue bylo vytváření komponenty Cloudinary zábavné a krátké na kód. Těším se, až si pohraju s Vue a Cloudinary, abychom vytvořili skutečně výkonné mediální komponenty!