💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[toc] # 3.9 弹幕组件开发(二) - 置于底部功能 ## 3.9.1 使用scroll-view组件实现弹幕布局 ``` <!-- 弹幕 --> <view style="position: fixed; bottom:120rpx; left: 0; right:0; "> <scroll-view scroll-y="true" style="width: 520rpx; height: 300rpx;" scroll-with-animation class="pl-3"> <view class="flex justify-start align-center rounded p-2" style="background-color: rgba(255,255,255,0.2);"> <text class="font-md text-danger">昵称:</text> <text class="font-md text-white">九月直播666</text> </view> </scroll-view> </view> ``` ## 3.9.2 将弹幕封装成组件 1. 在components的live文件夹内创建f-danmu.vue组件 2. 将live.nvu组件中弹幕的代码剪切到f-danmu.vue组件 3. 在live.nvue组件组件进行引入,注册,并使用 f-danmu.vue组件的内容 ``` <template> <view style="position: fixed; bottom:120rpx; left: 0; right:0; "> <scroll-view scroll-y="true" style="width: 520rpx; height: 300rpx;" scroll-with-animation class="pl-3"> <view class="flex justify-start align-center rounded p-2" style="background-color: rgba(255,255,255,0.2);"> <text class="font-md text-danger">昵称:</text> <text class="font-md text-white">九月直播666</text> </view> </scroll-view> </view> </template> <script> </script> <style> </style> ``` live.nvue组件的内容 ``` <template> <view class="page"> <!-- 直播内容 --> <video class="flex-1" src="http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8" autoplay :controls="false"></video> <!-- 头部 --> <view style="position: fixed; left: 0; right: 0;" :style="{top : `${statusBarHeight}px`}"> <!-- 个人信息|观看详细信息 --> <view class="px-2 flex justify-between" style="height:80rpx;"> <!-- 个人信息 --> <view style="width: 325rpx; background-color: rgba(0,0,0,0.4);" class="flex align-center rounded-circle"> <view class="p"> <image src="../../static/tabbar/min.png" style="width: 70rpx; height: 70rpx;" class="rounded-circle"></image> </view> <!-- 昵称与浏览量 --> <view class="flex-1 flex flex-column justify-center"> <text class="text-white font">昵称</text> <text class="text-white font-sm">100</text> </view> <!-- 关注按钮 --> <view class="rounded-circle flex align-center bg-danger justify-center" style="width: 70rpx; height: 70rpx;"> <text class="text-white">+</text> </view> </view> <!-- 观看情况 --> <view style="width: 325rpx; background-color: rgba(0,0,0,0.4);" class="flex align-center rounded-circle"> <!-- 观看的用户 --> <scroll-view scroll-x="true" class="flex-1 flex"> <view class="p" v-for="(item,index) in 20" :key="index"> <image src="../../static/tabbar/min.png" style="width: 70rpx; height: 70rpx;" class="rounded-circle"></image> </view> </scroll-view> <!-- 观看人数 --> <view class="rounded-circle flex align-center bg-danger justify-center" style="width: 70rpx; height: 70rpx;"> <text class="text-white font-sm">1000</text> </view> </view> </view> <!--金币--> <view class="px-2 my-2" style="height: 80rpx;"> <view style="width: 325rpx; background-color: rgba(0,0,0,0.4);" class="flex align-center rounded-circle"> <view class="p"> <text class="text-warning">金币</text> </view> <view class="flex-1 flex flex-column justify-center"> <text class="text-white font">100</text> </view> </view> </view> <!-- 礼物 --> <f-gift ref="gift"></f-gift> </view> <!-- 弹幕 --> <f-danmu></f-danmu> <!-- 底部评论..等 --> <view class="position-fixed right-0 bottom-0 left-0 flex align-center justify-between" style="height: 120rpx;"> <view class="px-2" > <view @click="openInput" style="height:80rpx;border-radius: 100rpx;background-color: rgba(255,255,255,0.12);" class="flex justify-center px-3 align-center"> <text class="text-white font">说点什么...</text> </view> </view> <view class="flex align-center"> <view style="height:80rpx; width: 80rpx; background-color: rgba(255,255,255,0.12);" class="flex mr-1 justify-center rounded-circle align-center"> <text class="iconfont text-white" style="font-size: 40px; ">&#xe633;</text> </view> <view style="height:80rpx; width: 80rpx;" class="flex mr-1 justify-center rounded-circle align-center bg-warning"> <text class="iconfont">&#xe67c;</text> </view> <view style="height:80rpx; width: 80rpx; background-color: rgba(255,255,255,0.12);" class="flex mr-1 justify-center rounded-circle align-center"> <text class="iconfont text-white">&#xe7cd;</text> </view> <view style="height:80rpx; width: 80rpx; background-color: rgba(255,255,255,0.12);" class="flex mr-1 justify-center rounded-circle align-center"> <text class="iconfont text-white">&#xe607;</text> </view> </view> </view> <!-- 输入框弹出层 --> <uni-popup type="bottom" ref="input"> <view class="bg-white flex align-center px-3" style="height: 120rpx;"> <input placeholder="说点什么呢..." v-model="content" type="text" style="height: 80rpx;" class="border rounded flex-1 px-3 font-md"> <view class="bg-main flex ml-3 align-center py-2 rounded px-2 justify-center" @click="submit"> <text class="font text-white">发送</text> </view> </view> </uni-popup> </view> </template> <script> import fGift from "../../components/live/f-gift.vue" import uniPopup from "../../components/uni-ui/uni-popup/uni-popup.vue" import fDanmu from "../../components/live/f-danmu.vue" export default { data(){ return { statusBarHeight : 0, content : "" } }, components: { fGift, uniPopup, fDanmu }, onLoad(){ //获取通知栏的高度 let res = uni.getSystemInfoSync(); this.statusBarHeight = res.statusBarHeight; }, mounted(){ setInterval(()=>{ this.$refs.gift.send({ username : "发送人", avatar : "", gift_name : "蛋糕", gift_image : "/static/gift/3.png", num : 1 }) },3000) }, methods:{ openInput(){ this.$refs.input.open() }, submit(){ this.$refs.input.close() } } } </script> <style> .page{ flex : 1; } </style> ``` ## 3.9.3 动态模拟弹幕的数据 1. 创建模拟的数据 2. 使用v-for进行动态渲染 ``` <template> <view style="position: fixed; bottom:120rpx; left: 0; right:0; "> <scroll-view scroll-y="true" style="width: 520rpx; height: 300rpx;" scroll-with-animation class="pl-3"> <view v-for="(item,index) in list" :key="index" class="flex justify-start align-center rounded p-2 mb-2" style="background-color: rgba(255,255,255,0.125);"> <text class="font-md text-danger">{{item.name}}</text> <text class="font-md text-white">{{item.content}}</text> </view> </scroll-view> </view> </template> <script> export default { data(){ return { list : [ { id : 1, name : "昵称", content : "九月直播666" }, { id : 2, name : "昵称", content : "九月直播666" }, { id : 3, name : "昵称", content : "九月直播666" } ] } } } </script> <style> </style> ``` ## 3.9.4 实现置于底部功能 1. 由于弹幕的数据都是从后端传递过来了,所以我们在这只是先进行模拟一下 ``` <script> export default { data(){ return { list : [ { id : 1, name : "昵称", content : "九月直播666" }, { id : 2, name : "昵称", content : "九月直播666" }, { id : 3, name : "昵称", content : "九月直播666" } ] } }, mounted(){ //由于弹幕的数据都是从后端传递过来了,所以我们在这只是先进行模拟一下 let id = 1; setInterval(()=>{ this.list.push({ id : id, name : "昵称" + id, content : "九月直播666" }) id++; },1000) } } </script> ``` 2. 实现置于底部功能 ``` <template> <view style="position: fixed; bottom:120rpx; left: 0; right:0; "> <scroll-view :scroll-into-view="scrollIntoView" scroll-y="true" style="width: 520rpx; height: 300rpx;" scroll-with-animation class="pl-3"> <view :id="'danmu' + item.id" v-for="(item,index) in list" :key="index" class="flex justify-start align-center rounded p-2 mb-2" style="background-color: rgba(255,255,255,0.125);"> <text class="font-md text-danger">{{item.name}}:</text> <text class="font-md text-white">{{item.content}}</text> </view> </scroll-view> </view> </template> <script> export default { data(){ return { scrollIntoView : "", list : [ ] } }, mounted(){ let id = 1; //由于弹幕的数据都是从后端传递过来了,所以我们在这只是先进行模拟一下 setInterval(()=>{ this.list.push({ id : id, name : "昵称" + id, content : "九月直播666" }) //调用置于底部方法 this.toBottom(); id++ },1000) }, methods:{ toBottom(){ setTimeout(()=>{ let len = this.list.length; if(len > 0 && this.list[len - 1]){ this.scrollIntoView = 'danmu' + this.list[len - 1].id; } },200) } } } </script> ```