小程序中如何实现表情组件
发布于 5 年前 作者 changchao 1499 次浏览 来自 分享

先上效果图(无图无真相)

1. 第一步准备表情包素材

我这里用的微博的表情包可以点击下面的链接查看具体JSON格式这里不展示
表情包文件weibo-emotions.js

2. 第二步编写表情组件(基于wepy2.0)

如果不会 wepy 可以先去了解下如果你会vue那非常容易上手

首先我们需要把表情包文件weibo-emotions.js中的JSON文件转换成我们需要的格式
emojis = [
 {
      id: 编号,
      value: 表情对应的汉字含义 例如:[偷笑],
      icon: 表情相对图片路径,
      url: 表情具体图片路径
  }
]

具体转换方法

function () {
    const _emojis = {}
    for (const key in emotions) {
        if (emotions.hasOwnProperty(key)) {
            const ele = emotions[key];
            for (const item of ele) {
                _emojis[item.value] = {
                    id: item.id,
                    value: item.value,
                    icon: item.icon.replace('/', '_'),
                    url: weibo_icon_url + item.icon
                }
            }
        }
    }
    return _emojis
}

编写组件的html代码

<template>
  <div class="emoji" style="height:{{height}}px;" :hidden="hide">
    <scroll-view :scroll-y="true" style="height:{{height}}px;">
      <div class="icons">
        <div class="img" v-for="img in emojis" :key="img.id" @tap.stop="onTap(img.value)">
          <img class="icon-image" :src="img.url" :lazy-load="true" />
        </div>
      </div>
      <div style="height:148rpx;"></div>
    </scroll-view>
    <div class="btn-box">
      <div class="btn-del" @tap.stop="onDel">
        <div class="icon icon-input-del" />
      </div>
    </div>
  </div>
</template>

html代码中的height变量为键盘的高度,通过props传入

编写组件的css代码

.emoji {
  position: fixed;
  bottom: 0px;
  left: 0px;
  width: 100%;
  transition: all 0.3s;
  z-index: 10005;
  &::after {
    content: ' ';
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    height: 1px;
    border-top: 0.4px solid rgba(235, 237, 245, 0.8);
    color: rgba(235, 237, 245, 0.8);
  }
  .icons {
    display: flex;
    flex-wrap: wrap;
    .img {
      flex-grow: 1;
      padding: 20rpx;
      text-align: left;
      justify-items: flex-start;
      .icon-image {
        width: 48rpx;
        height: 48rpx;
      }
    }
  }
  scroll-view {
    background: #f8f8f8;
  }
  .btn-box {
    right: 0rpx;
    bottom: 0rpx;
    position: fixed;
    background: #f8f8f8;
    padding: 30rpx;
    .btn-del {
      background: #ffffff;
      padding: 20rpx 30rpx;
      border-radius: 10rpx;
      .icon {
        font-size: 48rpx;
      }
    }
  }
  .icon-loading {
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }
}

这里是使用less来编写css样式的,flex布局如果你对flex不是很了解可以看看 这篇文章

组件JS代码比较少

import { weibo_emojis } from '../common/api';
import wepy from '[@wepy](/user/wepy)/core';
wepy.component({
  options: {
    addGlobalClass: true
  },
  props: {
    height: Number,
    hide: Boolean
  },
  data: {
    emojis: weibo_emojis,
  },
  methods: {
    onTap(val) {
      this.$emit('emoji', val);
    },
    onDel() {
      this.$emit('del');
    }
  }
});

表情组件基本已经编写完成是不是很简单

那么编写好的组件怎么用呢?

其实也很简单

第一步把组件引入到页面

<config>
{
    "usingComponents": {
      "emoji-input": "../components/input-emoji",
    }
}
</config>

第二步把组件加入到页面html代码中

<emoji-input
      :height="boardheight"
      @emoji="onInputEmoji"
      @del="onDelEmoji"
      :hide="bottom === 0"
    />

第三步编写onInputEmoji,onDelEmoji方法

    /**
     * 选择表情
     */
    onInputEmoji(val) {
      let str = this.content.split('');
      str.splice(this.cursor, 0, val);
      this.content = str.join('');
      if (this.cursor === -1) {
        this.cursor += val.length + 1;
      } else {
        this.cursor += val.length;
      }
      this.canSend();
    },
    /**
     *  删除表情
     */
    onDelEmoji() {
      let str = this.content.split('');
      const leftStr = this.content.substring(0, this.cursor);
      const leftLen = leftStr.length;
      const rightStr = this.content.substring(this.cursor);
      const left_left_Index = leftStr.lastIndexOf('[');
      const left_right_Index = leftStr.lastIndexOf(']');
      const right_right_Index = rightStr.indexOf(']');
      const right_left_Index = rightStr.indexOf('[');
      if (
        left_right_Index === leftLen - 1 &&
        leftLen - left_left_Index <= 8 &&
        left_left_Index > -1
      ) {
        // "111[不简单]|23[33]"left_left_Index=3,left_right_Index=7,leftLen=8
        const len = left_right_Index - left_left_Index + 1;
        str.splice(this.cursor - len, len);
        this.cursor -= len;
      } else if (
        left_left_Index > -1 &&
        right_right_Index > -1 &&
        left_right_Index < left_left_Index &&
        right_right_Index <= 6
      ) {
        // left_left_Index:4,left_right_Index:3,right_right_Index:1,right_left_Index:2
        // "111[666][不简|单]"right_right_Index=1,left_left_Index=3,leftLen=6
        let len = right_right_Index + 1 + (leftLen - left_left_Index);
        if (len <= 10) {
          str.splice(this.cursor - (leftLen - left_left_Index), len);
          this.cursor -= leftLen - left_left_Index;
        } else {
          str.splice(this.cursor, 1);
          this.cursor -= 1;
        }
      } else {
        str.splice(this.cursor, 1);
        this.cursor -= 1;
      }
      this.content = str.join('');
    },

好了基本就完成了一个表情组件的编写和调用

如果你想看完整的代码请点击这里

如果你想体验可以扫下面的二维码自己去体验下

下篇 我们写写怎么实现一个简单的富文本编辑器

1 回复

你这个版面的设计挺好的,看起来很舒服。

回到顶部