uni-app中使用subNVue和制作带video的swiper

最近在做一个手机端的商城项目,框架使用uni-app,其中有一个类似于淘宝的商品首页轮播图效果,轮播图可以是视频也可以是图片;本来以为是一个很简单的功能,毕竟uni-app自带了swiper标签。直接判断使用就行,谁知道后来踩坑无数(无论是百度还是cloud社区都没有很好的文档),用了两天时间才解决;下面是我的解决过程。

一、video出现的问题

在真机调试中,video如果放在swiper中便会出现层级过高的问题,遮挡导致轮播不能滑动;这是因为在uni-app中为了性能考虑,video使用了原生组件,在编译中会遮挡住所有页面元素并且无法调整;uni-app官方给出的解决办法有三种
1.使用cover-image
2.使用nvue页面
3.使用subnvue
方法一原理上可行但有很大局限,具体可参考官方文档
方法二由于nvue语法还是和vue有所差异,包括只能使用flex布局,无法使用任何公共js和css,当页面结构较为复杂时非常麻烦,而且对于本文只需要做一个轮播而言没有必要,所以综合考虑使用subnvue

二、subnvue页面搭建

前半部分官方文档说明的还是非常仔细的:
首先在需要subnvue的页面中新建一个文件夹,文件夹中放置subnvue文件如图:
新建的subnvue文件为nvue格式
第二步:在pages.json中注册subnvue;以我的文件sp_details.vue为例,在pages.json中找到该文件,在其配置文件的“app-plus”属性中的“titlenview”同级,加入subnvue属性,如图:
在这里插入图片描述
具体的属性可以去官方文档中查看
第三步:在sp_details.vue中使用
在需要加入subnvue的页面的mounted函数中加入这段代码:

mounted() {
			const subNvue = uni.getSubNVueById('concat');//初始化subnvue对象 'concat'为pages.josn中注册时的唯一标识
			subNvue.show();//显示subnvue;更多方法请·查看官方文档
		},

下面是我的subnvue中的轮播页面(图片加视频)

<template>
	<div class="header">

		<swiper class="swiper" :indicator-dots="indicatorDots" circular :autoplay="autoplay" :interval="interval" :duration="duration"
		 @change="get_current">
			<swiper-item v-for="(item,i) of mybanner" :key='i'>
				<!-- 判断:当alt为1时显示视频,其余显示图片 -->
				<video :src="item.url" id="myVideo" controls enable-progress-gesture='false' class="myvideo" v-if="item.alt == 1"></video>
				<image class="myimg" :src="item.url" mode="" v-else></image>

			</swiper-item>

		</swiper>

	</div>
</template>
<script>
</script>
<style>
	.header {
		width: 750rpx;
		height: 750rpx;
	}

	.swiper {
		width: 750rpx;
		height: 750rpx;
	}

	.myvideo {
		width: 750rpx;
		height: 750rpx;
	}

	.myimg {
		width: 750rpx;
		height: 750rpx;
	}
</style>

css因为害怕有不可预知的问题,所以写的比较傻
完成到此,基本的subnvue显示是可以了,但是实际应用中肯定是要从服务器拿数据,而本文的坑才刚刚开始

三、和父文件传输数据

根据官方文档,推荐使用uni. e m i t , u n i . emit,uni. emit,uni.on来发送,接收数据,
注意:使用uni. o n 监 听 接 收 数 据 时 , 需 要 在 o n U n l o a d 函 数 中 及 时 卸 载 该 监 听 函 数 u n i . on监听接收数据时,需要在onUnload函数中及时卸载该监听函数uni. ononUnloaduni.off
在数据传输时,可能会出现这种情况:subnvue中数据接收到了,也能打印出来,但是页面却没有正确显示;开始时我认为可能因为是异步函数,导致页面渲染完成后才拿到数据,因此进行了无数次调试,最终发现调试代码在ios真机运行时可以正确渲染数据,但在安卓真机调试时一直都是只有第一次打开包含subnvue的页面时才能正确显示,退出后再次打开的情况是数据可以打印出来,页面没有渲染。翻遍了官方文档和论坛也没有好的解决办法;好在nvue界面和vue界面公用内存,所以在安卓机上只能使用uni.getStorageSync方法拿取数据;
下面是我的两个文件间的数据传递代码
父文件:

//向子页面nvue子页面传输数据(ios可用)
			to_nvue(){
				let _this = this;
				if(this.banner){
					uni.$emit('lunbo',{
						mybanner:_this.banner
					})
				}
				
			},


this.$.set_data('banner',this.banner)//向内存中存入数据,安卓可用
//(this.$.set_data是封装的uni.getStorageSync,效果相同,方便记忆)

subnvue文件:

created() {
			//this.listen()
			this.banner = uni.getStorageSync('banner') //在安卓中uni-app的数据传输不可用,暂时用原始方法
		},
		onShow() {
			//ios中数据传输可用
			this.getbanner()
		},
		onUnload() {
			uni.$off('lunbo')
		},
		methods: {
			getbanner() {
				uni.$on('lunbo', (res) => {
					this.$nextTick(function() {
						this.mybanner = res.mybanner;
					})
					console.log('获取轮播传值', this.mybanner)
				})

			},

		}

经过测试,成功!!
不得不吐槽,uni-app的官方文档还有很多不足之处,踩坑是常态。
ok告辞!

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值