在做一个评论模块的时候,想在评论的内容添加一些emoji表情,在网上搜了一堆之后,发现最适合的还是v-emoji-picker组件库。
首先是下载该库npm install v-emoji-picker
(我这边前端的依赖管理用的是npm)下载完成后,你可以选择在全局使用该组件,也可以在某个页面使用。
话不多说,上效果图(可能视频转gif有点质量问题)
因为这个组件没有设置是否显示和隐藏的属性,所以我们可以使用vue的指令v-show
来使这个组件是否显示出来
<template>
<div class="app-container">
<el-col>
<el-button type="text" size="mini" @click="showDialog = !showDialog">😃</el-button>
</el-col>
<el-col :span="12">
<el-col :span="16">
<el-input
id="input"
v-model="text"
type="textarea"
:autosize="{ minRows: 2, maxRows: 2}"
resize="none"
placeholder="请输入内容">
</el-input>
</el-col>
<el-col :span="6">
<el-button style="height: 54px;background-color: #fc5531;color: white;border: 1px solid #fc5531">发表评论</el-button>
</el-col>
</el-col>
<el-col>
<VEmojiPicker v-show="showDialog" @select="selectEmoji"/>
</el-col>
</div>
</template>
利用v-show="showDialog"来控制emoji组件的显示
单个页面使用时,需要注册组件
<script>
import {VEmojiPicker} from 'v-emoji-picker'
export default {
components: {
VEmojiPicker
},
data() {
return {
text: '',
showDialog: false
}
},
methods: {
selectEmoji(emoji) {// 选择emoji后调用的函数
let input = document.getElementById("input")
let startPos = input.selectionStart
let endPos = input.selectionEnd
let resultText = input.value.substring(0, startPos) + emoji.data + input.value.substring(endPos)
input.value = resultText
input.focus()
input.selectionStart = startPos + emoji.data.length
input.selectionEnd = startPos + emoji.data.length
this.text = resultText
}
}
}
</script>
selectEmoji
方法具体实现是先根据input的两个属性selectionStart
selectionEnd
来获取input框输入时的光标位置,然后将表情插入到光标位置,插入之后重新定义光标位置。
值得注意的是let input = document.getElementById("input")
此处必须使用原生js获取input标签,如果是使用vue 的ref属性,获得的不是input标签,而是element-ui 封装的外层标签。
像这种element-ui的标签 <el-input>
都是经过饿了么封装之后的,而selectionStart
selectionEnd
这两个属性是input才有的。
let resultText = input.value.substring(0, startPos) + emoji.data + input.value.substring(endPos)
input.value = resultText
input.focus()
input.selectionStart = startPos + emoji.data.length
input.selectionEnd = startPos + emoji.data.length
this.text = resultText
对于这块代码,千万不要像我一样以为在给input框value赋值时可以直接给vue里的v-model绑定的属性值赋值之后就行了,这样只是值可以了,但是当你添加了一个表情之后,input框的光标就移动到了最后面,而不是你所期待的在表情后面。(我这段代码也是通过百度而来,当时没有使用cv大法,而是自己改的,以为给v-model的属性赋值就行了,结果一直得不到想要的结果,后来才改正)。
还有就是对于emoji这个参数selectEmoji(emoji)
,可能是因为库的版本原因,我在网上查询的资料里真正展现表情的不是emoji.data,而是另外一个属性,而我这个版本的是emoji.data,所以想正确使用的话,建议先console.log(emoji),看看是这个对象的什么属性才是表情
简而言之,想要正确的引入emoji组件库需要以下几步:
- 找到一个符合你预期的emoji组件库,对了,如果emoji选中之后显示的是类似于这种
<img src="/xx/x.png" />
这种用img图片展示的建议不要用,因为input框无法把HTML标签解析出来,至少我目前没想到办法(如果自己使用vue写一个组件出来应该可以实现) - 下载好依赖库,导入页面,并初始化和编写好调用emoji的函数
- 最主要的就是通过input的光标进行定位插入emoji。