Vue implements chat interface

Vue implements chat interface

This article example shares the specific code of Vue to realize the display of the chat interface for your reference. The specific content is as follows

1. Functional requirements

Choose to chat with different people based on the index

2. Code display

mock.js:

import Mock from 'mockjs'
Mock.mock("/chatchild",{
    'result':[
        {
            id:"001",
            imgurl:"/static/image/10.jpg",
            name:"XKDK",
            date:"09:23",
            words:"Haha, ok"
        },
        // ... ...
    ]
});
export default Mock

userinfo.js:

let usermsg = {
    id:"122",
    imgurl:"/static/image/8.jpg",
    words:"Yes!",
    data:{
        id:"1529",
        imgurl:"/static/image/7.jpg",
        name:"Yi An Jushi",
        words:[
            {info:"Are you there?"},
            {info:"Not in"},
            {info:"Have you submitted the draft?"},
            {info:"I have been watching TV series since lunch today"},
            {info:"I found out that I am really a homebody"},
            {info:"Hahaha"},
            {info:"Let's have dinner together when I have time"},
            {info:"hmm"},
            {info:"It won't have much of an impact anyway"}
        ]
    }
}
export default usermsg

index.js:

import Vue from 'vue'
import Router from 'vue-router'
import Chat from '../components/Chat.vue'
import ChatDetail from '../components/Pages/ChatDetail.vue'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/Chat ',
      component: Chat 
    },
    {
      path:'/ChatDetail',
      component:ChatDetail
    }
  ]
})

// Code to solve routing errors const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
    return originalPush.call(this, location).catch(err => err)
}

Chat.vue:

<template>
  <div id="chat">
    <Bottom />
    <Header :name="msg" />
    <div class="chat_alluser">
      <div ref="chatuser" @click="checkChild(index)" class="chatuser" v-for="(item,index) in chat" :key="index">
        <ChatChild :imgsrc="item.imgurl" :nickname="item.name" :time="item.date" :word="item.words" />
      </div>
    </div>
  </div>
</template>

<script>
import Bottom from "../components/Menu/Bottom";
import Header from "../components/Menu/Header";
import ChatChild from "../components/Pages/ChatChild";
export default {
  name: "Chat",
  components:
    Bottom: Bottom,
    Header: Header,
    ChatChild: ChatChild
  },
  data() {
    return {
      msg: "WeChat",
      chat: null,
      name: null
    };
  },
  mounted() {
    this.$axios.get("/chatchild").then(res => {
      this.chat = res.data.result;
    });
  },
  methods: {
    checkChild(index) {
      this.$refs.chatuser[index].style.backgroundColor = "rgb(240,240,240)";
      // After the dynamic DOM element rendering is completed, jump to another interface (ChatDetail)
      // Get the dynamic name
      let username = this.chat[index].name;
      this.$nextTick(() => {
        this.$router.push({
          path: "/ChatDetail",
          query: { name: username }
        });
      });
    }
  }
};
</script>

<style lang="scss" scope>
#chat {
  width: 100%;
  .chat_alluser {
    margin-bottom: 7.5rem;
    .chatuser {
      position: relative;
      top: 3.5rem;
      padding: 0.3rem 0;
    }
  }
}
</style>

The parent component uses the properties and methods in the child component:
Define a ref attribute on a child component in a parent component, using the this.$refs.name. attribute or this.$refs.name. method

ChatChild.vue:

<template>
  <div id="chatchild">
    <div class="photo">
      <img :src="imgsrc" alt />
    </div>
    <div class="content">
      <div>
          <span class="content_nickname">{{nickname}}</span>
          <span class="content_time">{{time}}</span>
      </div>
      <span class="content_word">{{word}}</span>
    </div>
  </div>
</template>

<script>
export default {
  name: "ChatChild",
  props:{
    'imgsrc':String,
    'nickname':String,
    'time':String,
    'word':String
  }
};
</script>

<style lang="scss" scope>
#chatchild {
  width: 100%;
  height: 5rem;
  display: flex;
  flex-direction: row;
  box-sizing: border-box;
  .photo {
    flex: 1;
    height: 5rem;
    img{
        object-fit: cover;
        width: 4rem;
        height: 4rem;
        border-radius: 5px;
        display: block;
        margin: 0 auto;
        margin-top: 0.5rem;
        margin-left: 1rem;
    }
  }
  .content {
    flex: 4;
    height: 5rem;
    border-bottom: 0.5px solid rgb(240, 240, 240);
    padding-left: 0.5rem;
    padding-top: 0.5rem;
    box-sizing: border-box;
    div{
      .content_nickname{
        display: inline-block;
        font-size: 1.1rem;
        margin-top: 0.3rem;
      }
      .content_time{
        float: right;
        margin-right: 1rem;
        color: rgb(209, 206, 206);
        font-size: 0.8rem;
      }
    }
    .content_word{
      color: rgb(209, 206, 206);
      font-size: 0.8rem;
      display: block;
      margin-top: 0.5rem;
    }
  }
}
</style>

ChatDetail.vue:

<template>
  <div id="chatdetail">
    <div class="chattop">
      <div @click="goback" class="chattop_back">
        <icon-svg icon-class="houtui_shangyibu_zuojiantou_shangyiye" />
      </div>
      <div class="chattop_name">{{name}}</div>
      <div class="chattop_more">
        <icon-svg icon-class="gengduo" />
      </div>
    </div>
    <div class="chatcontent">
      <ChatMsg ref="chatmsg" />
    </div>
    <div class="chatfooter">
      <div @click="changeSound">
        <icon-svg :icon-class="issound" />
      </div>
      <div>
        <input ref="sendcontent" @keypress="sendmsg" :type="istype" :value="isvalue" />
      </div>
      <div>
        <icon-svg icon-class="biaoqing" />
      </div>
      <div>
        <icon-svg icon-class="del" />
      </div>
    </div>
  </div>
</template>

<script>
import ChatMsg from "./ChatMsg";
export default {
  name: "ChatDetail",
  data() {
    return {
      name: null,
      issound: "xiaoxitongzhi",
      istype: "text",
      isvalue: "",
      isshow: false,
      tomsg: "",
      msgchild: null
    };
  },
  components:
    ChatMsg: ChatMsg
  },
  mounted() {
    this.name = this.$route.query.name;
    this.msgchild = this.$refs.chatmsg;
  },
  methods: {
    // Perform the return operation goback() {
      this.$router.go(-1);
    },
    // Switch input type changeSound() {
      // Define a variable isshow:false in data, and use this.isshow and !this.isshow to switch if (!this.isshow) {
        this.isshow = true;
        this.issound = "yuyin";
        this.istype = "button";
        this.isvalue = "Press and hold to speak";
      } else {
        this.isshow = false;
        this.issound = "xiaoxitongzhi";
        this.istype = "text";
        this.isvalue = "";
      }
    },
    // Send a message sendmsg(e) {
      // 1. Use ref to define the input text box for entering the reply content, and define the sendcontent variable to receive its value (the input content)
      let sendcontent = this.$refs.sendcontent.value;
      if (e.keyCode === 13 && sendcontent.split(" ").join("").length !== 0) {
        // 2. Use tomsg to receive the sendcontent (the value entered in the text box) in the ChatDetail (parent) component this.tomsg = sendcontent;
        // 3. Define the ChatMsg (child) component with ref, and use $refs to obtain it in mounted, that is, this.msgchild
        // 4. Call the method in the child component and pass tomsg to the ChatMsg (child) component (specific chat content) this.msgchild.saveMsg(this.tomsg);
        // 5. After sending a message, you need to clear the text box this.$refs.sendcontent.value = "";
        // When pressing Enter, call the random message method of the child component this.msgchild.randomMsg();
      }
    }
  }
};
</script>

<style lang="scss" scope>
#chatdetail {
  position: relative;
  background-color: rgb(238, 212, 238);
  .chattop {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 10;
    width: 100%;
    height: 3.5rem;
    line-height: 3.5rem;
    background-color: rgb(240, 240, 240) !important;
    display: flex;
    flex-direction: row;
    .chattop_back {
      flex: 1;
      margin-left: 1rem;
    }
    .chattop_name {
      flex: 20;
      text-align: center;
    }
    .chattop_more {
      flex: 1;
      margin-right: 1rem;
    }
  }
  .chatcontent {
    width: 100%;
    height: 100%;
  }
  .chatfooter {
    position: fixed;
    left: 0;
    bottom: 0;
    z-index: 10;
    width: 100%;
    height: 3.5rem;
    line-height: 3.5rem;
    text-align: center;
    background-color: rgb(240, 240, 240) !important;
    display: flex;
    flex-direction: row;
    div:nth-child(1),
    div:nth-child(3),
    div:nth-child(4) {
      flex: 1;
      svg {
        font-size: 1.5rem;
        margin-top: 0.9rem;
      }
    }
    div:nth-child(2) {
      flex: 5;
      input {
        width: 100%;
        height: 2.5rem;
        outline: none;
        padding-left: 0.5rem;
        box-sizing: border-box;
        height: 2.5rem;
        margin-top: 0.5rem;
        border-style: none;
        font-size: 0.9rem;
        border-radius: 4px;
        background-color: #fff;
        color: #000;
      }
    }
  }
}
</style>

ChatMsg.vue:

<template>
  <div id="chatmsg" ref="msg">
    <!-- Dynamic creation -->
    <div v-for="(item,index) in lists" :key="index">
      <div v-if="item.id==122" class="user">
        <div v-scroll>
          <img :src="item.face" alt />
          <div class="bubble">
            <span>{{item.word}}</span>
          </div>
        </div>
      </div>
      <div v-if="item.id==1529" class="touser">
        <div v-scroll>
          <img :src="item.face" alt />
          <div class="tobubble">
            <span>{{item.word}}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import userinfo from "./userinfo";
export default {
  name: "ChatMsg",
  data() {
    return {
      userimg: "",
      lists: []
    };
  },
  mounted() {
    this.userid = userinfo.id;
    this.userimg = userinfo.imgurl;
  },
  // vue automatically scrolls to the bottom directives: {
    scroll: {
      inserted(el) {
        el.scrollIntoView();
      }
    }
  },
  methods: {
    saveMsg(tomsg) {
      this.lists.push({
        id: this.userid,
        face: this.userimg,
        word: tomsg
      });
    },
    randomMsg() {
      let touserdata = userinfo.data;
      this.lists.push({
        id: touserdata.id,
        face: touserdata.imgurl,
        word:
          touserdata.words[Math.floor(Math.random() * touserdata.words.length)]
            .info
      });
    }
  }
};
</script>

<style lang="scss" scope>
#chatmsg {
  position: relative;
  top: 3.5rem;
  width: 100%;
  min-height: 44rem;
  background-color: rgb(238, 212, 238);
  margin-bottom: 3.5rem;
  overflow-x:hidden;
  overflow-y: auto;
  .user {
    position: relative;
    width: 100%;
    overflow: hidden;
    margin: 0.8rem 0;
    img {
      object-fit: cover;
      width: 3rem;
      height: 3rem;
      border-radius: 3px;
      float: right;
      margin-right: 1rem;
    }
    .bubble {
      position: relative;
      float: right;
      margin-right: 1rem;
      padding: 0.8rem;
      box-sizing: border-box;
      border-radius: 3px;
      max-width: 65%;
      background-color: rgb(116, 228, 116);
      span {
        height: 1.25rem;
        line-height: 1.25rem;
      }
    }
    .bubble::after {
      position: absolute;
      right: -1.3rem;
      top: 0.8rem;
      content: "";
      width: 0;
      height: 0;
      border: 0.7rem solid;
      border-color: transparent transparent transparent rgb(116, 228, 116);
    }
  }
  .touser {
    position: relative;
    width: 100%;
    overflow: hidden;
    margin: 0.8rem 0;
    img {
      object-fit: cover;
      width: 3rem;
      height: 3rem;
      border-radius: 3px;
      float: left;
      margin-left: 1rem;
    }
    .tobubble {
      position: relative;
      float: left;
      margin-left: 1rem;
      padding: 0 0.7rem;
      box-sizing: border-box;
      border-radius: 3px;
      max-width: 65%;
      background-color: rgb(116, 228, 116);
      line-height: 3rem;
    }
    .tobubble::after {
      position: absolute;
      left: -1.3rem;
      top: 0.8rem;
      content: "";
      width: 0;
      height: 0;
      border: 0.7rem solid;
      border-color: transparent rgb(116, 228, 116) transparent transparent;
    }
  }
}
</style>

3. Directory Structure

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • Vue+express+Socket realizes chat function
  • Vue realizes web online chat function
  • Vue+web terminal imitates WeChat web version chat room function
  • Vue.js imitates WeChat chat window to display component functions
  • Vue + socket.io implements a simple chat room sample code
  • A single-page application function imitating mobile QQ based on Vue2 (access to chatbot)
  • How to use RongCloud IM to implement chat function in Vue Cli 3 project
  • WeChat robot chat function example implemented by Vue [with source code download]
  • Multi-person online chat room based on vue and websocket
  • Vue+ssh framework to realize online chat

<<:  Oracle VM VirtualBox installation of CentOS7 operating system tutorial diagram

>>:  MySQL character set garbled characters and solutions

Recommend

mysql5.7 create user authorization delete user revoke authorization

1. Create a user: Order: CREATE USER 'usernam...

Briefly explain the use of group by in sql statements

1. Overview Group by means to group data accordin...

Add a floating prompt for the header icon in the ElementUI table

This article mainly introduces how to add floatin...

How to modify the IP restriction conditions of MySQL account

Preface Recently, I encountered a requirement at ...

Several techniques for playing sounds with CSS

CSS is the realm of style, layout, and presentati...

In-depth understanding of the matching logic of Server and Location in Nginx

Server matching logic When Nginx decides which se...

MySql 5.7.21 free installation version configuration method under win10

1. Unzip to the location where you want to instal...

Detailed tutorial on distributed operation of jmeter in docker environment

1. Build the basic image of jmeter The Dockerfile...

The easiest way to make a program run automatically at startup in Linux

I collected a lot of them, but all ended in failu...

Detailed process of upgrading gcc (version 10.2.0) under CentOS7 environment

Table of contents Short Introduction 1. Check the...

React Synthetic Events Explained

Table of contents Start by clicking the input box...

Docker deploys net5 program to achieve cross-platform functions

Deployment environment: docker container, liunx s...

MySQL 5.7.19 (tar.gz) installation graphic tutorial under Linux

The first tutorial for installing MySQL-5.7.19 ve...

Analysis and solutions to problems encountered in the use of label tags

I used the label tag when I was doing something re...