이 글은 주로 vue-music의 Player 컴포넌트에 대한 관련 정보를 자세하게 소개하고 있습니다. 관심 있는 친구들이 참고할 수 있습니다.
이 글의 예시는 Player 컴포넌트에 대한 것입니다. 참고로 구체적인 내용은 다음과 같습니다
미니 플레이어:
1. 각 페이지마다 플레이어 구성 요소가 열립니다. 먼저 vuex state.js
import {playMode} from 'common/js/config.js'; const state = { singer:{}, playing:false, //是否播放 fullScreen:false, //是否全屏 playList:[], //播放列表 sequenceList:[], // 非顺序播放列表 mode:playMode.sequence, // 播放模式(顺序0,循环1,随机2) currentIndex:-1, //当前播放索引 } export default state --------------------------------------------- // config.js export const playMode = { sequence:0, loop:1, random:2 }
2에서 전역 플레이어 상태를 정의합니다. 플레이어 페이지에 들어갈 때 재생 목록 데이터를 가져오고 재생 상태를 변경합니다. 음악 목록 목록에서 열기
노래 목록 구성 요소의 상위 항목에 이벤트를 전달합니다. 컴포넌트, 현재 노래의 정보와 인덱스를 전달합니다
<li @click="selectItem(song,index)" v-for="(song,index) in songs" class="item"> ------------------------------ selectItem(item,index){ this.$emit('select',item,index) },
음악 목록 컴포넌트에서 발송 이벤트를 받습니다.
<song-list :rank="rank" :songs="songs" @select="selectItem"></song-list>
3. 여러 상태를 커밋하는 경우
import {playMode} from 'common/js/config.js' export const selectPlay = function({commit,state},{list,index}){ commit(types.SET_SEQUENCE_LIST, list) commit(types.SET_PLAYLIST, list) commit(types.SET_CURRENT_INDEX, index) commit(types.SET_FULL_SCREEN, true) commit(types.SET_PLAYING_STATE, true) }
4. mapActions를 사용하여 음악 목록 구성 요소에 변경된 값을 제출합니다.
import {mapActions} from 'vuex' methods:{ selectItem(item,index){ this.selectPlay({ list:this.songs, index }) }, ...mapActions([ 'selectPlay' ]) },
5. 해당 위치 (코드 전체 코드는 아래 설명을 참고하시면 천천히 이해하실 수 있습니다)
<p class="player" v-show="playList.length>0"> // 如果有列表数据则显示 <p class="normal-player" v-show="fullScreen"> //如果全屏 <p class="background"> <img :src="currentSong.image" alt="" width="100%" height="100%"> //模糊背景图 </p> <p class="top"> <p class="back" @click="back"> <i class="icon-back"></i> </p> <h1 class="title" v-html="currentSong.name"></h1> //当前歌曲名称 <h2 class="subtitle" v-html="currentSong.singer"></h2> //当前歌手名 </p> <p class="middle"> <p class="middle-l"> <p class="cd-wrapper"> <p class="cd" :class="cdCls"> <img :src="currentSong.image" alt="" class="image"> //封面图 </p> </p> </p> </p> <p class="bottom"> <p class="progress-wrapper"> <span class="time time-l">{{ format(currentTime) }}</span> <p class="progress-bar-wrapper"> <progress-bar :percent="percent" @percentChange="onProgressBarChange"></progress-bar> </p> <span class="time time-r">{{ format(currentSong.duration) }}</span> </p> <p class="operators"> <p class="icon i-left"> <i :class="iconMode" @click="changeMode"></i> </p> <p class="icon i-left" :class="disableCls"> <i @click="prev" class="icon-prev"></i> </p> <p class="icon i-center" :class="disableCls"> <i :class="playIcon" @click="togglePlaying"></i> </p> <p class="icon i-right" :class="disableCls"> <i @click="next" class="icon-next"></i> </p> <p class="icon i-right"> <i class="icon icon-not-favorite"></i> </p> </p> </p> </p> </transition> <transition name="mini"> <p class="mini-player" v-show="!fullScreen" @click="open"> <p class="icon"> <img :src="currentSong.image" alt="" width="40" height="40" :class="cdCls"> </p> <p class="text"> <h2 class="name" v-html="currentSong.name"></h2> <p class="desc" v-html="currentSong.singer"></p> </p> <p class="control"> <i :class="miniIcon" @click.stop="togglePlaying"></i> </p> <p class="control"> <i class="icon-playlist"></i> </p> </p> </transition> <audio :src="currentSong.url" ref="audio" @canplay="ready" @error="error" @timeupdate="updateTime" @ended="end"></audio> </p>
플레이어 상태 열기
import {mapGetters,mapMutations} from 'vuex'; ...mapGetters([ 'fullScreen', 'playList', 'currentSong', 'playing', 'currentIndex', ])
참고: vuex에서 상태를 수정하기 위해 컴포넌트에 직접 값을 할당할 수는 없습니다. This.fullScreen = false는 돌연변이를 통해 변경되어야 합니다. 돌연변이 유형 및 돌연변이를 정의한 다음 vuex의 mapMutations 프록시 메서드를 사용하여
[types.SET_FULL_SCREEN](state, flag) { state.fullScreen = flag }, import {mapGetters,mapMutations} from 'vuex'; methods:{ ...mapMutations({ setFullScreen:"SET_FULL_SCREEN", }), back(){ this.setFullScreen(false) }, }
를 호출하여 클릭 재생 버튼 메서드
<i :class="playIcon" @click="togglePlaying"></i>
togglePlaying(){ this.setPlayingState(!this.playing); //改变全局变量playing 的属性 }, // 然后watch 监听playing 操作实际的audio 标签的播放暂停 watch:{ playing(newPlaying){ let audio = this.$refs.audio; this.$nextTick(() => { newPlaying ? audio.play():audio.pause(); }) } }, // 用计算属性改变相应的播放暂停图标 playIcon(){ return this.playing? 'icon-pause':'icon-play' },
를 설정합니다. -이전 및 다음 노래 버튼 방법을 재생합니다. mapGetters를 사용하여 currentIndex 값(더하기 1 또는 빼기 1)을 가져와 변경함으로써 currentSong의 상태를 변경하고 재생 전환을 수신합니다. 재생 목록 제한 재설정을 결정합니다.
prev(){ if(!this.songReady){ return; } let index = this.currentIndex - 1; if(index === -1){ //判断播放列表界限重置 index = this.playList.length-1; } this.setCurrentIndex(index); if(!this.playing){ //判断是否播放改变播放暂停的icon this.togglePlaying(); } this.songReady = false; }, next(){ if(!this.songReady){ return; } let index = this.currentIndex + 1; if(index === this.playList.length){ //判断播放列表界限重置 index = 0; } this.setCurrentIndex(index); if(!this.playing){ this.togglePlaying(); } this.songReady = false; },
곡이 로드될 때 오디오 요소 태그의 canpaly 이벤트를 듣고, 노래에 오류가 발생하면 error 이벤트를 들어 사용자가 빠르게 전환하여 오류가 발생하는 것을 방지할 수 있는 사용자 경험을 제공합니다.
songReady 플래그를 설정합니다. 노래가 준비되지 않은 경우 다음 노래를 클릭할 때 false를 직접 반환합니다.
data(){ return { songReady:false, } }, ready(){ this.songReady = true; }, error(){ this.songReady = true; },
진행 표시줄
오디오 요소는 현재의 읽기-쓰기 속성 타임스탬프를 얻기 위해 timeupdate 이벤트를 수신합니다. 재생 시간. 시간 처리 형식을 지정하려면 형식을 사용하세요. (_pad는 제로 패딩 함수입니다.)
총 오디오 지속 시간 가져오기 currentSong.duration
<p class="progress-wrapper"> <span class="time time-l">{{ format(currentTime) }}</span> <p class="progress-bar-wrapper"> <progress-bar :percent="percent" @percentChange="onProgressBarChange"></progress-bar> </p> <span class="time time-r">{{ format(currentSong.duration) }}</span> </p> <audio :src="currentSong.url" ref="audio" @canplay="ready" @error="error" @timeupdate="updateTime" @ended="end"></audio>
updateTime(e){ this.currentTime = e.target.currentTime; // 获取当前播放时间段 }, format(interval){ interval = interval | 0; const minute = interval/60 | 0; const second = this._pad(interval % 60); return `${minute}:${second}`; }, _pad(num,n=2){ let len = num.toString().length; while(len<n){ num = '0' + num; len ++; } return num; },
진행 표시줄 구성 요소를 만들고, 센트 진행 매개 변수를 받고, 진행 표시줄의 너비를 설정하고 공의 위치. 플레이어 구성 요소는 계산된 속성 백분율을 설정합니다
percent(){ return this.currentTime / this.currentSong.duration // 当前时长除以总时长 },
progress-bar 구성 요소
<p class="progress-bar" ref="progressBar" @click="progressClick"> <p class="bar-inner"> <p class="progress" ref="progress"></p> <p class="progress-btn-wrapper" ref="progressBtn" @touchstart.prevent="progressTouchStart" @touchmove.prevent="progressTouchMove" @touchend="progressTouchEnd" > <p class="progress-btn"></p> </p> </p> </p>
const progressBtnWidth = 16 //小球宽度 props:{ percent:{ type:Number, default:0 } }, watch:{ percent(newPercent){ if(newPercent>=0 && !this.touch.initated){ const barWidth = this.$refs.progressBar.clientWidth - progressBtnWidth; const offsetWidth = newPercent * barWidth; this.$refs.progress.style.width = `${offsetWidth}px`; this.$refs.progressBtn.style.transform=`translate3d(${offsetWidth}px,0,0)` } } }
Set drag
진행 표시줄 작은 버튼 ProgressBtn에 touchstart, touchmove, touchend 이벤트 수신 방법을 추가하고 이벤트에 방지를 추가합니다. 기본 검색 액추에이터 동작으로 드래그를 방지하고 계산을 위한 드래그 정보를 얻습니다
인스턴스에 터치 개체를 생성하여 서로 다른 콜백 간의 통신 및 공유 상태 정보를 유지합니다. touchstart 이벤트 메소드에서 먼저 this.touch.initiated를 true로 설정하여 드래그가 시작되었음을 나타냅니다. 클릭 시작 위치 e.touches[0].pageX를 기록하고 이를 터치 객체에 저장하여 현재 진행 폭을 기록합니다.
touchmove에서는 먼저 터치시작 방식이 입력되었는지 확인하고, 이동된 위치에서 클릭 시작 위치의 오프셋 길이를 뺀 값을 계산합니다. let deltax = e.touches[0].pageX - this.touch.startX
는 진행률 표시줄의 기존 길이에 오프셋 길이를 더해 설정할 수 있습니다. 최대 너비는 상위 진행률 표시줄의 너비를 초과할 수 없습니다
진행률 표시줄의 너비를 설정하려면 this._offset(offsetWidth) 메서드를 호출하세요.
드래그 종료를 나타내려면 터치엔드 이벤트 메서드에서 this.touch.initiated를 false로 설정하세요. 이벤트를 플레이어 구성 요소에 전달합니다. 오디오의 currentTime 값을 올바른 값으로 설정합니다. 매개변수는 pencent
진행률 표시줄에 클릭 이벤트를 추가하고, this._offset(e.offsetX)를 호출하고, 이벤트
created(){ this.touch = {}; }, methods:{ progressTouchStart(e){ this.touch.initiated = true; this.touch.startX = e.touches[0].pageX; this.touch.left = this.$refs.progress.clientWidth; }, progressTouchMove(e){ if(!this.touch.initiated){ return; } let deltaX = e.touches[0].pageX - this.touch.startX; let offsetWidth = Math.min(this.$refs.progressBar.clientWidth - progressBtnWidth,Math.max(0,this.touch.left + deltaX)); this._offset(offsetWidth); }, progressTouchEnd(e){ this.touch.initiated = false; this._triggerPercent(); }, progressClick(e){ const rect = this.$refs.progressBar.getBoundingClientRect(); const offsetWidth = e.pageX - rect.left; this._offset(offsetWidth); // this._offset(e.offsetX); this._triggerPercent(); }, _offset(offsetWidth){ this.$refs.progress.style.width = `${offsetWidth}px`; this.$refs.progressBtn.style[transform] = `translate3d(${offsetWidth}px,0,0)`; }, _triggerPercent(){ const barWidth = this.$refs.progressBar.clientWidth - progressBtnWidth; const percent = this.$refs.progress.clientWidth / barWidth; this.$emit("percentChange",percent) } },
를 전달합니다. 이 글은 "Vue.js 프론트엔드 구성 요소 학습" 튜토리얼"로 구성되어 있으며, 누구나 배우고 읽을 수 있습니다.
vue.js 구성 요소에 대한 튜토리얼을 보려면 특별한 vue.js 구성 요소 학습 튜토리얼을 클릭하여 학습하세요.
더 많은 Vue 학습 튜토리얼을 보려면 특별 주제 "Vue Practical Tutorial"을 읽어보세요.
위 내용은 제가 여러분을 위해 정리한 내용입니다. 앞으로 도움이 되길 바랍니다.
관련 기사:
vue.js의 mint-ui에 캐러셀 차트를 통합하는 방법
부모 노드가 선택되면 비활성화된 하위 노드도 선택되도록 Jstree에서 구현하는 방법
위 내용은 vue-music에서 Player 구성 요소를 사용하는 방법에 대한 지침의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!