到底是个啥说不明道不白的情况,来看看效果图:
我也是前前后后想了很多种办法,却忽略了一种最原始的!最简单的!直接将输入的内容中的<>标签符号替换成空字符串不就完事了吗。
二话不说定位一下这个发表评论的核心代码位置。
先来来看看这个button:
<div class="reply-btn-box" style="text-align:center">
<el-button
class="reply-btn"
size="medium"
@click="sendQuillComment"
type="primary"
>发表</el-button
>
</div>
绑定的sendQuillComment点击事件:
sendQuillComment() {
if (!this.$refs.postForm.form.content) {
this.$message({
showClose: true,
type: 'warning',
message: 'quill评论不能为空'
})
} else {
let a = {}
let input = document.getElementById('quillInput')
let timeNow = new Date().getTime()
let time = this.dateStr(timeNow)
a.name = this.myName
a.comment = this.$refs.postForm.form.content.replace(/<[^>]+>/g, '')
a.headImg = this.myHeader
a.time = time
a.commentNum = 0
a.like = 0
this.comments.push(a)
this.replyComment = ''
input.innerHTML = ''
}
},
聪明的同学一眼就看到了重点:
a.comment = this.$refs.postForm.form.content.replace(/<[^>]+>/g, '')
我们再简化一下,到底是哪一步在去除<>标签:
replace(/<[^>]+>/g, '')
最最最最核心就是为了实现评论时能选择emoji的功能。
评论,包括二级评论都是不啥难事哈,带emoji是不是有点调皮了。
等全部完事了,我会总结一篇《如何通过Vue+element实现帖子评论功能》给大家作为参考,类似于贴吧论坛盖楼。
那么回归正题哈,一开始我的想法是把emoji这个功能单独抽出来做个组件。下面先说一下实现的过程。
方法一
第一步,引入JSON文件:
const appData = require("../static/utils/emoji.json");
JSON文件具体内容如下:
<style lang="scss">
/* el-popover是和app同级的,所以scoped的局部属性设置了无效 */
/* 需要设置全局style */
.el-popover{
height:200px;
width:400px;
overflow: scroll;
overflow-x:auto;
}
</style>
<style scoped>
.chatIcon {
padding: 0 10px;
font-size: 25px;
}
.emotionList{
display: flex;
flex-wrap: wrap;
padding:5px;
}
.emotionItem{
width:10%;
font-size:20px;
text-align:center;
}
/*包含以下四种的链接*/
.emotionItem {
text-decoration: none;
}
/*正常的未被访问过的链接*/
.emotionItem:link {
text-decoration: none;
}
/*已经访问过的链接*/
.emotionItem:visited {
text-decoration: none;
}
/*鼠标划过(停留)的链接*/
.emotionItem:hover {
text-decoration: none;
}
/* 正在点击的链接*/
.emotionItem:active {
text-decoration: none;
}
</style>
第二步:template
表情框组件,通过slot插槽按钮触发显示;输入框是一个textarea,我们要把点击选择的表情插入到textarea光标对应的位置之后:
<div class="chatIcon">
<el-popover placement="top-start" width="400" trigger="click" class="emoBox">
<div class="emotionList">
<a href="javascript:void(0);" @click="getEmo(index)" v-for="(item,index) in faceList" :key="index" class="emotionItem">{{item}}</a>
</div>
<el-button
class="emotionSelect"
icon="iconfont icon-biaoqing"
slot="reference"
></el-button>
</el-popover>
</div>
<el-input
v-model="textarea"
class="chatText"
resize="none"
type="textarea"
id='textarea'
rows="5"
@keyup.enter.native="sendInfo"
></el-input>
第三步:css
由于el-popover比较特殊,需要全局设置el-popover样式,并防止污染全局:
<style lang="scss">
/* el-popover是和app同级的,所以scoped的局部属性设置了无效 */
/* 需要设置全局style */
.el-popover{
height:200px;
width:400px;
overflow: scroll;
overflow-x:auto;
}
</style>
<style scoped>
.chatIcon {
padding: 0 10px;
font-size: 25px;
}
.emotionList{
display: flex;
flex-wrap: wrap;
padding:5px;
}
.emotionItem{
width:10%;
font-size:20px;
text-align:center;
}
/*包含以下四种的链接*/
.emotionItem {
text-decoration: none;
}
/*正常的未被访问过的链接*/
.emotionItem:link {
text-decoration: none;
}
/*已经访问过的链接*/
.emotionItem:visited {
text-decoration: none;
}
/*鼠标划过(停留)的链接*/
.emotionItem:hover {
text-decoration: none;
}
/* 正在点击的链接*/
.emotionItem:active {
text-decoration: none;
}
</style>
第四步:script
mounted() {
for(let i in appData){
this.faceList.push(appData[i].char);
}
},
data() {
return {
faceList: [],
textarea: ""
};
},
method(){
getEmo(index){
var textArea=document.getElementById('textarea');
function changeSelectedText(obj, str) {
if (window.getSelection) {
// 非IE浏览器
textArea.setRangeText(str);
// 在未选中文本的情况下,重新设置光标位置
textArea.selectionStart += str.length;
textArea.focus()
} else if (document.selection) {
// IE浏览器
obj.focus();
var sel = document.selection.createRange();
sel.text = str;
}
}
changeSelectedText(textArea,this.faceList[index]);
this.textarea=textArea.value;// 要同步data中的数据
// console.log(this.faceList[index]);
return;
},
}
写完方法一,随之而来的一个问题是:我想用什么表情得先添加到JSON文件里,这样非常不方便,于是才有了方法二的出现。
方法二:使用quill-emoji
第一步:引入并注册
import dedent from 'dedent'
import { Quill, quillEditor } from 'vue-quill-editor'
import quillEmoji from 'quill-emoji'
import 'quill-emoji/dist/quill-emoji.css'
Quill.register('modules/quillEmoji', quillEmoji)
别忘了install这几个库
第二步:
export default {
components: {
Drawer,
quillEditor
},
data() {
return {
content: dedent`
`,
editorOption: {
theme: 'snow',
modules: {
'emoji-toolbar': true,
'emoji-shortname': true,
toolbar: {
container: ['emoji']
}
}
}
}
}
}
第三步:应用
<quill-editor
class="editor"
v-model="content"
:options="editorOption"
/>
Quill里的emoji有多丰富呢?
推荐大家使用方法二,这样可以避免巨坑一,发表评论时不会再有任何<>标签符乱入了。