项目前端搭建

 参考项目地址:https://gitee.com/mao-yongyao/chatroom

目前效果

实现了FreeChat界面,用户可与大模型自由对话

界面布局

布局分为左边侧边栏和右边实际界面

<template>
  <div class="home">
    <el-container height="100%">
      <el-aside width="100px">
        <Nav></Nav>
      </el-aside>
      <el-main>
        <router-view></router-view>
      </el-main>
    </el-container>
  </div>
</template>

FreeChat实际界面布局分为左边聊天列表与右边的聊天窗口 

<template>
  <div class="chatHome">
    <div class="chatLeft">
      <div class="title">
        <br/>
        <br/>
        <h1>FileChat</h1>
      </div>
      <div class="online-person">
        <input type="file" ref="fileInput" style="display: none" @change="handleFileChange">
        <div class="add-butt" @click="add_file">添加文件</div>
        <span class="onlin-text">聊天列表</span>
        <div class="person-cards-wrapper">
          <div
            class="personList"
            v-for="personInfo in personList"
            :key="personInfo.id"
            @click="clickPerson(personInfo)"
          >
            <PersonCard
              @transmit="delete_one_chat"
              :personInfo="personInfo"
              :pcCurrent="pcCurrent"
            ></PersonCard>
          </div>
        </div>
      </div>
    </div>
    <div class="chatRight">
      <div v-if="showChatWindow">
        <ChatWindow
          :frinedInfo="chatWindowInfo"
        ></ChatWindow>
      </div>
      <div class="showIcon" v-else>
        <span class="iconfont icon-snapchat"></span>
      </div>
    </div>
  </div>
</template>

聊天窗口布局为对话框和输入框

<template>
  <div class="chat-window">
    <div class="botoom">
      <div class="chat-content" ref="chatContent">
        <div class="chat-wrapper" v-for="(item, index) in chatList" :key="item.id">
          <div class="chat-friend" v-if="item.uid !== '1001'">
            <div class="info-time">
              <img :src="item.headImg" alt="" />
              <span>{{ item.name }}</span>
              <span>{{ item.time }}</span>
            </div>
            <div class="chat-text" v-if="item.chatType == 0">
              <template v-if="isSend && index == chatList.length - 1">
                <span class="flash_cursor"></span>
              </template>
              <template v-else><template><div v-hljs v-html="item.msg"></div></template></template>
            </div>
          </div>
          <div class="chat-me" v-else>
            <div class="info-time">
              <span>{{ item.name }}</span>
              <span>{{ item.time }}</span>
              <img :src="item.headImg" alt="" />
            </div>
            <div class="chat-text" v-if="item.chatType == 0">
              {{ item.msg }}
            </div>
          </div>
        </div>
      </div>
      <div class="chatInputs">
        <textarea class="inputs" v-model="inputMsg" @keydown="handleKeydown"></textarea>
        <el-button class="send boxinput" :disabled = "isSend" @click="sendText">
          <img v-if="!this.isSend" src="@/assets/img/emoji/rocket.png" alt="" />
          <i class="el-icon-loading" v-if="this.isSend"></i>
        </el-button>
      </div>
    </div>
  </div>
</template>

代码高亮

使用highlight.js库,在main.js注册为组件,这样以v-hljs为属性的标签里被pre和code标签包裹的内容就会被渲染成代码高亮的样式

Vue.directive('hljs', {
  inserted: el => {
    let codes = el.querySelectorAll('pre code');
    Array.prototype.forEach.call(codes, code => {
      hljs.highlightElement(code); 
      const language = code.className.split(/\s+/).find(className => className.startsWith('language-'))?.replace('language-', '');
      if (code.parentNode.tagName.toLowerCase() === 'pre') {
        const languageSpan = document.createElement('span');  
        languageSpan.className = 'code-language'; 
        languageSpan.textContent = language;  
        const copyButton = document.createElement('button');
        copyButton.className = 'copy-button';
        copyButton.textContent = 'Copy';
        copyButton.addEventListener('click', () => {
          // Copy code to clipboard
          const codeText = code.textContent;
          navigator.clipboard.writeText(codeText).then(() => {
            alert('Code copied to clipboard!');
          }).catch(err => {
            console.error('Unable to copy code: ', err);
          });
        });
        code.parentNode.appendChild(languageSpan)
        code.parentNode.appendChild(copyButton);
      }
    });
  }
});

由于hljs组件只能解析html格式的内容,我们需要将大模型传来的md格式转化为HTML格式,使用Showdown

import Showdown from "showdown";
 
 let converter = new Showdown.Converter();
 let htmlStr=res.msg;
 let convertedHtml = converter.makeHtml(htmlStr);
 this.chatList[this.chatList.length-1].msg = convertedHtml;

多会话与持久化储存

将聊天记录存储到localStorage以实现多会话与持久化储存

新建会话

add_chat(){
      let new_chat = {
            name: "new_chat",
            id: generateUUID(),
            time: new Date().toLocaleString(),
            type : 0,
      }
      this.personList.push(new_chat)
      localStorage.setItem("chats", JSON.stringify(this.personList));
    },

删除会话

delete_one_chat(data){
      let chats = JSON.parse(localStorage.getItem("chats"));
      for(let i=0;i<chats.length;i++){
        if(chats[i].id==data){
          chats.splice(i,1);
        }
      }
      localStorage.setItem("chats", JSON.stringify(chats));
      let history = JSON.parse(localStorage.getItem("history"));
      for(let i=0;i<history.length;i++){
        if(history[i].uuid==data){
          history.splice(i,1);
        }
      }
      localStorage.setItem("history", JSON.stringify(history));
      this.personList = chats;
      this.showChatWindow = false;
    },

获取单个会话的聊天记录

mounted() {
    let history = JSON.parse(localStorage.getItem("history"));
    let flag = false;
    for(let i=0;i<history.length;i++){
      if(history[i].uuid == this.frinedInfo.id){
        this.chatList=history[i].data;
        flag = true;
        break;
      }
    }
    if(!flag){
      this.chatList=[]
    }
    this.$nextTick(() => {
      const scrollDom = this.$refs.chatContent;
      scrollDom.scrollTop = scrollDom.scrollHeight;
    });
  },

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
搭建前端Vue项目的流程如下: 1. 环境准备:确保已经安装了Node.js和npm(或者使用yarn)。 2. 安装Vue CLI:使用npm或yarn全局安装Vue CLI,命令为:`npm install -g @vue/cli` 或 `yarn global add @vue/cli`。 3. 创建新项目:在命令行中执行`vue create 项目名`命令,创建一个新的Vue项目。你可以选择手动配置选项或使用默认配置。 4. 选择配置:如果选择手动配置,会出现一系列问题,包括选择Vue版本、Babel和TypeScript的配置、是否使用ESLint等。根据项目需求进行选择并进行相应的配置。 5. 安装依赖:等待项目创建完成后,进入项目目录,执行`npm install` 或 `yarn install`命令,安装项目所需的依赖。 6. 开发与构建:执行`npm run serve`或`yarn serve`命令,启动开发服务器,开始开发调试。在开发过程中,可以通过修改src目录下的文件来编写Vue组件和逻辑代码。 7. 页面和组件开发:根据项目需求,设计和编写页面和组件。Vue项目中,页面通常由多个组件组成,可以使用单文件组件(.vue文件)来编写组件。 8. 数据管理和路由配置:根据需要,可以选择使用Vue提供的状态管理工具Vuex来管理应用的状态,并配置Vue Router来实现前端路由。 9. 调试和测试:在开发过程中,可以使用Vue Devtools等工具进行调试和性能优化。同时,可以编写单元测试和端到端测试来确保项目的质量。 10. 打包和部署:在开发完成后,执行`npm run build`或`yarn build`命令,将项目打包成静态文件。将生成的dist目录中的文件部署到服务器或云平台上即可。 以上是搭建前端Vue项目的一般流程,根据实际需求和团队偏好,可能会有一些微调。祝你搭建项目顺利!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值