Статьи

Создайте музыкальный плеер с Vuetify

Конечный продукт
Что вы будете создавать

Создавать приложения с помощью Vue.js легко, весело и приятно. Вы можете создать работающее приложение с минимальными усилиями. Чтобы доказать это, сегодня я покажу вам, как легко создать свой собственный полнофункциональный музыкальный проигрыватель. Чтобы сделать все еще проще, мы будем использовать Vuetify.js , библиотеку пользовательского интерфейса на основе Vue.js, которая ускорит создание пользовательского интерфейса. Я почти чувствую твое нетерпение, так что начнем.

Вы можете найти полный исходный код в репозитории GitHub . А вот и рабочая демоверсия . Чтобы следовать этому руководству, вы должны быть знакомы с компонентами Vue, компонентами отдельных файлов Vue и синтаксисом ES2015 .

Каждое творение начинается с идеи и хотя бы некоторого базового планирования. Итак, сначала мы должны решить, что мы хотим построить и какую функциональность мы хотим реализовать. Говорят, что картинка стоит тысячи слов, поэтому начнем с простого наброска музыкального проигрывателя.

Vue музыкальный плеер каркасный набросок

Я сделал этот каркас, чтобы вы могли получить общее представление о пользовательском интерфейсе, который мы хотим построить. Следующим шагом является описание функциональности, которую мы намерены реализовать.

Как говорит Джон Джонсон:

Сначала решите проблему. Затем напишите код.

Мы будем использовать это как источник мудрости, и мы планируем приложение, прежде чем начнем его кодировать.

Vue.js — это основанная на компонентах инфраструктура. Поэтому нам нужно сначала разбить приложение на отдельные компоненты (пять в нашем случае, как показано на скриншоте выше), а также наметить функции и функциональные возможности для каждого из них.

Этот компонент будет содержать следующие части:

  • меню на левой стороне
  • название приложения в центре
  • три статических значка на правой стороне

Этот компонент будет отображать основную информацию о текущей воспроизводимой дорожке:

  • Исполнитель трека и название слева
  • текущая позиция трека и продолжительность на правой стороне

Этот компонент будет содержать две полосы, которые будут включать все элементы управления, необходимые для управления звуковыми дорожками в списке воспроизведения проигрывателя.

  • ползунок громкости со значком слева (его внешний вид будет меняться в зависимости от уровня громкости и при отключении звука), а также процентное соотношение громкости справа
  • кнопки для воспроизведения, приостановки, остановки и пропуска дорожек.
  • две кнопки справа: одна для повторения текущей дорожки, а другая для изменения порядка воспроизведения дорожек
  • панель поиска, показывающая положение воспроизводимой в данный момент дорожки, с возможностью ее изменения щелчком мыши на панели

Этот компонент будет содержать плейлист треков со следующими функциями:

  • отобразить трек с соответствующими номерами, исполнителем, названием и продолжительностью
  • выберите трек в один клик
  • проиграть трек двойным кликом

Этот компонент будет предлагать функции поиска в тех случаях, когда мы хотим найти и воспроизвести конкретную дорожку (и).

Конечно, вышеприведенный план не может охватить все детали и нюансы, и это прекрасно. На данный момент нам достаточно получить общее представление о конечном продукте. Мы будем обрабатывать все детали и возможные проблемы в процессе строительства.

Итак, давайте перейдем к интересной части и напишем код

Быстрая стартовая страница Vuetify предлагает множество вариантов, чтобы вы начали. Мы будем использовать один из готовых шаблонов Vue CLI, который называется Webpack Simple . Запустите следующие команды в каталоге, который вы хотите использовать для этого проекта:

Сначала установите Vue CLI:

1
$ npm install -g vue-cli

Затем создайте приложение:

1
$ vue init vuetifyjs/webpack-simple vue-music-player

Далее перейдите в каталог приложения и установите все зависимости:

1
2
$ cd vue-music player
$ npm install

Мы будем использовать Howler.js (аудио библиотека JavaScript) для обработки аудио частей музыкального проигрывателя. Поэтому мы должны включить его и в проект. Запустите следующую команду:

1
$ npm install —save howler

И наконец, запустите приложение:

1
$ npm run dev

Приложение откроется на localhost:8080 в браузере по умолчанию. Вы должны увидеть простой скелет приложения Vuetify.

Чтобы приспособить его к нашим потребностям, нам нужно очистить шаблон и немного настроить его. Переименуйте файл App.vue в Player.vue , откройте его, удалите все внутри и добавьте следующее:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<template>
  <v-app dark>
    <v-content>
      <v-container>
        <!— The player components go here —>
      </v-container>
    </v-content>
  </v-app>
</template>
 
<script>
  export default {
    data () {
      return {
 
      }
    }
  }
</script>

Мы помещаем наше приложение музыкального проигрывателя в компонент v-app , который необходим для правильной работы приложения. Мы также передаем dark опору, чтобы применить темную тему Vuetify.

Теперь откройте файл main.js , удалите исходное содержимое и добавьте следующее:

01
02
03
04
05
06
07
08
09
10
11
12
13
import Vue from ‘vue’
import Vuetify from ‘vuetify’
import ‘vuetify/dist/vuetify.css’
import Player from ‘./Player.vue’
 
import {Howl, Howler} from ‘howler’
 
Vue.use(Vuetify)
 
new Vue({
  el: ‘#app’,
  render: h => h(Player)
})

Кроме того, откройте файл index.html и измените содержимое <title> на Vue Music Player .

Теперь в вашем браузере вы должны увидеть пустую темную страницу. И вуаля. Вы готовы начать создавать.

Прежде чем приступить к кодированию, полезно знать, что Vuetify предлагает фрагменты кода и автозаполнение для основных редакторов кода: VS Code, Atom и Sublime. Чтобы получить фрагменты, найдите расширение в своем любимом редакторе ( vuetify-vscode , или vuetify-atom , или vuetify-sublime ).

В каталоге src создайте новую папку компонентов . Затем в этой папке создайте файл PlayerTitleBar.vue со следующим содержимым:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<template>
  <v-system-bar window>
    <v-menu offset-y transition=»slide-y-transition»>
      <v-btn flat small right slot=»activator»>
        <v-icon>headset</v-icon> MENU
      </v-btn>
      <v-list>
        <v-list-tile @click=»dialog = true»>
          <v-list-tile-title>About</v-list-tile-title>
        </v-list-tile>
        <v-dialog v-model=»dialog» max-width=»300″>
          <v-card>
            <v-card-title><h2>Vue Music Player</h2></v-card-title>
            <v-card-text>Version 1.0.0</v-card-text>
            <v-card-actions>
              <v-spacer></v-spacer>
              <v-btn flat @click=»dialog = false»>OK</v-btn>
            </v-card-actions>
          </v-card>
        </v-dialog>
      </v-list>
    </v-menu>
    <v-spacer></v-spacer>
    VUE MUSIC PLAYER
    <v-spacer></v-spacer>
    <v-icon>remove</v-icon>
    <v-icon>check_box_outline_blank</v-icon>
    <v-icon>close</v-icon>
  </v-system-bar>
</template>
 
<script>
  export default {
    data () {
      return {
        dialog: false
      }
    },
  }
</script>

Здесь мы используем следующие компоненты Vuetify: панель инструментов , меню , кнопка , значок , список , диалог и карта .

Мы разделяем меню, имя и значки с помощью компонента <v-spacer> . Чтобы показать или скрыть диалог, мы создаем свойство dialog: false данные. Его значение будет переключаться при нажатии на пункт меню « О программе» .

Теперь в файле Player.vue импортируйте компонент строки заголовка, зарегистрируйте его в объекте компонентов и добавьте в шаблон.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
  <v-app dark>
    <v-content>
      <v-container>
        <player-title-bar></player-title-bar> // ADD the component in the template
      </v-container>
    </v-content>
  </v-app>
</template>
 
<script>
  import PlayerTitleBar from ‘./components/PlayerTitleBar.vue’ // IMPORT the component
 
  export default {
    components: {
      PlayerTitleBar // REGISTER the component
    },
    data () {
      return {
 
      }
    }
  }
</script>

Теперь проверьте результат в вашем браузере. Вы должны увидеть следующее:

Строка заголовка игрока

Мы повторим эти три шага для остальных четырех компонентов. Поэтому, когда в следующих разделах я скажу вам импортировать, зарегистрировать и добавить компонент в шаблон, вы должны следовать той же процедуре, описанной здесь.

В корневом каталоге создайте новую папку списка воспроизведения и добавьте аудиофайлы, которые вы хотите воспроизвести. Имена файлов должны быть написаны с подчеркиванием между словами и расширением .mp3 в конце — например, Remember_the_Way.mp3 . Теперь создайте массив аудиодорожек внутри объекта данных Player.vue :

1
2
3
4
5
playlist: [
  {title: «Streets of Sant’Ivo», artist: «Ask Again», howl: null, display: true},
  {title: «Remember the Way», artist: «Ask Again», howl: null, display: true},
  …
]

У каждой дорожки есть свойства title и artist , объект howl со значением null и свойство display со значением true .

Свойство display будет использоваться при реализации функции поиска. Теперь для всех треков установлено значение true , поэтому все они видны.

Howler оборачивает аудиофайл в howl объект. Мы установили значение howl в null потому что оно будет динамически заполняться при создании экземпляра Vue. Для этого мы используем created Vue хук жизненного цикла .

1
2
3
4
5
6
7
8
created: function () {
  this.playlist.forEach( (track) => {
    let file = track.title.replace(/\s/g, «_»)
    track.howl = new Howl({
      src: [`./playlist/${file}.mp3`]
    })
  })
}

Это установит новый объект Howl для каждой дорожки в списке воспроизведения.

Теперь создайте компонент PlayerPlaylistPanel.vue и добавьте его внутрь:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
  <v-card height=»330″>
    <v-list>
      <v-list-tile
        v-for=»(track, index) in playlist»
        :key=»track.title»
        v-show=»track.display»>
        <v-list-tile-content>
          <v-list-tile-title>{{ index }} {{ track.artist }} — {{ track.title }}</v-list-tile-title>
        </v-list-tile-content>
        <v-spacer></v-spacer>
        {{ track.howl.duration() }}
      </v-list-tile>
    </v-list>
  </v-card>
</template>
 
<script>
  export default {
    props: {
      playlist: Array
    }
  }
</script>

Сначала мы передаем playlist prop из файла Player.vue . Далее в шаблоне мы просматриваем каждый трек с помощью директивы v-for и отображаем индекс трека, за которым следует исполнитель и название трека, а также длительность трека в крайнем правом углу. Мы также используем v-show привязанное к свойству display . Дорожка будет видна только в том случае, если display true .

Теперь в файле Player.vue мы импортируем, регистрируем и добавляем компонент плейлиста в шаблон. Затем мы привязываем реквизит playlist свойству данных playlist следующим образом: <player-playlist-panel :playlist="playlist"></player-playlist-panel> .

Давайте проверим результат в браузере:

Панель плейлиста плеера

Здесь есть две проблемы. Во-первых, номера треков не верны, а во-вторых, длительность трека отображается в миллисекундах, но мы хотим, чтобы это было в минутах. Мы исправим каждую из этих проблем, создав фильтр форматирования.

В файле main.js создайте фильтр numbers фильтр minutes , который будет доступен для всех. Далее в PlayerPlaylistPanel.vue мы используем их следующим образом: {{ index | numbers }} {{ index | numbers }} и {{ track.howl.duration() | minutes }} {{ track.howl.duration() | minutes }} .

Теперь, если вы проверите приложение, все должно отображаться правильно.

Панель плейлиста игрока с фиксированными номерами и минутами

В файле Player.vue добавьте свойство selectedTrack: null data и привяжите его к компоненту списка воспроизведения ( :selectedTrack="selectedTrack" ). Затем мы передаем реквизит в файле PlayerPlaylistPanel.vue ( selectedTrack: Object ).

Мы также добавляем прослушиватель событий щелчка в <v-list-tile-content @click="selectTrack(track)"> и затем создаем метод selectTrack() :

1
2
3
4
5
methods: {
  selectTrack (track) {
    this.$emit(‘selecttrack’, track)
  }
}

Теперь, вернувшись в Player.vue , добавьте событие selecttrack в компонент списка воспроизведения ( @selecttrack="selectTrack" ) и создайте метод selectTrack() :

1
2
3
selectTrack (track) {
  this.selectedTrack = track
}

Теперь, если вы перейдете к плейлисту и нажмете на трек, он будет выбран. Мы не можем видеть это, но мы можем доказать это в Vue DevTools. На следующем скриншоте выбран второй трек:

Плейлист плеера с выбранным треком показывается в DevTools

Следующий шаг — сделать выбор видимым. Для этого мы свяжем класс, который будет окрашивать выбранную дорожку в оранжевый, и другой класс, который сделает еще ряды темнее, чтобы сделать дорожки более различимыми. Поместите следующее после директивы v-show :

1
:class=»[{selected: track === selectedTrack}, {even: index % 2 == 0}]»

Мы также добавим еще один класс, который будет показывать полосу прокрутки, когда список становится слишком большим.

1
<v-card height=»330″ :class=»{playlist}»>

Мы добавляем необходимые классы в конец файла.

01
02
03
04
05
06
07
08
09
10
11
<style scoped>
  .selected {
    background-color: orange !important;
  }
  .even {
    background-color: #505050
  }
  .playlist {
    overflow: auto
  }
</style>

Вот и все. Теперь выбранная дорожка выделяется оранжевым цветом.

Плейлист плеера с выбранной дорожкой окрашен

Мы добавим функцию воспроизведения двойным щелчком в конце следующего раздела.

Давайте создадим элементы управления плеером сейчас. Начнем с кнопок воспроизведения, паузы и остановки.

Создайте компонент PlayerControlsBars.vue и добавьте его внутрь:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<template>
  <div>
    <v-toolbar flat height=90>
      <v-spacer></v-spacer>
      <v-btn outline fab small color=»light-blue» @click=»stopTrack»>
        <v-icon>stop</v-icon>
      </v-btn>
      <v-btn outline fab color=»light-blue» @click=»playTrack()»>
        <v-icon large>play_arrow</v-icon>
      </v-btn>
      <v-btn outline fab small color=»light-blue» @click=»pauseTrack»>
        <v-icon>pause</v-icon>
      </v-btn>
      <v-spacer></v-spacer>
    </v-toolbar>
  </div>
</template>

Здесь мы используем компонент панели инструментов Vuetify.

Есть три кнопки с зарегистрированными слушателями события щелчка. Давайте создадим методы для них:

01
02
03
04
05
06
07
08
09
10
11
methods: {
  playTrack(index) {
    this.$emit(‘playtrack’, index)
  },
  pauseTrack() {
    this.$emit(‘pausetrack’)
  },
  stopTrack() {
    this.$emit(‘stoptrack’)
  }
}

Теперь в файле Player.vue импортируйте, зарегистрируйте и добавьте компонент в шаблон. Затем зарегистрируйте прослушиватели событий ( @playtrack="play" , @pausetrack="pause" , @stoptrack="stop" ).

Затем создайте свойство данных index: 0 , в котором будет храниться индекс текущей дорожки. Затем создайте вычисляемый currentTrack() :

1
2
3
4
5
computed: {
  currentTrack () {
    return this.playlist[this.index]
  }
}

И теперь мы можем начать создавать методы play , pause и stop . Мы начнем с метода play() , но перед этим нам нужно создать свойство данных play() playing: false , которое будет указывать, воспроизводится ли дорожка или нет. Добавьте следующий код для метода play() :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
play (index) {
  let selectedTrackIndex = this.playlist.findIndex(track => track === this.selectedTrack)
 
  if (typeof index === ‘number’) {
    index = index
  } else if (this.selectedTrack) {
    if (this.selectedTrack != this.currentTrack) {
      this.stop()
    }
    index = selectedTrackIndex
  } else {
    index = this.index
  }
 
  let track = this.playlist[index].howl
 
  if (track.playing()) {
    return
  } else {
    track.play()
  }
   
  this.selectedTrack = this.playlist[index]
  this.playing = true
  this.index = index
}

Метод принимает индекс в качестве параметра, который указывает дорожку, которую необходимо воспроизвести. Сначала мы получаем индекс выбранного трека. Затем мы делаем некоторые проверки, чтобы определить значение index . Если в качестве аргумента указан индекс, а это число, то мы его используем. Если дорожка выбрана, мы используем индекс выбранной дорожки. Если выбранный трек отличается от текущего, мы используем метод stop() чтобы остановить текущий. Наконец, если ни аргумент индекса не передан, ни дорожка не выбрана, мы используем значение свойства данных index .

Далее мы получаем вой (на основе значения индекса) для трека и проверяем, играет ли он. Если это так, мы ничего не возвращаем; если это не так, мы играем в нее.

Наконец, мы обновляем свойства selectedTrack , playing и index данных.

Давайте теперь создадим методы pause() и stop() .

1
2
3
4
5
6
7
8
pause () {
  this.currentTrack.howl.pause()
  this.playing = false
},
stop () {
  this.currentTrack.howl.stop()
  this.playing = false
}

Здесь мы просто приостанавливаем или останавливаем текущий трек и обновляем свойство playing данных.

Давайте также начнем играть трек двойным кликом.

Добавьте @dblclick="playTrack()" в <v-list-tile-content> в PlayerPlaylistPanel.vue и создайте метод playTrack() :

1
2
3
playTrack(index) {
  this.$emit(‘playtrack’, index)
}

Зарегистрируйте слушателя @playtrack="play" в файле Player.vue и вуаля.

Давайте теперь добавим предыдущую и следующую кнопки.

1
2
3
4
5
6
7
8
9
<v-btn outline fab small color=»light-blue» @click=»skipTrack(‘prev’)»>
  <v-icon>skip_previous</v-icon>
</v-btn>
 
<!— stop, play, and pause buttons are here —>
 
<v-btn outline fab small color=»light-blue» @click=»skipTrack(‘next’)»>
  <v-icon>skip_next</v-icon>
</v-btn>

Создайте метод skipTrack() :

1
2
3
skipTrack (direction) {
    this.$emit(‘skiptrack’, direction)
}

Зарегистрируйте прослушиватель событий ( @skiptrack="skip" ) в Player.vue .

И создайте метод skip() :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
skip (direction) {
  let index = 0
 
  if (direction === «next») {
    index = this.index + 1
    if (index >= this.playlist.length) {
      index = 0
    }
  } else {
    index = this.index — 1
    if (index < 0) {
      index = this.playlist.length — 1
    }
  }
 
  this.skipTo(index)
},
skipTo (index) {
  if (this.currentTrack) {
    this.currentTrack.howl.stop()
  }
 
  this.play(index)
}

Сначала мы проверяем, является ли направление next . Если это так, мы увеличиваем индекс на 1. И если индекс становится больше, чем последний индекс в массиве, то мы начинаем снова с нуля. Когда направление prev , мы уменьшаем индекс на 1. А если индекс меньше нуля, то мы используем последний индекс. В конце мы используем index в качестве аргумента для skipTo() . Останавливает текущий трек и воспроизводит следующий или предыдущий.

Вот как выглядит плеер с помощью кнопок:

Кнопки воспроизведения игрока

Добавьте следующее перед всеми кнопками:

1
<v-slider v-model=»volume» @input=»updateVolume(volume)» max=»1″ step=»0.1″></v-slider>

Здесь мы используем компонент слайдера Vuetify.

Добавьте свойство данных volume: 0.5 , а затем создайте метод updateVolume() :

1
2
3
updateVolume (volume) {
  Howler.volume(volume)
}

Здесь мы используем глобальный объект Howler, чтобы установить громкость для всех воплей.

Также нам нужно синхронизировать начальный том Howler, для которого по умолчанию установлено значение 1, со свойством volume . Если вы этого не сделаете, громкость покажет 0,5, но изначально будет 1. Для этого мы снова будем использовать created хук:

1
2
3
created: function () {
  Howler.volume(this.volume)
}

Мы хотим видеть уровень громкости в процентах справа от ползунка громкости, поэтому добавим его в шаблон: {{this.volume * 100 + '%'}}

Теперь мы добавляем значок громкости перед слайдером.

1
2
3
4
5
6
7
8
<v-btn flat icon @click=»toggleMute»>
  <template v-if=»!this.muted»>
    <v-icon v-if=»this.volume >= 0.5″>volume_up</v-icon>
    <v-icon v-else-if=»this.volume > 0″>volume_down</v-icon>
    <v-icon v-else>volume_mute</v-icon>
  </template>
  <v-icon v-show=»this.muted»>volume_off</v-icon>
</v-btn>

Значок изменится в соответствии со значениями volume и muted свойствами.

Добавьте свойство данных muted: false и создайте метод toggleMute() :

1
2
3
4
toggleMute () {
  Howler.mute(!this.muted)
  this.muted = !this.muted
}

Мы снова используем глобальный объект Howler, чтобы установить отключение звука глобально, а затем переключаем значение отключения звука.

На скриншоте ниже вы можете увидеть, как должен выглядеть слайдер громкости:

Слайдер громкости плеера

Добавьте следующее после всех кнопок:

1
2
3
4
<v-btn flat icon @click=»toggleLoop»>
  <v-icon color=»light-blue» v-if=»this.loop»>repeat_one</v-icon>
  <v-icon color=»blue-grey» v-else>repeat_one</v-icon>
</v-btn>

Добавьте свойство loop: false в Player.vue , свяжите его :loop="loop" и передайте проп ( loop: Boolean ) в PlayerControlsBars.vue .

Теперь давайте создадим метод toggleLoop() :

1
2
3
toggleLoop () {
  this.$emit(‘toggleloop’, !this.loop)
}

Теперь вернитесь в Player.vue , зарегистрируйте прослушиватель событий ( @toggleloop="toggleLoop" ) и создайте метод toggleLoop() :

1
2
3
toggleLoop (value) {
  this.loop = value
}

На данный момент мы сталкиваемся с небольшой проблемой. Когда трек ищет конца, он просто останавливается. Плеер не перемещается к следующему треку и не повторяет текущий трек. Чтобы это исправить, нам нужно добавить следующее в created функцию после свойства src :

1
2
3
4
5
6
7
onend: () => {
  if (this.loop) {
    this.play(this.index)
  } else {
    this.skip(‘next’)
  }
}

Теперь, когда loop , текущая дорожка будет повторяться. Если он выключен, игрок перейдет на следующую дорожку.

Добавьте следующее после кнопки повтора:

1
2
3
4
<v-btn flat icon @click=»toggleShuffle»>
  <v-icon color=»light-blue» v-if=»this.shuffle»>shuffle</v-icon>
  <v-icon color=»blue-grey» v-else>shuffle</v-icon>
</v-btn>

Добавьте свойство shuffle: false в Player.vue , привяжите его ( :shuffle="shuffle" ) и передайте пропеллер ( shuffle: Boolean ) в PlayerControlsBars.vue .

Теперь давайте создадим метод toggleShuffle() ;

1
2
3
toggleShuffle () {
  this.$emit(‘toggleshuffle’, !this.shuffle)
}

Теперь, вернувшись в Player.vue , зарегистрируйте прослушиватель событий ( @toggleshuffle="toggleShuffle" ) и создайте метод toggleShuffle() :

1
2
3
toggleShuffle (value) {
  this.shuffle = value
}

Теперь добавьте следующее в метод skip() после index = 0 :

1
2
3
4
5
6
7
8
lastIndex = this.playlist.length — 1
 
if (this.shuffle) {
  index = Math.round(Math.random() * lastIndex)
  while (index === this.index) {
    index = Math.round(Math.random() * lastIndex)
  }
} else if (direction === «next») { …

Вот как ваше приложение должно выглядеть сейчас:

Плеер повторяет и тасует кнопки

Сначала в Player.vue создайте свойство seek: 0 . Затем нам нужно будет просмотреть playing свойство, чтобы обновить поиск.

01
02
03
04
05
06
07
08
09
10
11
12
13
watch: {
  playing(playing) {
    this.seek = this.currentTrack.howl.seek()
    let updateSeek
    if (playing) {
      updateSeek = setInterval(() => {
        this.seek = this.currentTrack.howl.seek()
      }, 250)
    } else {
      clearInterval(updateSeek)
    }
  },
}

Это обновит значение поиска четыре раза в секунду.

Теперь создайте вычисляемый progress() :

1
2
3
4
progress () {
  if (this.currentTrack.howl.duration() === 0) return 0
  return this.seek / this.currentTrack.howl.duration()
}

Свяжите это ( :progress="progress" ) в шаблоне.

Теперь в PlayerControlsBars.vue передайте реквизит progress ( progress: Number ) и добавьте еще одну панель инструментов под уже созданную нами:

1
2
3
<v-toolbar flat height=»40″>
  <v-progress-linear height=»40″ v-model=»trackProgress» @click=»updateSeek($event)»></v-progress-linear>
</v-toolbar>

Здесь мы используем компонент прогресса Vuetify.

Создайте вычисленный trackProgress() , который будет получать прогресс трека в процентах.

1
2
3
4
5
computed: {
  trackProgress () {
    return this.progress * 100
  },
}

А теперь создайте метод updateSeek() :

1
2
3
4
5
6
7
updateSeek (event) {
  let el = document.querySelector(«.progress-linear__bar»),
      mousePos = event.offsetX,
      elWidth = el.clientWidth,
      percents = (mousePos / elWidth) * 100
  this.$emit(‘updateseek’, percents)
}

Здесь мы получаем элемент индикатора выполнения, который использует .progress-linear__bar . Я нашел это с помощью браузера DevTools. Далее мы получаем положение мыши и ширину полосы. Затем мы получаем позицию щелчка мыши в процентах.

Вернитесь в Player.vue , добавьте и зарегистрируйте прослушиватель событий ( @updateseek="setSeek" ) и создайте метод setSeek() :

1
2
3
4
5
6
7
setSeek (percents) {
  let track = this.currentTrack.howl
 
  if (track.playing()) {
    track.seek((track.duration() / 100) * percents)
  }
}

И бум! Вы можете использовать мышь, чтобы изменить положение воспроизводимой дорожки.

Создайте файл PlayerInfoPanel.vue со следующим содержимым:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<template>
  <v-card height=»60″>
    <v-card-title>
      <h2>{{ trackInfo.artist }} — {{ trackInfo.title }}</h2>
      <v-spacer></v-spacer>
      <h3>{{trackInfo.seek |
    </v-card-title>
  </v-card>
</template>
 
<script>
  export default {
    props: {
      trackInfo: Object
    },
  }
</script>

Здесь мы передаем реквизит trackInfo , который мы используем для заполнения информации о треке в нашем компоненте.

Теперь вернитесь в Player.vue , импортируйте, зарегистрируйте и добавьте компонент в шаблон.

Затем создайте вычисляемый getTrackInfo() :

01
02
03
04
05
06
07
08
09
10
11
12
getTrackInfo () {
  let artist = this.currentTrack.artist,
      title = this.currentTrack.title,
      seek = this.seek,
      duration = this.currentTrack.howl.duration()
  return {
    artist,
    title,
    seek,
    duration,
  }
}

Далее мы связываем его в шаблоне ( :trackInfo="getTrackInfo" ) и вуаля. Мы получаем некоторую базовую информацию о текущей воспроизводимой дорожке, как вы можете видеть на скриншоте ниже.

Панель информации об игроке

Создайте файл PlayerSearchBar.vue со следующим содержимым:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<template>
  <v-toolbar flat>
    <v-text-field
    clearable
    prepend-icon=»search»
    placeholder=»Quick search»
    v-model=»searchString»
    @input=»searchPlaylist»>
    </v-text-field>
    <v-spacer></v-spacer>
  </v-toolbar>
</template>
 
<script>
  export default {
    props: {
      playlist: Array
    },
    data () {
      return {
        searchString: «»,
      }
    },
    methods: {
      searchPlaylist () {
        this.playlist.forEach((track) => {
          if (this.searchString) {
            if (!track.title.toLowerCase().includes(this.searchString.toLowerCase()) && !track.artist.toLowerCase().includes(this.searchString.toLowerCase())) {
              track.display = false
            } else {
              track.display = true
            }
          } else if (this.searchString === «» || this.searchString === null) {
            track.display = true
          }
        })
      }
    },
  }
</script>

Мы создаем текстовое поле и добавляем clearable опору, чтобы показать значок очистки при вводе чего-либо.

Используя v-model , мы связываем ее с searchString , которая изначально является пустой строкой. И мы добавляем слушатель события ввода.

Мы также передаем реквизит playlist , который мы используем в searchPlaylist() . В этом методе мы используем свойство display и off его для каждой дорожки, где заголовок или исполнитель не соответствует строке поиска, и сохраняем ее или включаем для всех совпадений. Наконец, если строка поиска пуста или равна null , что происходит, когда мы очищаем поле кнопкой очистки, мы включаем display для всех дорожек.

Теперь вернитесь в Player.vue , импортируйте, зарегистрируйте и добавьте компонент в шаблон.

Свяжите свойство playlist ( :playlist="playlist" ) и проверьте функциональность. Вот как это должно выглядеть в действии:

Тест панели поиска игрока

Как видите, при четкой цели и правильном планировании создание приложения Vue / Vuetify может быть действительно простым и приятным. Теперь у вас есть рабочий музыкальный проигрыватель, который вы можете использовать во время отдыха или кодирования. Конечно, всегда есть место для дальнейших улучшений и дополнений, поэтому вот несколько идей, которые вы можете попробовать, чтобы сделать плеер еще более многофункциональным:

  • поддержка нескольких списков воспроизведения
  • возможность добавлять или удалять треки из плейлиста
  • поддержка перетаскивания
  • умение сортировать треки
  • аудио визуализация

В этом уроке мы увидели, как легко и приятно создавать приложение с Vue.js, в частности с Vuetify.js. Надеюсь, вам понравилось собрать этот плеер так же, как и мне. Я буду рад видеть вашу собственную улучшенную версию плеера. Так что, если вы создадите его, просто оставьте демонстрационную ссылку в комментариях!