美文网首页
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