这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
一、audio标签的使用
1、Audio 对象属性
2、对象方法
二、效果
效果如下:
三、代码
代码如下: MusicPlayer.vue
1 2 3 4 5 6 7 8 9 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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | < template > < div class="music"> <!-- 占位 --> < div class="m_hold"> </ div > < div class="m_img"> < img :src="this.$parent.songNames[this.$parent.index].png" width="90px" :class="this.$parent.isRun"> </ div > <!-- 歌曲信息 --> < div class="m_text"> {{ this.$parent.songNames[this.$parent.index].name }} < div class="block" style="margin-top:5px"> < el-slider :v-model="value1"></ el-slider > </ div > </ div > <!-- 按钮 --> < div class="m_btn"> < a href="#" class="m_prev" @click="playLastSong()"></ a > < a href="#" class="m_play" @click="changeState()" v-show="this.$parent.isShow"></ a > < a href="#" class="m_pause" @click="changeState()" v-show="!this.$parent.isShow"></ a > < a href="#" class="m_next" @click="playNextSong()"></ a > </ div > <!-- 折叠功能 --> < div class="m_close" @click="changeCloseState()"> < a href=""></ a > </ div > </ div > </ template > < script > export default { name: 'MusicPlayer', data() { return { songName: '', value1:0 } }, methods: { changeState() { this.$emit("play") }, changeCloseState() { this.$emit("hello"); }, playNextSong() { this.$emit("nextSongs"); this.songName = this.$parent.songNames[this.$parent.index].name }, playLastSong() { this.$emit("lastSongs"); this.songName = this.$parent.songNames[this.$parent.index].name } }, watch: { }, mounted() { this.songName = this.$parent.songNames[this.$parent.index].name } } </ script > < style scoped> /* 关于播放器的样式 */ .music { width: 100%; height: 120px; background: black; /* 相对浏览器定位 */ position: absolute; left: 0px; bottom: 100px; border-bottom: 50px; /* 透明度 */ opacity: 0.8; /* 阴影值 */ box-shadow: 10px 15px 15px 1px black } .music .m_hold { float: left; width: 90px; height: 90px; } /* 调整音乐盒图片 */ .music .m_img { margin-top: 15px; margin-left: 10px; margin-right: 10px; /* 左浮动 */ float: left; width: 90px; height: 90px; border-radius: 50%; overflow: hidden; } /* 修改文字 */ .music .m_text { /* 左浮动 */ float: left; color: white; font-size: 20px; /* 字体加粗 */ font-weight: bold; margin-top: 25px; margin-left: 20px; margin-bottom: 10px; width: 25%; } /* 使得所有a标签一起移动 */ .music .m_btn { float: left; position: absolute; /* 绝对定位:防止歌曲名称过长,挤出div */ left: 40%; } /* 修改a标签 */ .music .m_btn a { width: 32px; height: 32px; float: left; margin-top: 50px; margin-left: 20px; background: url(@/assets/player_bg.png); } .music .m_btn .m_prev { background-position: -69px 0px; } .music .m_btn .m_next { background-position: -150px 0px; } .music .m_btn .m_play { background-position: -107px -5px; } .music .m_btn .m_prev:hover { background-position: -69px -32px; } .music .m_btn .m_next:hover { background-position: -150px -32px; } .music .m_btn .m_play:hover { background-position: -107px -47px; } .music .m_btn .m_pause { background-position: -292px -94px; } .music .m_btn .m_pause:hover { background-position: -334px -94px; } /* 还有一个悬停 没写 */ /* 设置最右边的关闭样式 */ .music .m_close { float: right; background: white; cursor: pointer; width: 23px; height: 100px; margin-top: 10px; background: url(@/assets/player_bg.png); } /* 设置最右边的关闭样式 */ .music_hide { float: left; background: white; cursor: pointer; width: 23px; height: 100px; margin-top: 2px; } .go { animation: bounce-in 2s linear infinite; } .come { animation: none; } @keyframes bounce-in { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .open-enter-active { animation: slide-in linear 0.5s; } .open-leave-active { animation: slide-in reverse linear 0.5s; } @keyframes slide-in { from { transform: translateX(-100%); } to { transform: translateX(0%); } } </ style > |
HideMusic.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | < template > < div class="music_hide" @click="changeCloseState()">< a href="#" class="m_open"></ a ></ div > </ template > < script > export default { name:'HidePlayer', methods:{ changeCloseState() { this.$emit("hello"); } } } </ script > < style scoped> .music_hide { float: left; background: url(@/assets/player_bg.png); cursor: pointer; width: 23px; height: 100px; margin-top: 10px; bottom: 100px; position: absolute; background-position-x: -45px; } </ style > |
MyPlayer.vue
1 2 3 4 5 6 7 8 9 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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | < template > < div > < transition name="open" mode="out-in"> < component v-bind:is="view" @hello="changeSlideState" @play="changePlayState" @lastSongs="lastSongs" @nextSongs="nextSongs"></ component > </ transition > < audio class="m_mp3" id="m_mp3" :src="this.songNames[this.index].Url" autoplay loop> </ audio > </ div > </ template > < script > import HidePlayer from '@/part/HidePlayer' import MusicPlayer from '@/part/MusicPlayer' export default { name: 'MyPlayer', data() { return { view: MusicPlayer, isClose: false, isShow: true, isRun: 'come', index: 0, songNum: 2, currentTime: '0:00', duration: '0:00', songNames: [ { id: 1, name: '张韶涵-篇章', Url: require('@/assets/张韶涵-篇章.mp3'), png: require('@/assets/篇章.png'), }, { id: 2, name: '爱就一个字 抒情版', Url: require('@/assets/爱就一个字 抒情版.mp3'), png: require('@/assets/爱就一个字.png'), }, { id: 3, name: '最伟大的作品-周杰伦', Url: require('@/assets/最伟大的作品-周杰伦.mp3'), png: require('@/assets/周杰伦.jpg'), }, { id: 4, name: '等你下课 (with 杨瑞代)-周杰伦', Url: require('@/assets/等你下课 (with 杨瑞代)-周杰伦.mp3'), png: require('@/assets/等你下课.png'), }, { id: 5, name: '告白气球-周杰伦', Url: require('@/assets/告白气球-周杰伦.mp3'), png: require('@/assets/告白气球.png'), }, { id: 6, name: '还在流浪-周杰伦', Url: require('@/assets/还在流浪-周杰伦.mp3'), png: require('@/assets/还在流浪.png'), }, ] } }, components: { HidePlayer, MusicPlayer }, methods: { changeSlideState() { this.isClose = !this.isClose; if (this.isClose) { this.view = HidePlayer; } else { this.view = MusicPlayer; } }, changePlayState() { if (!this.isShow) { this.isShow = true; this.isRun = "come"; document.getElementById("m_mp3").pause(); } else { this.isShow = false; this.isRun = "go"; var my_mp3 = document.getElementById("m_mp3"); my_mp3.play(); } }, nextSongs() { if (this.isShow) { this.isShow = false; this.isRun = "go"; } this.index = (this.index + 1) % this.songNum; }, lastSongs() { if (this.isShow) { this.isShow = false; this.isRun = "go"; } if (this.index == 0) { this.index = this.songNum - 1; } else { this.index = this.index - 1; } } }, mounted() { this.songNum = this.songNames.length; } } </ script > < style scoped> .open-enter-active { animation: slide-in linear 0.5s; } .open-leave-active { animation: slide-in reverse linear 0.5s; } @keyframes slide-in { from { transform: translateX(-100%); } to { transform: translateX(0%); } } </ style > |
四、难点解析
1、过渡动画的实现
参考了vue文档过渡&动画中多个组件的过渡(下面三份代码)
1 2 3 | < transition name="component-fade" mode="out-in"> < component v-bind:is="view"></ component > </ transition > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | new Vue({ el: '#transition-components-demo', data: { view: 'v-a' }, components: { 'v-a': { template: '< div >Component A</ div >' }, 'v-b': { template: '< div >Component B</ div >' } } }) |
1 2 3 4 5 6 7 | .component-fade-enter-active, .component-fade-leave-active { transition: opacity .3s ease; } .component-fade-enter, .component-fade-leave-to /* .component-fade-leave-active for below version 2.1.8 */ { opacity: 0; } |
因此分化出MusicPlayer.vue 和 HideMusic.vue,由此又产生了组件内通信的问题。
2、组件内通信
为什么会产生组件内的通信?原因在于:MusicPlayer组件和HidePlayer组件,只能有一个展示,但是在不展示的过程中,他的数据应该也是实时改变的。例如MusicPlayer组件上有播放按钮,如果不采用组件通信,那么MusicPlayer重新渲染的时候,播放按钮会回到最初的设定,是不符合逻辑的。所以需要采用组件内通信的方式。实现的方式也比较简单,子组件直接访问父组件的数据,子组件通过$emit调用父组件的方法,修改父组件的数据。
3、旋转动画的实现
首先,编写动画。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | .go { animation: bounce-in 2s linear infinite; } .come { animation: none; } @keyframes bounce-in { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } |
然后,动态绑定class,isRun两个值即为"go","come"。
1 2 3 | < div class="m_img"> < img :src="this.$parent.songNames[this.$parent.index].png" width="90px" :class="this.$parent.isRun"> </ div > |
本文转载于:
https://blog.51cto.com/u_15807146/5807883
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
__EOF__