使用UniApp ColorUi
1、chat.vue
<template>
<view>
<view
class="input-content text-left"
:focus.sync="textareaFocus"
@input="textareaBInput"
ref="input-content"
placeholder="多行文本輸入框"
contenteditable="true">
</view>
<choose-person :visible.sync="choosePersonVisible" @check-person="checkPerson"></choose-person>
</view>
</template>
<script>
import choosePerson from './choose-person.vue'
export default {
components: {
choosePerson
},
data() {
return {
// 內(nèi)容
oldContent:'',
content: '',
cursorIndex:0,//光標(biāo)的位置
// 選擇@人
choosePersonVisible:false,
textareaFocus:false,
}
},
methods: {
// 用戶輸入
textareaBInput() {
// 記錄當(dāng)前輸入的內(nèi)容
this.content = this.$refs['input-content'].$el.innerHTML;
const oldArr = this.oldContent.split('');
const newArr = this.content.split('');
let contentStr = this.content;
// 找出當(dāng)前輸入的內(nèi)容
oldArr.forEach(str=>{
contentStr = contentStr.replace(str,'');
})
// 輸入是@時(shí)
if(contentStr === '@'){
this.choosePersonVisible = true;
this.textareaFocus = false;
// 比對(duì)算法,找出當(dāng)前光標(biāo)的位置,找到當(dāng)前輸入的位置
newArr.some((now,index) => {
if(this.content.substring(0,index) !== this.oldContent.substring(0,index)){
this.cursorIndex = index;
return true;
}
this.cursorIndex = 0;
})
}
this.oldContent = this.content
},
// 選擇@的人
checkPerson(data){
const span= `<span contenteditable="false" userName="${data.name}" userId="${data.personId}" style="color:#4A90E2;">@${data.name}</span>`;
let html = this.$refs['input-content'].$el.innerHTML;
// 光標(biāo)位置為0在后面追加,不為0從中間替換
if(this.cursorIndex){
html = html.substr(0,this.cursorIndex-1)+span+html.substr(this.cursorIndex,html.length)
}else{
html = html.substr(0,html.length-1)+span;
}
this.$refs['input-content'].$el.innerHTML = html;
this.oldContent = this.$refs['input-content'].$el.innerHTML;
this.choosePersonVisible = false;
this.textareaFocus = true;
},
},
}
</script>
<style lang="scss">
.input-content{
outline: none;
margin: 16px 0 15px;
height: 4.6em;
width: 100%;
line-height: 1.2em;
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
font-size: 14px;
padding: 0;
}
</style>
調(diào)用chat組件
...
<chat ref="chat" class="flex-sub"></chat>
...
//使用這種方法獲取輸入的內(nèi)容
let content = this.$refs.chat.$refs['input-content'].$el.innerHTML
2、choose-person.vue
<template>
<view class="cu-modal bottom-modal" :class="visible?'show':''">
<view class="cu-dialog">
<view class="cu-bar bg-white">
<view class="action text-green"></view>
<view class="action text-blue" @tap="hideModal">取消</view>
</view>
<view class="">
<view class="cu-list menu-avatar">
<view class="cu-item" @tap="checkPerson">
<view class="cu-avatar round lg"
style="background-image:url(https://ossweb-img.qq.com/images/lol/web201310/skin/big10001.jpg);">
</view>
<view class="content">
<view class="text-grey">凱爾</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default{
props:['visible'],
methods:{
hideModal(){
this.$emit('update:visible',false)
},
checkPerson(){
this.$emit('check-person',{personId:'1313',name:'凱爾'})
}
}
}
</script>
<style>
</style>
效果展示