最近准备给博客小程序添加一个留言板功能,考虑到如果只是纯文本留言有点过于简陋了,所以准备按照仿微信风格,在评论时可以添加emoji表情发送,实际上为了简化开发,原本找到了github一个插件WxEmojiView,可以快速引入项目实现emoji表情的渲染,但是由于几个缺点放弃了使用这个插件,首先这个插件实际上是用户选择emoji表情时转换成一串对应的字符串拼接到文本中,这样输入文本的显示效果我觉得不是很理想,第二点是插件坐着没有继续维护,所以担心某一天出问题不好处理,所以最终决定自己实现文本插入emoji表情的效果。我们可以先简单看下本篇文章最终要实现的效果:
我们既然要实现这个emoji表情的效果,那具体是什么样的业务逻辑呢。我这里将业务逻辑分成3个步骤:
-
下载emoji表情eif文件并使用eifBQJYTool工具进行解压得到emoji的表情文件。然后将图片上传到图片服务器中。 -
根据用户选择的emoji表情,选中对应emoji表情的字符串形式添加到输入文本中。 -
用户点击输入框右侧的表情按钮弹出浮层可以选择emoji表情,再次点击表情按钮或者点击发送按钮可以关闭浮层。
首先意义不没啥好说的,都是玩计算机的解压文件难不倒大家。至于eif文件和解压工具而我已经上传百度云,公众号回复emoji工具就可以得到下载链接。然后将图片上传图片服务器。首先刚才讲过了我们需要根据用户选择的emoji表情,选中对应emoji表情的字符串形式添加到输入文本中。所以首先需要在页面js文件的data中创建一个数组存储emoji表情的名称,再创建一个字符串存储emoji表情对应的字符串格式。不同的emoji字符串形式以-拼接。我们可以看下源码:
data: {
emoji: ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35'],
emojiChar: '😓-😡-😳-😁-😠-😪-😄-😄-😔-😒-😞-😖-😏-😥-😷-😚-😂-😉-😵-☺-😌-😣-😥-😭-😱-😰-😨-😍-😃-😊-😝-😋-🍓-☀-☁-☔'
},
http://www.oicqzone.com/tool/emoji/
下面我们先来设计页面效果,我们设计一个view置于屏幕底部,view中存在三个组件:input组件负责输入文本,表情按钮点击会弹出浮层以供用户选择emoji表情,发送按钮用于连接服务端保存留言数据。接着我们先看看页面布局:
<view class="message">
<form bindreset="cleanInput" class="sendMessage">
<input type="text" placeholder="留言内容.." value="{{message}}" bindinput='messageInput'></input>
<image class="add" src="/images/bq.png" bindtap='increase'></image>
<button type="primary" bindtap='send' form-type="reset" size="small" button-hover="blue">发送</button>
</form>
<view class='increased {{aniStyle?"slideup":"slidedown"}}' wx:if="{{increase}}">
<block wx:for="{{emoji}}" wx:key="index">
<view class="emoji-cell">
<image class="touch-active" data-id="{{index}}" bindtap="emojiChoose" src="https://pic.niyueling.cn/upload_avatar/2019/11/19/0/0/{{item}}.jpg"></image>
</view>
</block>
</view>
</view>
实际上看到布局代码可以发现emoji浮层我设置了一个wx:if属性,然后监听表情按钮的点击事件,在点击事件中更改increase的值,当increase值为true则浮层显示,当increase为false浮层隐藏。然后浮层显示时使用wx:for循环emoji表情数组,每循环一次可以得到文件名,根据我们图片服务器地址拼接成可访问的emoji表情url,放入image标签的src中。至于页面布局效果实际上就是使用flex布局,然后浮层显示隐藏加了个简单的动画效果:
@keyframes slidedown {
from {
transform: translateY(0);
}
to {
transform: translateY(100%);
}
}
.slidedown {
animation: slidedown 0.5s linear;
}
.slideup {
animation: slideup 0.5s linear;
}
@keyframes slideup {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
界面效果没有问题了,那下一步就需要来实现留言的功能了。实际上我们的需求很简单,就是文字和emoji表情结合,在我们选择emoji表情时,将emoji表情对应的字符串形式添加到输入文本中。首先我们需要在data中设置message参数保存输入文本,我们刚才已经在input输入框绑定了bindInput事件,可以监听文本输入。在用户输入文本就将文本值动态添加到data的message参数中,当用户选择emoji表情时将message已有的输入文本和对应的emoji表情的字符串形式进行拼接。然后input的value值显示的就是data中的message参数。这样就可以保证我们选择emoji表情时输入框可以显示。接下来我们看看js文件的关键代码:
data: {
message: '',
emoji: ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35'],
emojiChar: '😓-😡-😳-😁-😠-😪-😄-😄-😔-😒-😞-😖-😏-😥-😷-😚-😂-😉-😵-☺-😌-😣-😥-😭-😱-😰-😨-😍-😃-😊-😝-😋-🍓-☀-☁-☔'
},
//监听input值的改变
messageInput(res) {
this.setData({
message: res.detail.value
});
},
cleanInput() {
//button会自动清空,所以不能再次清空而是应该给他设置目前的input值
this.setData({
message: this.data.message
});
},
increase() {
this.setData({
increase: !this.data.increase,
aniStyle: true
});
},
emojiChoose: function(e) {
var index = e.target.dataset.id
var emojiArr = this.data.emojiChar.split('-');
this.setData({
message: this.data.message + emojiArr[index]
});
},
//点击空白隐藏message下选框
outbtn() {
this.setData({
increase: false,
aniStyle: true
});
},
send: function() {
this.setData({
increase: false
});
if(!this.data.message) {
$Toast({
content: '不能留言空消息!',
type: 'error'
});
} else {
//chatInfo 中 friendInfo 是作者信息,userInfo 是留言者信息也就是登陆者信息
var that = this;
var chatInfo = that.data.chatInfo;
chatInfo.message = that.data.message;
wx.request({
url: util.basePath + '/article/v1/saveMessageBoard',
method: "post",
data: {
chatInfo: chatInfo543
},
header: {
'content-type': 'application/json'
},
success(res) {
if (res.data.status == 200) {
$Toast({
content: res.data.payload,
type: 'success'
});
that.setData({message: '', messageboard: []});
that.onLoad();
} else {
$Toast({
content: res.data.err,
type: 'error'
});
}
}
});
}
}
后端就是一个insert语句的问题就不展示代码了,但是这里要注意一个问题,这里的表情字符串形式并非任何格式都可以存储的。所以这里数据库留言内容的字符编码处理最简单的方法就是字符集修改为utf8mb4,这样我们就可以成功存储emoji表情的字符串形式,存储成功我们可以发现数据库存储的是?但是实际上读取出来是可以正常转换成原有的emoji表情字符形式的。
博客小程序功能正在不断完善,目前已经开源于码云。欢迎star。源码地址:
https://gitee.com/mqzuimeng_admin/wx_blog.git
本文分享自微信公众号 - 程序猿周先森(zhanyue_org)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。