欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 Vue+element如何让帖子评论带上emoji,这个需求让我在富文本Quill开始了踩坑连连看

程序员文章站 2022-08-09 16:04:16
天降巨坑1:Quill富文本输入的内容提交后显示的有文本+标签到底是个啥说不明道不白的情况,来看看效果图:emm…看起来让人感觉真是怪别扭的。我也是前前后后想了很多种办法,却忽略了一种最原始的!最简单的!直接将输入的内容中的<>标签符号替换成空字符串不就完事了吗。二话不说定位一下这个发表评论的核心代码位置。先来来看看这个button:

天降巨坑1:Quill富文本输入的内容提交后显示的有文本+标签

到底是个啥说不明道不白的情况,来看看效果图:

荐
                                                        Vue+element如何让帖子评论带上emoji,这个需求让我在富文本Quill开始了踩坑连连看
荐
                                                        Vue+element如何让帖子评论带上emoji,这个需求让我在富文本Quill开始了踩坑连连看
emm…看起来让人感觉真是怪别扭的。

我也是前前后后想了很多种办法,却忽略了一种最原始的!最简单的!直接将输入的内容中的<>标签符号替换成空字符串不就完事了吗。

二话不说定位一下这个发表评论的核心代码位置。

先来来看看这个button:

<div class="reply-btn-box" style="text-align:center">
      <el-button
        class="reply-btn"
        size="medium"
        @click="sendQuillComment"
        type="primary"
        >发表</el-button
      >
    </div>

绑定的sendQuillComment点击事件:

    sendQuillComment() {
      if (!this.$refs.postForm.form.content) {
        this.$message({
          showClose: true,
          type: 'warning',
          message: 'quill评论不能为空'
        })
      } else {
        let a = {}
        let input = document.getElementById('quillInput')
        let timeNow = new Date().getTime()
        let time = this.dateStr(timeNow)
        a.name = this.myName
        a.comment = this.$refs.postForm.form.content.replace(/<[^>]+>/g, '')
        a.headImg = this.myHeader
        a.time = time
        a.commentNum = 0
        a.like = 0
        this.comments.push(a)
        this.replyComment = ''
        input.innerHTML = ''
      }
    },

聪明的同学一眼就看到了重点:

a.comment = this.$refs.postForm.form.content.replace(/<[^>]+>/g, '')

我们再简化一下,到底是哪一步在去除<>标签:

replace(/<[^>]+>/g, '')

荐
                                                        Vue+element如何让帖子评论带上emoji,这个需求让我在富文本Quill开始了踩坑连连看
这不是整挺好了吗

天降巨坑2:Vue+element+Emoji+Quill

最最最最核心就是为了实现评论时能选择emoji的功能。

评论,包括二级评论都是不啥难事哈,带emoji是不是有点调皮了。

等全部完事了,我会总结一篇《如何通过Vue+element实现帖子评论功能》给大家作为参考,类似于贴吧论坛盖楼。

那么回归正题哈,一开始我的想法是把emoji这个功能单独抽出来做个组件。下面先说一下实现的过程。

方法一

第一步,引入JSON文件:

const appData = require("../static/utils/emoji.json");

JSON文件具体内容如下:

<style lang="scss">
/* el-popover是和app同级的,所以scoped的局部属性设置了无效 */
/* 需要设置全局style */
  .el-popover{
    height:200px;
    width:400px;
    overflow: scroll;
    overflow-x:auto;
  }
</style>

<style scoped>
.chatIcon {
  padding: 0 10px;
  font-size: 25px;
}
.emotionList{
  display: flex;
  flex-wrap: wrap;
  padding:5px;
}
.emotionItem{
  width:10%;
  font-size:20px;
  text-align:center;
}
/*包含以下四种的链接*/
.emotionItem {
    text-decoration: none;
}
/*正常的未被访问过的链接*/
.emotionItem:link {
    text-decoration: none;
}
/*已经访问过的链接*/
.emotionItem:visited {
    text-decoration: none;
}
/*鼠标划过(停留)的链接*/
.emotionItem:hover {
    text-decoration: none;
}
/* 正在点击的链接*/
.emotionItem:active {
    text-decoration: none;
}
</style>

第二步:template

表情框组件,通过slot插槽按钮触发显示;输入框是一个textarea,我们要把点击选择的表情插入到textarea光标对应的位置之后:

<div class="chatIcon">
    <el-popover placement="top-start" width="400" trigger="click" class="emoBox">
        <div class="emotionList">
            <a href="javascript:void(0);" @click="getEmo(index)" v-for="(item,index) in faceList" :key="index" class="emotionItem">{{item}}</a>
        </div>
        <el-button
        class="emotionSelect"
        icon="iconfont icon-biaoqing"
        slot="reference"
        ></el-button>
    </el-popover>
</div>
<el-input
  v-model="textarea"
  class="chatText"
  resize="none"
  type="textarea"
  id='textarea'
  rows="5"
  @keyup.enter.native="sendInfo"
></el-input>

第三步:css

由于el-popover比较特殊,需要全局设置el-popover样式,并防止污染全局:

<style lang="scss">
/* el-popover是和app同级的,所以scoped的局部属性设置了无效 */
/* 需要设置全局style */
  .el-popover{
    height:200px;
    width:400px;
    overflow: scroll;
    overflow-x:auto;
  }
</style>

<style scoped>
.chatIcon {
  padding: 0 10px;
  font-size: 25px;
}
.emotionList{
  display: flex;
  flex-wrap: wrap;
  padding:5px;
}
.emotionItem{
  width:10%;
  font-size:20px;
  text-align:center;
}
/*包含以下四种的链接*/
.emotionItem {
    text-decoration: none;
}
/*正常的未被访问过的链接*/
.emotionItem:link {
    text-decoration: none;
}
/*已经访问过的链接*/
.emotionItem:visited {
    text-decoration: none;
}
/*鼠标划过(停留)的链接*/
.emotionItem:hover {
    text-decoration: none;
}
/* 正在点击的链接*/
.emotionItem:active {
    text-decoration: none;
}
</style>

第四步:script

mounted() {
    for(let i in appData){
      this.faceList.push(appData[i].char);
    }
},
data() {
    return {
      faceList: [],
      textarea: ""
    };
},
method(){
    getEmo(index){
        var textArea=document.getElementById('textarea');
        function changeSelectedText(obj, str) {
          if (window.getSelection) {
            // 非IE浏览器
            textArea.setRangeText(str);
            // 在未选中文本的情况下,重新设置光标位置
            textArea.selectionStart += str.length;
            textArea.focus()
          } else if (document.selection) {
            // IE浏览器
            obj.focus();
            var sel = document.selection.createRange();
            sel.text = str;
          }
        }
        changeSelectedText(textArea,this.faceList[index]);
        this.textarea=textArea.value;// 要同步data中的数据
        // console.log(this.faceList[index]);
        return;
      },
}

写完方法一,随之而来的一个问题是:我想用什么表情得先添加到JSON文件里,这样非常不方便,于是才有了方法二的出现。

方法二:使用quill-emoji

第一步:引入并注册

import dedent from 'dedent'
import { Quill, quillEditor } from 'vue-quill-editor'
import quillEmoji from 'quill-emoji'
import 'quill-emoji/dist/quill-emoji.css'

Quill.register('modules/quillEmoji', quillEmoji)

别忘了install这几个库

第二步:

export default {
  components: {
    Drawer,
    quillEditor
  },
  data() {
    return {
      content: dedent`
          <p><span data-name="grinning"><span contenteditable="false"><span class="ap ap-grinning"></span></span></span></p>
        `,
      editorOption: {
        theme: 'snow',
        modules: {
          'emoji-toolbar': true,
          'emoji-shortname': true,
          toolbar: {
            container: ['emoji']
          }
        }
      }
    }
   }
 }

第三步:应用

 <quill-editor
      class="editor"
      v-model="content"
      :options="editorOption"
    />

Quill里的emoji有多丰富呢?

荐
                                                        Vue+element如何让帖子评论带上emoji,这个需求让我在富文本Quill开始了踩坑连连看
荐
                                                        Vue+element如何让帖子评论带上emoji,这个需求让我在富文本Quill开始了踩坑连连看
要啥啥都有,Quill真香!

推荐大家使用方法二,这样可以避免巨坑一,发表评论时不会再有任何<>标签符乱入了。

本文地址:https://blog.csdn.net/weixin_42224055/article/details/107249967