实现效果如图:参考得到app交互,音频课程返回时,app下方展示悬浮窗口播放,可暂停、播放、关闭,点击可返回至音频文章查看文章。关闭app,再进入有缓存上次音频课程,可点击继续播放。上滑显示悬浮框,下滑隐藏悬浮框。

原生子窗体
subNVues 是 vue 页面的原生子窗体。用于解决App中 vue 页面中的层级覆盖和原生界面灵活自定义用的。它不是全屏页面,也不是组件,就是一个原生子窗体。它是一个 nvue 页面,使用 weex 引擎渲染,提供了比 cover-view、plus.nativeObj.view 更强大的原生排版能力,方便自定义原生导航或覆盖原生地图、视频等。
详细配置见这个:原生子窗体
请详读:subNVues 开发指南
如何获取原生子窗体实例及实例方法,见这篇:subNVue原生子窗体
请先熟读:如何配置 — 开发指南 — 实例及方法
解决方案
1、在需要展示的页面增加原生子窗体配置
{
"path": "pages/course/course",
"style":{
"app-plus":{
"subNVues":[{
"id": "course-bgAudio",
"path": "pages/subNVue/bgAudio",
"style": {
"width": "710rpx",
"height": "100rpx",
"bottom": "30rpx",
"margin": "auto",
"background": "transparent"
}
}]
}
}
},
注意:
id 需唯一不能重复;
margin: auto; 代表左右居中。
path 代表子窗体页面路径。我们这个需求都是要一样的窗口展示,所以可以共用一个 nvue 页面。页面路径指南上有说,只要可以正确引入即可。
2、在 pages/subNVue/bgAudio.nvue 页面编写自己的页面样式及代码逻辑即可,这个就不多说了。
3、上滑滚动、下滑隐藏。这里我们接可以写一个 mixin - submixin.js
export const submixin = {data() {return {curTop: 0}},methods: {showSubOrNot(subId) {if(!uni.getStorageSync('curArticle')) {const _sub = uni.getSubNVueById(subId + '-bgAudio')_sub.hide()}else{const _sub = uni.getSubNVueById(subId + '-bgAudio')_sub.show()}},pageScroll(subId, top) {if(!uni.getStorageSync('curArticle')) returnconst _sub = uni.getSubNVueById(subId + '-bgAudio')top > this.curTop ? _sub.hide() : _sub.show()this.curTop = top}}
}
4、那么如何使用呢?
// 1、引入submixin
import { submixin } from '@/mixins/submixin.js'
// 2、注册mixins
mixins:[submixin],
// 3、onShow的时候控制sub窗口展示与否的逻辑
// 4、onPageScroll的时候控制sub窗口滚动显示的逻辑
onShow() {this.showSubOrNot('course')
},
onPageScroll(top) {this.pageScroll('course', top.scrollTop)
},
业务逻辑处理,肯定是需要结合 vuex 状态管理了。
踩坑点
1、获取sub窗口实体的方法易踩坑:
- uni.getSubNVueById(subNvueId):通过
ID
获取subNVues
原生子窗体的实例。* uni.getCurrentSubNVue():在一个subnvue窗体的nvue页面代码中,获取当前subNVues
原生子窗体的实例。我刚开始为了简便不写sub窗口的id,以为可以使用 uni.getCurrentSubNVue() 任意获取当前页面的子窗体实例,但是好像不是这样的,这样用的话,就很容易卡死不动。不知道为啥,后来认真看了官网上对 2 种获取实例的方法描述。uni.getCurrentSubNVue() 说的是在一个subnvue窗体的nvue页面代码中,获取当前subNVues
原生子窗体的实例。所以猜到可能是这里的问题,然后换成 uni.getSubNVueById(subNVueId) 之后就 ok 了。具体原因不详,只能说是个踩坑点。
2、不知道是否有设置公共的子窗体的配置,查了一下,没找到。
目前我是需要悬浮窗体播放的几个页面,就加了 子窗体
的配置,不需要的不加即可。
不过也确实应该是这样,总不可能所有页面都放子窗体,对用户也不那么友好。看得到也是在个别与音频播放相关和tabbar列表的页面加了悬浮窗体播放,其他位置就没加。
通过这个原生子窗体感觉就可以做很多事情了,比如这篇博客说的这个:视频聊天,可以了解下:uniapp 使用原生子窗体进行视频聊天
PS:其实之前就想做这个东西,之前研究的是通过 Html5+ 的接口:plus.webview.create 去做这个事情,也可以实现置顶悬浮,但是那个悬浮窗口的样式包括业务逻辑就不好控制了,研究了一下也没有很好的解决方案。后来看到这个原生子窗体,感觉挺可以,一试确实可以,感觉还行。
最后
最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。
有需要的小伙伴,可以点击下方卡片领取,无偿分享