美文网首页
UniApp中实现类似微信聊天@功能

UniApp中实现类似微信聊天@功能

作者: 一个小前端程序员 | 来源:发表于2021-09-01 16:28 被阅读0次

使用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 {
                // 内容
                oldContent:'',
                content: '',
                cursorIndex:0,//光标的位置
                // 选择@人
                choosePersonVisible:false,
                textareaFocus:false,
            }
        },
        methods: {
            // 用户输入
            textareaBInput() {
                // 记录当前输入的内容
                this.content = this.$refs['input-content'].$el.innerHTML;
                const oldArr = this.oldContent.split('');
                const newArr = this.content.split('');
                let contentStr = this.content;
                // 找出当前输入的内容
                oldArr.forEach(str=>{
                    contentStr = contentStr.replace(str,'');
                })
                // 输入是@时
                if(contentStr === '@'){
                    this.choosePersonVisible = true;
                    this.textareaFocus = false;
                    
                    // 比对算法,找出当前光标的位置,找到当前输入的位置
                    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;
                // 光标位置为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>

调用chat组件

...
<chat ref="chat" class="flex-sub"></chat>
...
//使用这种方法获取输入的内容
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>

效果展示


GIF 2021-9-1 16-56-58.gif

相关文章

网友评论

      本文标题:UniApp中实现类似微信聊天@功能

      本文链接:https://www.haomeiwen.com/subject/xhaxwltx.html