vue实现表情、图片、视频评论

/src/utils/emojiMap.js //表情库请自行寻找

//表情图片地址
//例如 emojiUrl + 'emoji_141@2x.png'
export const emojiUrl = '' 
export const emojiMap = {
  '[龇牙]': 'emoji_141@2x.png'
}
export const emojiName = [
  '[龇牙]',
]

/src/utils/decodeText.js 字符串转换成字符串和图片的数组 例如 你好[龇牙]转换成['你好',emojiUrl + 'emoji_141@2x.png']用于循环显示表情和文本的内容

import { emojiMap, emojiUrl } from '@/utils/emojiMap'
export function decodeText (text) {
  let renderDom = []
  // 文本消息
    let temp = text
    let left = -1
    let right = -1
    while (temp !== '') {
      left = temp.indexOf('[')
      right = temp.indexOf(']')
      switch (left) {
        case 0:
          if (right === -1) {
            renderDom.push({
              name: 'text',
              text: temp
            })
            temp = ''
          } else {
            let _emoji = temp.slice(0, right + 1)
            if (emojiMap[_emoji]) {
              renderDom.push({
                name: 'img',
                src: emojiUrl + emojiMap[_emoji]
              })
              temp = temp.substring(right + 1)
            } else {
              renderDom.push({
                name: 'text',
                text: '['
              })
              temp = temp.slice(1)
            }
          }
          break
        case -1:
          renderDom.push({
            name: 'text',
            text: temp
          })
          temp = ''
          break
        default:
          renderDom.push({
            name: 'text',
            text: temp.slice(0, left)
          })
          temp = temp.substring(left)
          break
      }
    }
  return renderDom
}

使用

​
<template>
  <div>
    <div class="flex box" style="margin-bottom: 4px; position: relative">
      <div
        v-if="faceFlag"
        style="position: absolute; top: -250px; z-index: 100"
      >
        <div class="boxs" style="padding: 20rpx 30rpx">
          <div
            v-for="item in emojiName"
            class="emoji"
            :key="item"
            @click.stop="chooseEmoji(item)"
          >
            <img
              :src="emojiUrl + emojiMap[item]"
              style="width: 20px; height: 20px"
            />
          </div>
        </div>
      </div>
      <img
        class="icon cur"
        src="@/assets/png/addFace.png"
        mode=""
        @click.stop="openFaceFun"
        style="margin-right: 10px"
      />
      <div style="position: relative; margin-right: 10px">
        <input
          type="file"
          id="imagePicker"
          accept="image/*"
          class="inpt"
          @click="faceFlag = false"
          @change="sendFun($event, 'image')"
          title=""
        />
        <img class="icon cur" src="@/assets/png/addPic.png" mode="" />
      </div>
      <div style="position: relative; margin-right: 10px">
        <input
          type="file"
          id="videoPicker"
          accept="video/*"
          class="inpt"
          @click="faceFlag = false"
          @change="sendFun($event, 'video')"
          title=""
        />
        <img class="icon cur" src="@/assets/png/addVideo.png" mode="" />
      </div>
    </div>
    <el-input
      v-model="textarea"
      :rows="2"
      type="textarea"
      placeholder="Please input"
    />
    <el-button @click="sendFun(textarea, 'msg')">发送</el-button>
    <div>
      <div v-for="(item, index) in msgArr" :key="index">
        <template v-if="item.type == 'msg'">
          <div class="flex text-box">
            <div v-for="(i, k) in decode(item.content)" :key="k">
              <div class="font" v-if="i.name === 'text'">{{ i.text }}</div>
              <img v-else-if="i.name === 'img'" :src="i.src" class="imgbox" />
            </div>
          </div>
        </template>
        <template v-else-if="item.type == 'image'">
          <img :src="item.content" alt="" />
        </template>
        <template v-else>
          <video :src="item.content" controls></video>
        </template>
      </div>
    </div>
  </div>
</template>

<script>
import { emojiMap, emojiName, emojiUrl } from '@/utils/emojiMap'
import { decodeText } from '@/utils/decodeText'

export default {
  data() {
    return {
      textarea: '',
      msgArr: [],
      faceFlag: false,
      emojiMap,
      emojiName,
      emojiUrl,
    }
  },
  methods: {
    openFaceFun() {
      this.faceFlag = !this.faceFlag
    },
    openOperFun() {
      console.log(222)
      this.faceFlag = false
    },
    chooseEmoji(e) {
      this.textarea += e
      this.faceFlag = false
    },
    decode(text) {
      return decodeText(text)
    },
    sendFun(e, type) {
      let obj = {
        type,
        content:
          type == 'msg' ? e : window.URL.createObjectURL(e.target.files[0]),
      }
      this.msgArr.push(obj)
      if (type == 'msg') this.textarea = ''
    },
  },
}
</script>

<style lang='scss' scoped>
.inpt {
  position: absolute;
  top: 0;
  height: 100%;
  width: 100%;
  opacity: 0;
  padding: 0;
}
.boxs {
  background-color: #fff;
  height: 250px;
  overflow-y: scroll;
  transition: all 1s ease-in-out;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
}
.emoji {
  margin: 5px 7.5px;
}
.imgbox {
  width: 20px;
  height: 20px;
}
.font {
  font-size: 20px;
}
.text-box {
  align-items: center;
}
</style>

​

展示效果

样式没有写的很多,请自行调整

表情

图片、视频(实际应用的时候,图片视频是需要上传到服务器的,本文没有写,可以去看看我的另一篇上传组件)

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值