在使用Vue3+Ts封装的微信消息播放组件时怎么停止上一次的声音播放
在我的上一篇博客(http://t.csdnimg.cn/LAQ4w)中,我们封装一个类似于微信消息播放的组件,但是会遇到一个问题,因为每一个实例化出来的组件都是单独的,里面的audio也是单独的,在我们点击另外一个组件播放声音时,我们会发现上一次播放的声音依旧在播放,导致两个声音重叠了,那我们应该怎么解决这个问题呢?
此时就要用到ref作为元素的Attribute,给每一个声音播放组件绑定一个相同的ref,这个我们可以拿到所有的声音播放器的实例;详情查询Vue3官网:https://cn.vuejs.org/api/built-in-special-attributes.html#refhttps://cn.vuejs.org/api/built-in-special-attributes.html#ref
另外我们还使用到另一个api——$el,详情请查看Vue3官网:
https://cn.vuejs.org/api/component-instance.html#elhttps://cn.vuejs.org/api/component-instance.html#el
这个属性可以让我们获取到ref定义的实例的真实dom元素
我们在点击元素时,把鼠标点击的event事件传递过来
<VoicePlaybackref="voiceRef":isSent="false"iconColor="#ffffff"backgroundColor="rgba(255 255 255 / 20%)":smallSize="5":middleSize="16":largeSize="28":duration="30"audioSrc="http://11111.mp3"@click.stop="(event:Event)=>{handlePlayAudio(event)}"
/>
在这里的event中有两个属性:
event.target:可以得到当前鼠标点击作用于哪个dom上面,它是具体到这个组件的子dom;
event.currentTarget:得到当前点击事件绑定的dom元素;
所以这里我们需要使用event.currentTarget刚好的找到当前声音播发器的组件,voiceRef.value是一个数组我们需要遍历他通过$el属性来找到当前鼠标点击的dom元素和哪一个ref实例.$el得到的dom相同,记录这个组件实例,在下一次播放声音时,停止上一次的声音播放。
// 点击播放器时,暂停上一次的声音播放
const handlePlayAudio = (event: Event) => {// 判断当前点击的声音播放的组件是不是与上次相同,如果相同,则return,不执行下面的代码if (lastVoiceRef.value && lastVoiceRef.value.$el == event.currentTarget) {return;} else {// 如果上一次的声音播放的组件存在,先暂停他的播放lastVoiceRef.value && lastVoiceRef.value.pauseVoice();}for (let i of voiceRef.value) {// 遍历所有的voiceRef绑定的实例,找到当前鼠标点击事件绑定的元素event.currentTarget在ref绑定的元素数组中的实例,赋给上一次的声音播放实例if (event.currentTarget == i.$el) {lastVoiceRef.value = i;}}
};