WeChat 文章评论页(二)

作者 : 开心源码 本文共8738个字,预计阅读时间需要22分钟 发布时间: 2022-05-13 共241人阅读

Unsplash

本次的系列博文的知识点讲解和代码,主要是来自于 七月老师 的书籍《微信小程序开发:入门与实践》,由个人总结并编写,关于更多微信小程序开发中的各项技能,以及常见问题的处理方案,还请大家购买书籍进行学习实践,该系列博文的发布已得到七月老师的受权许可

受权许可

0 系列文章目录

01 WeChat 从一个简单的“Welcome”页面来开启小程序之旅吧
02 WeChat 文章列表页面(一)
03 WeChat 文章列表页面(二)
04 WeChat 模块、模板与缓存
05 WeChat 文章介绍页
06 WeChat 文章评论页(一)
07 WeChat 文章评论页(二)

1 评论框实现

评论框左侧的声音按钮,可以切换文本类型评论或者语音类型评论,右侧加号图标可以选择图片和拍照,最右侧为发送按钮,通过 useKeyboardFlag 变量来切换语音输入框和键盘输入框,useKeyboardFlag 变量将由 catchtap="switchInputType" 这个事件来控制,catchtouchstart="recordStart"catchtouchend="recordEnd" 将开启录音和结束录音,catchtap="sendMoreMsg" 将实现向内容中增加图片和拍照选择框的功能,catchtap="submitComment" 将实现评论内容的最终发送功能

<!--pages/post/post-comment/post-comment.wxml--><view class="comment-detail-box">  ...  <view class="input-box">    <view class="send-msg-box">      <view hidden="{{useKeyboardFlag}}" class="input-item">        <image src="/images/icon/wx_app_keyboard.png" class="comment-icon keyboard-icon" catchtap="switchInputType"></image>        <input class="input speak-input {{recodingClass}}" value="按住 说话" disabled="disabled" catchtouchstart="recordStart" catchtouchend="recordEnd" />      </view>      <view hidden="{{!useKeyboardFlag}}" class="input-item">        <image class="comment-icon speak-icon" src="/images/icon/wx_app_speak.png" catchtap="switchInputType"></image>        <input class="input keyboard-input"  value="{{keyboardInputValue}}" bindconfirm="submitComment" bindinput="bindCommentInput" placeholder="说点什么吧……" />      </view>      <image class="comment-icon add-icon" src="/images/icon/wx_app_add.png" catchtap="sendMoreMsg"></image>      <view class="submit-btn" catchtap="submitComment">发送</view>    </view>  </view></view>
/* pages/post/post-comment/post-comment.wxss */.input-box {position:absolute;bottom:0;left:0;right:0;background-color:#eae8e8;border-top:1rpx solid #d5d5d5;min-height:100rpx;z-index:1000;}.input-box .send-msg-box {width:100%;height:100%;display:flex;padding:20rpx 0;}.input-box .send-more-box {margin:20rpx 35rpx 35rpx 35rpx;}.input-box .input-item {margin:0 5rpx;flex:1;width:0%;position:relative;}.input-box .input-item .comment-icon {position:absolute;left:5rpx;top:6rpx;}.input-box .input-item .input {border:1rpx solid #d5d5d5;background-color:#fff;border-radius:3px;line-height:65rpx;margin:5rpx 0 5rpx 75rpx;font-size:24rpx;color:#838383;padding:0 2%;}.input-box .input-item .keyboard-input {width:auto;max-height:500rpx;height:65rpx;word-break:break-all;overflow:auto;}.input-box .input-item .speak-input {text-align:center;color:#212121;height:65rpx;}.input-box .input-item .recoding {background-color:#ccc;}.input-box .input-item .comment-icon.speak-icon {height:62rpx;width:62rpx;}.input-box .input-item .comment-icon.keyboard-icon {height:60rpx;width:60rpx;left:6rpx;}.input-box .add-icon {margin:0 5rpx;height:65rpx;width:65rpx;transform:scale(0.9);margin-top:2px;}.input-box .submit-btn {font-size:24rpx;margin-top:5rpx;margin-right:8rpx;line-height:60rpx;width:120rpx;height:60rpx;background-color:#4a6141;border-radius:5rpx;color:#fff;text-align:center;font-family:Microsoft Yahei;}.send-more-box .more-btn-item {display:inline-block;width:110rpx;height:145rpx;margin-right:35rpx;text-align:center;}.more-btn-main {width:100%;height:60rpx;text-align:center;border:1px solid #d5d5d5;border-radius:10rpx;background-color:#fbfbfc;margin:0 auto;padding:25rpx 0;}.more-btn-main image {width:60rpx;height:60rpx;}.send-more-box .more-btn-item .btn-txt {color:#888888;font-size:24rpx;margin:10rpx 0;}.send-more-result-main {margin-top:30rpx;}.send-more-result-main .file-box {margin-right:14rpx;height:160rpx;width:160rpx;position:relative;display:inline-block;}.send-more-result-main .file-box.deleting {animation:deleting 0.5s ease;animation-fill-mode:forwards;}@keyframes deleting {0% {transform:scale(1);}100% {transform:scale(0);}}.send-more-result-main image {height:100%;width:100%;}.send-more-result-main .remove-icon {position:absolute;right:5rpx;top:5rpx;}.send-more-result-main .file-box .img-box {height:100%;width:100%;}
// pages/post/post-comment/post-comment.js//切换语音和键盘输入switchInputType: function (event) {  this.setData({    useKeyboardFlag: !this.data.useKeyboardFlag  })}

运行结果

2 新添加评论

编写 bindinput 事件,获取客户输入内容,小程序没有数据双向绑定功能,只能在表单内容发生变化时,触发表单元素上绑定的方法,将表单上的值赋值给 data 里的对应值

// pages/post/post-comment/post-comment.js// 获取客户输入bindCommentInput: function (event) {  let val = event.detail.value;  this.data.keyboardInputValue = val;}

我们在成功获取客户的输入后,需要将其保存到 this.data 变量中,发送按钮的事件响应函数是 submitComment,这个方法中我们需要将 newData 保存到缓存数据库中,而我们曾在 DBPost.js 中的 updatePostData 方法中解决新添加评论,在这里就不再复述;显示评论发表成功的提醒;将当前发表的评论增加到评论列表中,并显示这条新增的评论;清空 input 组件,准备接受下一条评论

// db/DBPost.js// 发表评论newComment(newComment) {  this.updatePostData('comment', newComment);}
// pages/post/post-comment/post-comment.js// 提交客户评论submitComment: function (event) {  let newData = {      username: "青石",      avatar: "/images/avatar/avatar-3.png",      create_time: new Date().getTime() / 1000,      content: {        txt: this.data.keyboardInputValue      },  }  if(!newData.content.txt) {    return;  }  //保存新评论到缓存数据库中  this.dbPost.newComment(newData)  //显示操作结果  this.showCommitSuccessToast()  //重新渲染并绑定所有评论  this.bindCommentData()  //恢复初始状态  this.resetAllDefaultStatus()},//评论成功showCommitSuccessToast: function () {  //显示操作结果  wx.showToast({    title: "评论成功",    duration: 1000,    icon: "success"  })},bindCommentData: function () {  let comments = this.dbPost.getCommentData()  // 绑定评论数据  this.setData({    comments: comments  })},//将所有相关的按钮状态,输入状态都回到初始化状态resetAllDefaultStatus: function () {  //清空评论框  this.setData({    keyboardInputValue: ''  })}

运行结果

3 图片与拍如实现

<!--pages/post/post-comment/post-comment.wxml--><view class="comment-detail-box">  ...  <view class="input-box">    ...    <view class="send-more-box" hidden="{{!sendMoreMsgFlag}}">      <!--选择图片和拍照的按钮-->      <view class="send-more-btns-main">        <view class="more-btn-item" catchtap="chooseImage" data-category="album">          <view class="more-btn-main">            <image src="/images/icon/wx_app_upload_image.png"></image>          </view>          <text>照片</text>        </view>        <view class="more-btn-item" catchtap="chooseImage" data-category="camera">          <view class="more-btn-main">            <image src="/images/icon/wx_app_camera.png"></image>          </view>          <text>拍照</text>        </view>      </view>      <!--显示选择的图片-->      <view class="send-more-result-main" hidden="{{chooseFiles.length==0}}">        <block wx:for="{{chooseFiles}}" wx:for-index="idx" wx:key="idx">          <!--假如删除其中一个,则对其增加deleting 样式;-->          <view class="file-box {{deleteIndex==idx?'deleting':''}}">            <view class="img-box">              <image src="{{item}}" mode="aspectFill"></image>              <icon class="remove-icon" type="cancel" size="23" color="#B2B2B2" catchtap="deleteImage" data-idx="{{idx}}" />            </view>          </view>        </block>      </view>    </view>  </view></view>

随后设置切换面板的变量

// pages/post/post-comment/post-comment.jsPage({  data: {    // 控制使用键盘还是发送语音    useKeyboardFlag: true,    // 控制input组件的初始值    keyboardInputValue: '',    // 控制能否显示图片选择面板    sendMoreMsgFlag: false,  },  ...  //显示 选择照片、拍照等按钮  sendMoreMsg: function () {    this.setData({      sendMoreMsgFlag: !this.data.sendMoreMsgFlag    })  }})

运行结果

小程序提供了 wx.chooseImage(object) API 用来实现从相册选择照片和拍照上传功能,我们设定一次评论内容最多只允许发送 3 张照片,对应 wx.chooseImage(object) 方法中的 count 参数,该方法接收的另一个参数是 sourceType,用于指定是拍照生成照片还是从手机相册选择照片,该参数是一个数组,可以有以下几个取值:['album'] 直接打开相册,并可以选择照片,无论是在开发工具还是真机上都可以支持多选;['camera'] 直接打开相机并拍照生成照片;['album', 'camera'] 可以让客户自行选择拍照还是从手机相册选择

// pages/post/post-comment/post-comment.jsPage({  data: {    ...    // 保存已选择图片    chooseFiles: []  },  ...  //选择本地照片与拍照  chooseImage: function (event) {    // 已选择图片数组    let imgArr = this.data.chooseFiles;    //只能上传3张照片,包括拍照    let leftCount = 3 - imgArr.length;    if (leftCount <= 0) {      return    }    let sourceType = [event.currentTarget.dataset.category],        that = this;    wx.chooseImage({      count: leftCount,      sourceType: sourceType,      success: function (res) {        // 可以分次选择图片,但总数不能超过3张        that.setData({          chooseFiles: imgArr.concat(res.tempFilePaths)        })      }    })  }})

运行结果

我们在编写 wxml 代码的 icon 组件时,注册了 deleteImage 事件,用于删除已选择图片,获取当前删除图片的序号,并将该图片的 urlthis.data.chooseFiles 数组中删除,重新绑定 chooseFiles 变量就可

我们在编写 wxss 代码时,给删除图片增加了一段动画效果,通过 deleteIndex == idx ? 'deleting' : '' 进行判断,所以我们需要定义一个 deleteIndex 变量,将所需要删除图片的序号赋值给该变量,使被删除的图片立即增加并执行一个 deleting 动画,并在删除之后将该变量恢复为初始值,否则动画执行将会出错

// pages/post/post-comment/post-comment.jsPage({  data: {    ...    // 被删除的图片序号    deleteIndex: -1  },  ...  //删除已经选择的图片  deleteImage: function (event) {    let index = event.currentTarget.dataset.idx,        that = this;    that.setData({        deleteIndex: index    })    that.data.chooseFiles.splice(index, 1)    setTimeout(function () {      that.setData({        deleteIndex: -1,        chooseFiles: that.data.chooseFiles      })    }, 500)  }})

运行结果

4 图片评论发送实现

实现发送图片评论的方法非常简单,只要要将当前 this.data.chooseFilse 所保存的图片地址存入数据缓存中,并重新渲染评论列表就可,在发送完图片评论后,重置 chooserFiles 变量和 sendMoreMsgFlag 变量,清空图片选择面板中已选择的图片,并再次隐藏图片选择面板

// pages/post/post-comment/post-comment.js// 提交客户评论submitComment: function (event) {  let imgs = this.data.chooseFiles;  let newData = {      username: "青石",      avatar: "/images/avatar/avatar-3.png",      create_time: new Date().getTime() / 1000,      content: {        txt: this.data.keyboardInputValue,        img: imgs      },  }  if(!newData.content.txt && imgs.length === 0) {    return;  }  //保存新评论到缓存数据库中  this.dbPost.newComment(newData)  //显示操作结果  this.showCommitSuccessToast()  //重新渲染并绑定所有评论  this.bindCommentData()  //恢复初始状态  this.resetAllDefaultStatus()},//将所有相关的按钮状态,输入状态都回到初始化状态resetAllDefaultStatus: function () {  //清空评论框  this.setData({    keyboardInputValue: '',    chooseFiles: [],    sendMoreMsgFlag: false  })}

该章节的内容到这里就一律结束了,源码我已经发到了 GitHub WeChat_07 上了,有需要的同学可自行下载

End of File

行文过程中出现错误或者不妥之处在所难免,希望大家能够给予指正,以免误导更多人,最后,假如你觉得我的文章写的还不错,希望能够点一下喜欢关注,为了我能早日成为简书优秀作者献上一发助攻吧,谢谢!^ ^

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » WeChat 文章评论页(二)

发表回复