共计 2909 个字符,预计需要花费 8 分钟才能阅读完成。
文章概述
本次的文章次要是对于后面的聊天输入框的一个补充,对于有多种要求的开发者而言,能够借鉴本文实现高度定制化的扩大面板
聊天输入框扩大面板的实现
1. 为何要扩大面板
对于聊天输出而言,咱们不可能把所有的业务都搬到一个输入框内,也不可能把所有的操作都搬到输入框内,因而咱们很有必要去实现一个扩大面板,并且提供一个简略易用的操作逻辑,比方下图。
2. 内置的表情面板
在 demo 中,因为聊天输入框的须要,咱们内置了一个表情面板,在 components/ChatInputDrawer 目录中,咱们当初来看看其中的实现代码
<view class="face-drawer">
<scroll-view
v-if="currentPackage == 0"
class="face-drawer__scroll"
scroll-y
>
<view key="emoji" class="face-drawer-scroll-ctx">
<view
v-for="(item,index) in faceList"
class="face-drawer__scroll-item"
@click="$emit('emoji', item)"
>
<text
class="face-drawer__scroll-item-image"
>{{item}}</text>
</view>
<view
class="face-drawer__scroll-item-holder"
></view>
</view>
</scroll-view>
</view>
因为咱们曾经在聊天输入框中实现好了高度自适应,因而咱们这里不须要做过多的解决,咱们能够间接实现面板的逻辑,然而重点在于咱们怎么通知父级组件去发送数据,在这里扩大面板提供了一个很简略的思路如下:
<view key="emoji" class="face-drawer-scroll-ctx">
<view
v-for="(item,index) in faceList"
class="face-drawer__scroll-item"
@click="$emit('emoji', item)"
>
<text
class="face-drawer__scroll-item-image"
>{{item}}</text>
</view>
<view
class="face-drawer__scroll-item-holder"
></view>
</view>
在这里咱们通过事件反馈的形式,将须要发送的数据提供给父级组件,父级组件方面承受并且解决的代码如下:
<drawer-face
v-if="faceMode"
@emoji="text += $event;showText = text;"
@tipface="$emit('sendFace', $event)"
></drawer-face>
// 发送表情
async sendFace ({url}) {let V2TIMMessageManager = this.$txim.getMessageManager()
let v2TIMMessage = V2TIMMessageManager.createFaceMessage(0, { faceUrl: url})
try {let ret = await V2TIMMessageManager.sendMessage(v2TIMMessage, this.receiver)
console.log(ret)
this.HistoryMessageToChatLog([ret.data])
} catch (e) {this.$utils.toast('发送失败')
}
await this.$nextTick()
this.$refs.chatLayout.scrollToBottom()},
这样咱们就能够很简略的实现一个扩大面板,并且将面板内的事件传递进来,从而实现发送表情的性能
3. 更多功能的扩大面板
当然,下面的例子仅仅是内置的一个表情面板,个别状况下咱们还须要发送图片,音视频,发红包等业务逻辑,因而咱们须要一个更多功能的扩大面板,在这里咱们有内置一个 extra 面板,须要开发者自行实现逻辑,该面板对应的文件为 components/ChatInputDrawer/extra.vue。
3.1 扩大项配置
在这里,扩大面板采纳 json 配置图标,题目,命令的形式,确定如何去实现每一个扩大的性能,具体配置如下
data () {
return {
fnList: [{ name: 'image', title: '相册', icon: '../static/icon_btn_image.png'},
{name: 'camera', title: '拍摄', icon: '../static/icon_btn_camera.png'},
{name: 'voip', title: '视频通话', icon: '../static/icon_btn_voip.png'},
{name: 'location', title: '地位', icon: '../static/icon_btn_location.png'},
{name: 'redpaper', title: '红包', icon: '../static/icon_btn_redpaper.png'},
{name: 'transfer', title: '转账', icon: '../static/icon_btn_transfer.png'},
{name: 'use', title: '名片', icon: '../static/icon_btn_use.png'},
{name: 'file', title: '文件', icon: '../static/icon_btn_file.png'},
]
}
},
对于点击事件的反馈,代码是这样的,开发者在外层监听之后能够依据 fn 执行对应的业务解决
clickItem (item) {console.log(item)
this.$emit('clickFn', item)
}
3.2 扩大项性能实现
下面咱们说到了,是通过事件的反馈实现的 fn 传递,所以咱们须要在父级组件去监听事件,具体操作如下
<drawer-extra
v-if="extraMode"
@clickFn="onClickExtraFn"
></drawer-extra>
这里咱们监听了 clickFn 事件,所以咱们须要在 onClickExtraFn 中实现对应的页面,这里开发者能够查看 demo 中的源码,不过多赘述,只以发送图片作为例子
onClickExtraFn({name}) {switch(name) {
case 'image':
uni.chooseImage({success: ({ tempFilePath}) => {
// 这里抉择实现,须要告诉父级发送图片信息
this.$emit('sendImage', { filePath: tempFilePath})
}
})
break
}
}
我的项目开源地址及交换群
我的项目成品成果查看:请点击我的项目引言
我的项目开源地址:https://gitee.com/ckong/Zhimi…
Uniapp 开发交换群:755910061