使用video组件时,弹出框总是在video下方。
需要的效果如图:
解决方法:
使用subNvue子窗体:
1。在使用video组件的页面同级建立一个子目录subNVue,创建一个DialogNet.nvue页面,
<template>
<view class="my-confirm-notice" id="netDialog">
<view class="confirm-content-wrap1">
<!-- 标题 -->
<div class="unipop__ui_tit">
<text class="unipop__ui_tit_text">查询条件</text>
<image src="../../../static/images/workbeach/icon_close.png" class="close_image" @click="close()"></image>
</div>
<!-- 内容 -->
<div class="content_margin">
<div class="flex_row_center label_text label_margin">
<text style="font-size: 16px;">实体名称:</text>
<input type="text" class="inputStyle" placeholder="实体名称" @input="onKeyInput" :value="userName" >
</div>
</div>
<div v-if="btns" class="unipop__ui_btns">
<text v-for="(item,index) in btns" :key="index" class="btn" :style="item.style" @tap="btnTaped(item)">{{item.text}}</text>
</div>
</view>
</view>
</template>
<script>
export default {
data() {
return {
btns:[
{
text: '重置',
style: 'color: #ffffff',
},
{
text: '确定',
style: 'color: #ffffff',
}
],
selectCondition:{},
userName:'',
}
},
mounted() {
console.log('mounted==================1111111111111111')
},
methods: {
close(){
this.userName = '';
this.selectCondition = {};
const subNvue = uni.getSubNVueById('netDialog');
subNvue.hide();
},
btnTaped(item) {
console.log(item);
if(item.text == '重置') {
this.userName = '';
this.selectCondition = {};
} else {
uni.$emit('receiveData',this.selectCondition);
this.close();
}
},
onKeyInput(event) {
this.userName = event.detail.value;
this.selectCondition['nickName'] = this.userName;
},
}
}
</script>
<style lang="scss">
.my-confirm-notice {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
// z-index: 19998;
/* 这里防止当用户长按屏幕,出现的黑色背景色块,以及 iPhone 横平时字体的缩放问题 */
// -webkit-text-size-adjust: 100%;
// -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
display: flex;
align-items: center;
justify-content: center;
}
.confirm-content-wrap1 {
position: relative;
left: 0;
right: 0;
width: 675rpx;
/* #ifndef APP-PLUS-NVUE */
height: auto;
margin: 0 auto;
user-select: none;
/* #endif */
background-color: white;
border-radius: 10px;
// z-index: 999;
}
.unipop__ui_tit {
background-color: #074498;
width: 675rpx;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
}
.unipop__ui_tit_text {
color: white;
text-align: center;
line-height: 44px;
width: 675rpx;
font-size: 16px;
}
.close_image {
z-index: 100;
position: absolute;
/* #ifndef APP-PLUS-NVUE */
float: right;
/* #endif */
right: 10px;width:30px;height: 30px;
}
.unipop__ui_btns{
height: 80px;
justify-content: space-around;
display: flex;
flex-direction: row;
padding-left: 20px;
padding-right: 20px;
align-items: center;
}
.btn {
width: 80px;
height: 34px;
background-color: #074498;
line-height: 34px;
text-align: center;
font-size: 13px;
border-radius: 6rpx;
}
.content_margin {
padding: 15px 0px 5px 0px;
}
.flex_row_center {
display: flex; flex-direction: row; justify-content: center; align-items: center;
}
.label_text {
font-size: 28rpx;color: #555555;
}
.label_margin {
margin-top: 36rpx;
}
.inputStyle {
border: #bababa 0.5px solid; width: 169px;height: 40px;
/* #ifndef APP-PLUS-NVUE */
box-sizing: border-box;
/* #endif */
font-size: 14px; color: #aaaaaa; padding: 3px 5px;
}
.top_level {
position: fixed;z-index: 100;width: 675rpx;
}
</style>
2。在page.json文件中配置subNVues,
{
"path": "pages/netcheck/NetCheckList",
"style": {
"navigationBarTitleText": "远程巡店",
"enablePullDownRefresh":true,
"app-plus": {
"pullToRefresh": {
"style":"circle",
"offset": "88px"
},
"subNVues":[{
"id": "netDialog", // 唯一标识
"path": "pages/netcheck/subNVue/DialogNet", // 页面路径
"type": "popup", //原生子窗口内置样式,可取值:'popup',弹出层;"navigationBar",导航栏
"style": {
"position":"fixed",
"background":"transparent"
}
}]
}
}
},
3。显示子窗体
const subNvue = uni.getSubNVueById('netDialog');
subNvue.show();
4。关闭子窗体,在弹出的子窗体上点击关闭按钮或确定按钮关闭窗体
const subNvue = uni.getSubNVueById('netDialog');
subNvue.hide();
5。在.nvue页面获取input输入框的值:
onKeyInput(event) {
this.userName = event.detail.value;
this.selectCondition['nickName'] = this.userName;
},
6。向video页面传值:点击“确定”按钮,将获取到的input中的值,传到vue页面:
btnTaped(item) {
console.log(item);
if(item.text == '重置') {
this.userName = '';
this.selectCondition = {};
} else {
uni.$emit('receiveData',this.selectCondition);
this.close();
}
},
7。vue页面接收nvue的传值
onLoad() {
uni.$on('receiveData',(options)=>{
console.log('onLoad====receiveData',JSON.stringify(options));
this.searchCondition = options;
})
},
整体代码:
代码中包含的知识点:
1。上拉加载(自定义了错误处理)
2。下拉刷新
3。使用subNVue子窗体,解决video层级高的问题
4。vue与nvue之间的通讯;
<template>
<view>
<uni-nav-bar title="远程巡店" backgroundColor="#074498" color="white" fixed="true"
statusBar='true' @clickRight="searchPerson">
<view slot="right" class="flex_vcenter">
<image src="../../static/images/workbeach/icon_search.png" class="imgSize"></image>
</view>
</uni-nav-bar>
<uni-list :border="false">
<UniListItemCustomer v-for="(item,index) in deviceList" :key="index" :border="false" direction="column" class="item" clickable @click="gotoDetail(item)">
<template v-slot:header>
<view>
<video id="myVideo" :src="src" class="video_width"
@error="videoErrorCallback" controls
autoplay="false" direction="90" objectFit="fill">
<cover-image src="../../static/images/check/icon_full.png" class="cover_img_common right_20"></cover-image>
<cover-image src="../../static/images/check/icon_crop.png" class="cover_img_common right_65"></cover-image>
<cover-image src="../../static/images/check/icon_replay.png" class="cover_img_common right_110"></cover-image>
</video>
</view>
</template>
</UniListItemCustomer>
</uni-list>
<uni-load-more :status="more" :contentText="contentText" @clickLoadMore="more=='error'?getPersonelList():''"></uni-load-more>
</view>
</template>
<script>
import ApiService from './service.js'
import Tips from '../../utils/tips.js'
import UniListItemCustomer from '../../components/uni-list-item/uni-list-item-customer.vue'
export default {
components:{
UniListItemCustomer
},
data() {
return {
deviceList:[],
ruleName:'',
searchCondition:{},
more:'more',
pageNum:1,
pageSize:10,
contentText: {
contentdown: '上拉加载更多',
contentrefresh: '正在加载中',
contentnomore: '没有更多数据了',
contenterror: '数据异常,请点击此处重新加载'
},
reLoad:false,
src: 'https://cmgw-vpc.lechange.com:8890/LCO/6F0E7A3PAGC76B8/0/0/20211110T095117/3dfad2653e6e0010df9d5cf00739ae13.m3u8?proto=https',
}
},
created() {
this.getPersonelList();
console.log('created');
},
mounted() {
console.log('mounted');
},
onReady() {
this.videoContext = uni.createVideoContext('myVideo')
},
onLoad() {
uni.$on('receiveData',(options)=>{
console.log('onLoad====receiveData',JSON.stringify(options));
this.searchCondition = options;
})
},
onReachBottom() {
console.log('onReachBottom');
if(this.more != 'noMore') {
this.more = 'more';
this.getPersonelList();
}
},
onPullDownRefresh() {
console.log('onPullDownRefresh');
this.reLoad = true;
this.pageNum = 1;
this.getPersonelList();
},
methods:{
goBack() {
uni.navigateBack();//跳转到上一个页面
},
searchPerson() {
const subNvue = uni.getSubNVueById('netDialog');
subNvue.show();
},
onKeyInput(event) {
this.ruleName = event.target.value;
this.searchCondition = {'roleName':this.ruleName};
},
async getPersonelList() {
this.searchCondition['pageSize'] = this.pageSize;
this.searchCondition['pageNum'] = this.pageNum;
this.more = 'loading';
let res = await ApiService.getPersonnelList(this.searchCondition);
// console.log('getPersonelList',JSON.stringify(res));
if(res.success) {
if(res.data.code == 200) {
this.deviceList = this.reLoad?res.data.data.rows:this.deviceList.concat(res.data.data.rows);
if(this.deviceList.length != res.data.data.total) {
this.pageNum += 1;
this.more = 'more';
} else {
this.more = 'noMore';
}
} else {
if(this.pageNum == 1) {
this.deviceList = [];
}
Tips.toast(res.data.msg);
this.more = 'error';
}
} else {
Tips.toast(res.message);
this.more = 'error';
}
if(this.reLoad) {
uni.stopPullDownRefresh();
this.reLoad = false;
}
},
gotoDetail(item) {
console.log(item)
uni.navigateTo({
url: 'personnelDetail?item='+JSON.stringify(item)
})
},
videoErrorCallback: function(e) {
uni.showModal({
content: e.target.errMsg,
showCancel: false
})
}
}
}
</script>
<style lang="scss" scoped>
@import '../../styles/base.scss';
page {
background: #f9f9f9;
overflow-x: hidden;
padding: 0;
}
.nav-style {
font-family: 'PingFangSC-Semibold', 'PingFang SC Semibold', 'PingFang SC';
height: 45px;
}
.status_style {
float: right;position: absolute;right: 35px;
font-size: 16px;
font-family: 'PingFangSC-Regular', 'PingFang SC';
}
.common_color {
color:#074498
}
.title_size {
font-size: 16px;
}
.status_color_use {
color: #73B703;
}
.status_color_forbidden {
color: #D9001B;
}
.item_text {
/* padding-top: 8px; */
font-family: 'PingFangSC-Regular', 'PingFang SC';
color: #333333;
font-size: 14px;
line-height: 25px;
}
.arrow_right {
width: 20px;
height: 25px;
float: right;
right: 20px;
position: absolute;
}
.item_content {
padding: 10px 0px 0px 0px;
display: flex;flex-direction: column;
}
.divider {
height: 0.5px;width: 100%; background-color: #dbdbdb;margin-top: 10px;
}
.flex_vcenter {
display: flex; align-items: center;
}
.item {
border-bottom: #f9f9f9 8px solid;
/* padding: 0px 15px 0px 15px; */
}
.video_width {
width: 100%;
z-index: 100;
}
.cover_img_common {
width: 25px; height: 25px;float: right;position: absolute;bottom: 15px;
}
.right_20 {
right: 20px;
}
.right_65 {
right: 65px;
}
.right_110 {
right: 110px;
}
.imgSize {
width: 25px; height: 25px;
}
</style>