用Vue.js來開發一個電影App的前端部分

來源:互聯網
上載者:User

標籤:sha   frame   ubi   分享圖片   cep   表示   dwz   min   ret   

我們要構建一個什麼樣的App?

我們大多數人使用線上流媒體服務(如Netflix)觀看我們最喜歡的電影或者節目。這篇文章將重點介紹如何通過使用vue.js 2建立一個類似風格的電影流媒體WEB互動介面(見)。

最終的產品可以去這裡找:https://codepen.io/itslit/full/mvvjzr。

儘管Bulma將作為應用的CSS架構,但是本文將主要集中在Vue.js的使用和瀏覽CSS式樣,如果你想跟著學,我設定了一個可以作為開始學習的地方,所有自訂群組合,初始資料對象和必要的需要通過CDN引用的外部庫(如Vue-router等),都可以從https://codepen.io/itslit/pen/qmzrev獲得。

App的基本需求

讓我們記下這些基本需求:

  1. 介紹(登入)螢幕

  2. 頁尾要允許使用者可以選擇自己想要的電影

  3. 一個電影螢幕,顯示電影的標題/描述和並且有“立即播放”的提示。

  4. 一個電影預告片螢幕,在電影播放時顯示電影的預告片。

  5. 可以將電影添加到收藏夾中

我們將建立應用程式,讓頁尾隨時出現,而首頁、電影和電影預告片將共用相同的螢幕。

資料

為了簡單起見,我們將從一個簡單/可靠的資料對象(對象)開始,它將作為我們所有組件的主儲存空間。這個儲存物件將擁有我們所需要的所有電影資訊,並將集中在克裡斯托弗·諾蘭的令人敬畏的電影。下面是資料對象的一部分:

const movies = {"dunkirk": {"id": ‘dunkirk‘"title": ‘Dunkirk‘,"subtitle": ‘Dunkirk‘,"description": ‘Miraculous evacuation of Allied soldiers from Belgium, Britain, Canada, and France, who were cut off and surrounded by the German army from the beaches and harbor of Dunkirk, France, during the Battle of France in World War II.‘,"largeImgSrc": `url(‘https://image.tmdb.org/t/p/w780/fudEG1VUWuOqleXv6NwCExK0VLy.jpg‘)`,"smallImgSrc‘: ‘https://image.tmdb.org/t/p/w185/fudEG1VUWuOqleXv6NwCExK0VLy.jpg‘,"releaseDate": ‘July 21 2017‘,"duration": ‘1hr 46min‘,"genre": ‘Action, Drama, History‘,"trailerPath": ‘https://www.youtube.com/embed/F-eMt3SrfFU‘,"favorite": false},"interstellar": {...},"the-dark-knight-rises": {...},"inception": {...},"the-prestige": {...}}

讓我們開始構建App

既然我們已經建立了主要的儲存物件並理解了我們的所有組件是如何布局的,我們就可以開始構建介面了。

讓我們首先建立Vue執行個體。我們將把執行個體掛載到DOM元素app,並返回全域儲存的movies,作為我們的HTML中訪問的執行個體資料對象的一部分。

const rootApp = new Vue({el: ‘#app‘,data() {return {movieChoices: movies}}})

我們現在可以開始處理每個獨立的組件了。

頁尾部分

讓我們從列出資料存放區中所有電影的固定式頁面腳部分開始。

<div id="app"><section class="hero is-primary is-medium"><div class="hero-foot"><div class="columns is-mobile"><div v-for="movieChoice in movieChoices" class="column"><li class="movie-choice"><img :src="`${movieChoice.smallImgSrc}`" class="desktop"/><p class="mobile">{{ movieChoice.subtitle }}</p></li></div></div></div></section></div>

對已在上述粗體程式碼片段的部分:

  1. 我們用id="app"建立的DOM元素,在那裡我們的Vue執行個體將被掛載。

  2. 我們使用的是原生的v-for指令從資料來源movieChoices渲染列表。

  3. 在每一個movieChoice:

  • 我們將綁定一個映像的src到描述我們電影的smallImgSrc對象內的url(“desktop”)。

  • 我們用Mustache文法,資料繫結到movieChoice.subtitle作為手機螢幕文本顯示內容。

隨著所有CSS樣式的渲染,我們的應用程式目前應該像這樣:

案頭頁尾

手機端頁尾

電影介紹組件(和Vue-router)

我們建立了頁尾,現在我們的目標是建立一個具有我們的App標題和描述的電影介紹組件。

我們已經提到了組件將共用相同的螢幕為即將上映的電影預告片和組件(即使用者將能夠在我們的APP中直接通過點擊Intro -> Movie -> MovieComponent到達相應的連結)。

這是一個完美的用例添加vue-router庫。vue-router是vue.js官方路由器,是允許組件深入的整合的可配置的路由器,還可以嵌套/視圖映射等等。

我們將在js檔案中進行基本路由設定:

const Intro = {template:`<div class="hero-body" style="background: #1e1d1d"><div class="container has-text-centered"><div class="columns"><div class="column is-half is-offset-one-quarter vertical-align"><h1 class="home-intro">VueFlix</h1><p class="home-subintro">Select a movie below from the list of critically acclaimed Christopher Nolan films.</p></div></div></div></div>`}const routes = [{ path: ‘/‘, component: Intro },]const router = new VueRouter({routes})

上面你可以看到我們定義的第一個路由群組件Intro,我們路由這個組件{ path: ‘/‘, component: Intro }和執行個體化我們的路由new VueRouter({ routes })。

註:通過Vue有多種方式定義組件模板。電影介紹和電影詳細頁的組件使用ES6的模板文本,定義模板的多個路徑。Anthony Gore有一篇文章: 7 Ways To Define A Component Template in Vue.js。

我們現在需要注入我們的router到Vue執行個體,這使整個App的路由和渲染到我們的DOM<router-view></router-view>。

注入我們的router到Vue執行個體:

const rootApp = new Vue({el: ‘#app‘,router: router,data() {return {movieChoices: movies}}})

在DOM中渲染我們的路由群組件:

<div id="app"><section class="hero is-primary is-medium"><router-view></router-view><div class="hero-foot"><div class="columns"><div v-for="movieChoice in movieChoices" class="column"><li class="movie-choice"><img :src="`${movieChoice.smallImgSrc}`" class="desktop"/><p class="mobile">{{ movieChoice.subtitle }}</p></li></div></div></div></section></div>

我們已經成功地建立了我們的第一個根路徑:path: ‘/‘來顯示我們的IntroComponent。隨著我們添加的所有樣式,我們的應用程式應該如下所示:

電影組件(多路由)

我們現在App已經完成我們指定的主要路徑和我們的頁尾部分布局。讓我們將路徑擴充到顯示特定電影所有資訊的電影組件。

首先,讓我們正確地設定導航。如前所述,我們設定頁尾的目的是允許使用者在電影之間導航。我們將使用Vue的vue-router的router-link組件去實現導航並提供相應的目標地址。

回到HTML並對頁尾部分進行小的編輯:

<div id="app"><section class="hero is-primary is-medium"><router-view></router-view><div class="hero-foot"><div class="columns"><div v-for="movieChoice in movieChoices" class="column"><router-link :to="`/${movieChoice.id}`"tag="li"class="movie-choice"><img :src="`${movieChoice.smallImgSrc}`" class="desktop"/><p class="mobile">{{ movieChoice.subtitle }}</p></router-link></div></div></div></section></div>

我們已經建立了一個`/${movieChoice.id}`使用ES6模板文字標籤的目標url作為ID的獨立的電影(例如黑暗騎士崛起的路徑/the-dark-knight-rises)。tag參數表明,我們希望我們的router-link作為一個li渲染,而仍然偵聽點擊事件。

為了補充我們的新導航路徑,我們需要為我們的電影組件設定一個動態路由。回到我們設定路徑的地方:

const routes = [{ path: ‘/‘, component: Intro },{ path: ‘/:id‘, component: Movie }]

我們已經用一個動態段表示:id指向同一組件Movie每一條路由。我們現在能夠通過讀取$route.params.id獲得不同的動態段內組件。

現在我們已經為電影組件設定了路由,讓我們快速草擬組件並確保我們的路由正常工作。

電影組件的初稿:

const Movie = {template:`<div><div class="hero-body"><div class="container has-text-centered"><div class="columns"><div class="column is-half is-offset-one-quarter vertical-align"><h1 class="home-intro">{{ selectedMovie.title }}</h1></div></div></div></div></div>`,data () {return {selectedMovie: movies[this.$route.params.id]}},watch: {$route () {this.selectMovie()}},methods: {selectMovie () {this.selectedMovie = movies[this.$route.params.id]}}}

這裡有幾點需要注意。

data () {return {selectedMovie: movies[this.$route.params.id]}}

data函數基於$route.params.id設定組件內的selectedMovie屬性,可以從全域的movies儲存對象。

所以假設電影選擇的是黑暗騎士崛起,這selectedMovie將是movies[the-dark-knight-rises]。

watch: {$route () {this.selectMovie()}},methods: {selectMovie () {this.selectedMovie = movies[this.$route.params.id]}}

我們用watch看路徑然後有任何變化調用組件的selectMovie方法。該方法selectMovie簡單更新selectedMovie參數用新電影的選擇。當使用者從一個電影組件切換到另一個電影組件(即開關電影)時,這是必須處理的。

測試所有的東西,我們應該能夠看到路由已經工作:

現在我們知道我們的路由工作得很好,我們將更新我們的電影組件中的模板來顯示所有關於電影的期望資訊。

const Movie = {template:`<div class="hero-body":style="{ ‘background-image‘: selectedMovie.largeImgSrc }"><header class="nav"><div class="container"><div class="nav-left"><a class="nav-item"><i class="fa fa-bars" aria-hidden="true"></i></a><router-link to="/" class="nav-item is-active">Home</router-link><a class="nav-item is-active"><span class="tag is-rounded">Films</span></a><a class="nav-item is-active">Shows</a><a class="nav-item is-active">Music</a></div><div class="nav-right desktop"><span class="nav-item"><a class="title">VueFlix</a></span></div></div></header><div class="container description-container"><div class="columns"><div class="column is-three-quarters"><h1 class="title">{{ selectedMovie.title }}</h1><h4 class="subtitle"><p class="subtitle-tag">{{ selectedMovie.duration }}</p><p class="subtitle-tag">{{ selectedMovie.genre }}</p><p class="subtitle-tag">{{ selectedMovie.releaseDate }}</p></h4><p class="description">{{ selectedMovie.description }}</p><div class="links"><router-link:to="{path: ‘/‘ + $route.params.id + ‘/trailer‘}"class="button play-button">Play <i class="fa fa-play"></i></router-link></div></div></div></div></div>`,}

我們已經建立了一個router-link組件在首頁連結在導覽列使用者直接回根路徑(介紹電影的部分)。

我們引入了另一個router-link,在影片的播放按鈕,建立一個目標位置的‘/‘ + $route.params.id + ‘/trailer‘。這基本上用/trailer擴充了電影ID的當前路徑和預告片,是對我們最後的電影預告片組件的導航。

到目前為止,我們應用程式中的電影組件應該如下所示:

令人驚歎的。由於我們已經建立了一個合適的router-link來引導使用者從電影到電影預告片,現在我們需要建立電影預告片組件和相應的動態路由。

電影預告片:

const MovieTrailer = {template: `<div class="trailer-body" style="background: #1e1d1d"><div class="has-text-centered"><div class="columns"><div class="column vertical-align"><iframeallowFullScreenframeborder="0"height="376":src="trailerUrlPath"style="width: 100%; min-width: 536px"/></div></div></div></div>`,data () {return {trailerUrlPath: movies[this.$route.params.id].trailerPath}}}

我們用一個簡單的iframe顯示來自YouTube上的預告片。我們綁定iframe的src到組件的屬性trailerUrlPath設定在data函數。簡單的trailerUrlPath訪問全域的movies,得到基於$route.params.id合適的電影資訊的url。

伴隨著動態路由:

const routes = [{ path: ‘/‘, component: Intro },{ path: ‘/:id‘, component: Movie },{ path: ‘/:id/trailer‘, component: MovieTrailer }]

我們的應用程式在這個時刻:

我們差不多完成了!我們只需要再解決一個簡單的添加電影收藏和VueFlix那便是完整的。

添加到收藏夾

movies中的每一個電影對象都有一個favorite的布爾值。我們將使用這個觸發器來表示一個電影是否被添加到收藏夾中。

關於視覺顯示,我們將有兩個視覺提示:

  • 電影組件周圍的黃色框陰影

  • 通過一個黃色標記清單項目在頁尾部分

我們通過在我們已經預留的favorite-shadow和favourite-check類的建立來協助我們做到這些。

.favorite-shadow {box-shadow: 0 0 50px 15px rgba(251, 255, 15, 0.25);}.favorite-check {position: absolute;right: 5px;top: 5px;z-index: 1;color: #fcff4c;@media(max-width: $medium) {position: initial;display: block;}}

現在,我們需要在Movie組件模板和頁尾部分中應用條件類綁定。我們還需要為Movie組件中的“添加到收藏夾”按鈕建立事件處理常式。

我們的電影組件:

const Movie = {template:`<div :class="[{ ‘favorite-shadow‘: selectedMovie.favorite }, ‘hero-body‘]":style="{ ‘background-image‘: selectedMovie.largeImgSrc }"><header class="nav">...</header><div class="container description-container">.........<div class="links"><router-link:to="{path: ‘/‘ + $route.params.id + ‘/trailer‘}"class="button play-button">Play <i class="fa fa-play"></i></router-link><aclass="button is-link favorites-button"@click="addToFavorites"><span:class="[{ ‘hide‘: selectedMovie.favorite }]">Add to</span><span:class="[{ ‘hide‘: !selectedMovie.favorite }]">Remove from</span>&nbsp;favorites<i class="fa fa-plus-square-o"></i></a></div></div></div>`,data() {...},watch: {},methods: {selectMovie() {...},addToFavorites() {movies[this.$route.params.id].favorite =!movies[this.$route.params.id].favorite}}

結合上述的類favorite-shadow是由selectedMovie.favorite布爾值來確定而hero-body應該永遠存在。

我們還推出了‘添加/刪除‘從收藏夾按鈕後,原來的播放按鈕。“添加到收藏夾”按鈕從addToFavorites()方法處理簡單的切換即當單擊某一部電影的favorite時,文本之間切換“添加”和“刪除”基於電影是否已添加或刪除收藏夾(hide類是建立類設定display:none),沒有就添加有就刪除。

類似地,我們還需要在頁尾中引入檢查標記的條件類綁定:

<div id="app"><section class="hero is-primary is-medium"><router-view></router-view><div class="hero-foot"><div class="columns is-mobile"><div v-for="movieChoice in movieChoices" class="column"><router-link :to="`/${movieChoice.id}`"tag="li"class="movie-choice"><i :class="[{ ‘fa fa-check-circle favorite-check‘: movieChoice.favorite }]"></i><img :src="`${movieChoice.smallImgSrc}`" class="desktop"/><p class="mobile movie-title">{{ movieChoice.subtitle }}</p></router-link></div></div></div></section></div>

現在我們應該能夠把電影添加到我們的收藏夾列表中!

乾杯!

謝謝你花時間來看這篇文章。這是我我們一起打破瓶頸和進一步瞭解vue.js概念的共同的一種鍛煉,所以我希望這是有益的,你學到的東西了嗎?

如果你有任何問題/意見,我會很高興聽到的!

本文原作者Hassan Djirdeh,由本博主翻譯,本博主的很多vue.js教程也可以到這裡。

用Vue.js來開發一個電影App的前端部分

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.