Skip to content

EmojiPicker 表情面板

表情选择面板。六组内置表情,附最近使用。

基础用法

最近选择:(尚未选择)

vue
<script setup>
function onSelect(emoji) {
  // emoji.native 是字符本身,emoji.shortcode 是 :smile: 这样的短代码
  text.value += emoji.native
}
</script>

<template>
  <SrEmojiPicker @select="onSelect" />
</template>

数据结构

选中项包含三个字段:

ts
interface SrEmojiItem {
  native: string      // 字符本身:😀
  shortcode: string   // 短代码::grinning:
  keywords?: string[] // 搜索关键词
}

nativeshortcode 都要留

  • 存进正文用 native——它是用户看到的那个字符,不需要额外渲染逻辑;
  • 筛选与搜索要用 shortcode——native 是四字节的 emoji, 在部分数据库与旧系统的排序规则下会出现乱码或匹配异常。

搜索与最近使用

面板顶部有搜索框,支持按短代码与关键词匹配。 「最近使用」会在同一浏览器内跨会话保留——数据存在 localStorage

vue
<SrEmojiPicker :recent-limit="12" @select="onSelect" />

「最近使用」是本地存储,不跨设备

不同设备上的使用习惯本就不同(手机与电脑常发的表情差异很大), 而且跨设备同步需要账号体系——组件库不该引入这种依赖。

需要服务端同步时,在 @select 里自行上报即可。

列数与尺寸

vue
<SrEmojiPicker :columns="6" :image-size="26" />
<SrEmojiPicker :columns="10" :image-size="22" />

columnsimageSize 需要配套调整:列数越多、单个越要小, 否则宽度会撑破容器。

自定义表情包

packages 传入自定义数据后,内置的六组会被完全替换—— 不是追加,是替换。

这一组还没有表情

只保留自定义的一组

vue
<script setup>
const packages = [
  {
    name: '自定义',
    emojis: [
      { native: '🐟', shortcode: ':fish:' },
      { native: '🌊', shortcode: ':wave:' }
    ]
  }
]
</script>

<template>
  <SrEmojiPicker :packages="packages" />
</template>

packages 会替换而非追加

这是有意的——否则「只想用自己那几组」的场景还得先想办法把内置的删掉。

需要在内置基础上追加时,从 DEFAULT_EMOJI_PACKAGES 展开:

ts
import { DEFAULT_EMOJI_PACKAGES } from '@starriver/ui'

const packages = [...DEFAULT_EMOJI_PACKAGES, myPackage]

关于渲染 Markdown 里的表情

SrCommentSrMarkdown 都能把正文里的 :shortcode: 渲染成表情字符。 它们内部用同一套解析逻辑,因此短代码定义必须一致—— 若给 SrEmojiPicker 传了自定义包,记得也给它们传。

Props

名称类型默认值说明
packagesSrEmojiPackage[]内置六组表情包数据,会替换内置
recentLimitnumber16「最近使用」最多保留几个
columnsnumber8每行几个
imageSizenumber28单个表情尺寸(px)

事件

事件参数说明
selectSrEmojiItem选中某个表情

无障碍

  • 每个表情是 <button> 并带 aria-label(短代码形式,如「grinning」)—— emoji 字符本身在部分读屏软件下会被念成无意义的描述
  • 分组标签用 role="tab",可用方向键在分组间切换
  • 搜索框带 aria-label="搜索表情"
  • 「最近使用」与「搜索」空结果都有明确文案,不是一片空白

自用组件库 · 源码分发 · 不发布 npm