Vue 채 팅 창 구현

16154 단어 vue채 팅 창
본 논문 의 사례 는 Vue 가 채 팅 인터페이스 에서 보 여 주 는 구체 적 인 코드 를 공유 하여 여러분 께 참고 하 시기 바 랍 니 다.구체 적 인 내용 은 다음 과 같 습 니 다.
1.기능 요구 사항
색인 선택 에 따라 다른 사람과 채 팅 하기


2.코드 전시
mock.js:

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

let usermsg={
    id:"122",
    imgurl:"/static/image/8.jpg",
    words:"  !",
    data:{
        id:"1529",
        imgurl:"/static/image/7.jpg",
        name:"    ",
        words:[
            {info:"  ?"},
            {info:"  "},
            {info:"        "},
            {info:"                 "},
            {info:"         "},
            {info:"   "},
            {info:"       "},
            {info:"  "},
            {info:"      "}
        ]
    }
}
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
    }
  ]
})

//          
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: "  ",
      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)";
      //   dom        ,        (ChatDetail)
      //     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>
부모 구성 요 소 는 하위 구성 요소 의 속성 과 방법 을 사용 합 니 다:
부모 구성 요소 의 하위 구성 요소 에 ref 속성 을 정의 합 니 다.this.$refs.name 속성 이나 this.$refs.name 방법 을 통 해
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: {
    //       
    goback() {
      this.$router.go(-1);
    },
    //   input   
    changeSound() {
      //  data       isshow:false,  this.isshow !this.isshow    
      if (!this.isshow) {
        this.isshow = true;
        this.issound = "yuyin";
        this.istype = "button";
        this.isvalue = "     ";
      } else {
        this.isshow = false;
        this.issound = "xiaoxitongzhi";
        this.istype = "text";
        this.isvalue = "";
      }
    },
    //     
    sendmsg(e) {
      // 1、 ref         input   ,  sendcontent     value (     )
      let sendcontent = this.$refs.sendcontent.value;
      if (e.keyCode === 13 && sendcontent.split(" ").join("").length !== 0) {
        // 2、 ChatDetail( )    sendcontent(       )  tomsg  
        this.tomsg = sendcontent;
        // 3、 ref  ChatMsg( )  ,  mounted   $refs  , this.msgchild
        // 4、        ,  tomsg  ChatMsg( )  (       ) 
        this.msgchild.saveMsg(this.tomsg);
        // 5、         ,      
        this.$refs.sendcontent.value = "";
        //    ,             
        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">
    <!--      -->
    <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       
  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.디 렉 터 리 구조
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기