Vue评论留言的表情功能实现


Vue评论留言的表情功能实现

介绍:使用的微信提供的表情包地址,生成img标签,然后用v-html渲染.然后点击标签返回#表情名字;

带有#表情名字;的内容用正则表达式处理替换成img标签,其他文字不变,然后用v-html渲染出来

大概就是点击标签,然后input/areatext框里面出现#表情名字,然后content里的#表情名字会变成

第一步 拥有一个表情名字的数组

为了共用,这个数组可以放到一个js文件里并导出

例:https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/0.gif 这表情就是微笑 ,然后数组中微笑的下标就是0

// 这里是放在 src\assets\js\emotionList.js
export default{emotionList:["微笑","撇嘴","色","发呆","得意","流泪","害羞","闭嘴","睡","大哭","尴尬","发怒","调皮","呲牙","惊讶","难过","酷","冷汗","抓狂","吐","偷笑","可爱","白眼","傲慢","饥饿","困","惊恐","流汗","憨笑","大兵","奋斗","咒骂","疑问","嘘","晕","折磨","衰","骷髅","敲打","再见","擦汗","抠鼻","鼓掌","糗大了","坏笑","左哼哼","右哼哼","哈欠","鄙视","委屈","快哭了","阴险","亲亲","吓","可怜","菜刀","西瓜","啤酒","篮球","乒乓","咖啡","饭","猪头","玫瑰","凋谢","示爱","爱心","心碎","蛋糕","闪电","炸弹","刀","足球","瓢虫","便便","月亮","太阳","礼物","拥抱","强","弱","握手","胜利","抱拳","勾引","拳头","差劲","爱你","不","好","爱情","飞吻","跳跳","发抖","怄火","转圈","磕头","回头","跳绳","挥手","激动","街舞","献吻","左太极","右太极"]}

第二步 编写表情展示组件(一个按钮和一个表情盒子)

  1. 这个组件(display:inline-block)默认就只展示一个emotion然后点击展示它会展示出一个表情盒子
  2. 这三部分是同一个文件的,复制到一起直接就可以用了
<template>
  <div @click="handleShowClick" class="emotion-box">
    <slot>
      <span class="emotion">emotion</span>
    </slot>
    <div v-if="load" v-show="show" class="box">
      <span
        class="emo"
        v-for="(line, i) in emotionArr"
        :key="'emojo'+i"
        @click.stop="emoClick(line.name)"
        v-html="line.url"
      ></span>
    </div>
  </div>
</template>

  1. 点击emotion(可以视为按钮)触发handleShowClick(),如果没有加载过表情盒子则去调用loadEmotion()加载表情盒子(懒加载)

  2. loadEmotion()遍历第一步里的数组并生成一个对象数组(对象的名字,img表情完全体)

  3. <template> 中用v-for和emotionArr生成一堆<img ... />在盒子里

  4. 然后给每个设置事件监听,点击时触发emoClick并向父组件发送这个表情的名字(子向父传值)

<script>
// emo: 单个span标签标签简写
// TODO 鼠标点击其他地方关闭
// 位置 src\components\common\emotion-box.vue    
import emotions from '@/assets/js/emotionList.js'
export default {
  name: 'emotion-box',
  data() {
    return {
      show: false, // 是否展示表情框(表情盒子)
      load: false, // 是否加载了表情框
      emotionArr: null, //表情数组
    }
  },
  methods: {
    // 监听span点击来选择展示表情box
    handleShowClick() {
      // 当第一次点击展开在渲染表情盒子 懒加载
      if (this.load == false) this.loadEmotion()
      this.show = !this.show //切换表情盒子的展示状况
    },
    // 表情点击把名字发给父组件(调用者)
    emoClick(arg) {
      this.show = false // 关闭表情盒子
      this.$emit('emotionClick', arg)
    },
    // 加载表情
    loadEmotion() {
      const list = emotions.emotionList
      let emotionArr = []
      list.map((item, index) => {
        emotionArr.push({
          name: `#${item};`,
          url: `<img title="${item}" src="https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/${index}.gif">`,
        })
      })
      this.emotionArr = emotionArr
      this.load = true
      console.log('表情盒子加载完成')
    },
  },
}
</script>
  1. 然后就是随便加点样式,别看代码多主要是设置相对定位绝对定位,还可以设置下z-index防止被覆盖
<style lang="scss" scoped>
.emotion-box {
  // 重要的就是加个相对定位
  display: inline-block;
  position: relative;
  > .emotion {
    cursor: pointer;
    height: 30px;
    user-select: none;
    line-height: 30px;
    padding: 2px 4px;
    border: 1px solid #9c9a9a;
    border-radius: 7px;
    margin-right: 5px;
    &:hover {
      background-color: aquamarine;
    }
  }
  // 重要的就是加个绝对定位 其他就是好看的
  > .box {
    z-index: 10;
    position: absolute;
    background-color: #fff;
    width: 285px;
    max-height: 150px;
    overflow: scroll;
    top: 30px;
    border: 1px solid aqua;
    // 每个span表情标签样式
    .emo {
      cursor: pointer;
    }
  }
}
</style>

然后别的组件导入,注册下这个组件,然后写个函数处理监听到的表情点击事件就可以了

第三步 写个函数利用正则表达式处理带有特殊格式的内容

当有xxx#色;的文字就会变转成成xxx😍 (就是img标签)

把内容用这个函数处理,然后交给v-html

import emotions from '../assets/js/emotionList.js';

export function processEmotion(str) {
  return str.replace(/\#[\u4E00-\u9FA5]{1,3}\;/gi, (words) => {
    let word = words.replace(/\#|\;/gi, '')
    let index = emotions.emotionList.indexOf(word)
    if (index !== -1) {
      return `<img src="https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/${index}.gif" align="middle">`
    } else {
      return words
    }
  })
}

参考

[1] 表情包 - vue/微信小程序/js/数据驱动


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM