当前位置:   article > 正文

vue实现基本对话功能_vue 实现聊天对话框

vue 实现聊天对话框

基于vue3.0实现的简易对话功能,仿照微信、QQ聊天界面。

HTML代码块

  1. <template>
  2. <el-container style="height: 100%" ref="bodyform">
  3. <div class="el_main_content">
  4. <div class="main_content_header">这是一个对话框</div>
  5. <div class="main_content_center">
  6. <el-scrollbar
  7. class="faultExpertConsultation_scrollbar"
  8. ref="scrollbarRef"
  9. >
  10. <!--对话内容-->
  11. <div
  12. v-for="(item, index) in messagesWithTimestamps"
  13. :key="index"
  14. v-show="messagesWithTimestamps.length > 0"
  15. >
  16. <!--对话时间-->
  17. <div v-if="item.showTime" class="chat_time">
  18. {{ formatSendTime(item.timestamp) }}
  19. </div>
  20. <!--提问-->
  21. <div class="question chat">
  22. <div class="chat_question chat_common">
  23. <span>{{ item.question }}</span>
  24. </div>
  25. <el-avatar class="avatar">
  26. <span class="me"></span>
  27. </el-avatar>
  28. </div>
  29. <!--回答-->
  30. <div class="answer chat" v-if="item.answer">
  31. <el-avatar :src="robot" />
  32. <div class="chat_answer chat_common">
  33. <span>{{ item.answer }}</span>
  34. </div>
  35. </div>
  36. </div>
  37. </el-scrollbar>
  38. </div>
  39. <div class="main_content_footer">
  40. <div class="input_box">
  41. <textarea class="chat-input no-border" v-model="question" />
  42. </div>
  43. <div class="btn_box">
  44. <el-button type="primary" class="btn" @click="askClick(question)"
  45. >发送</el-button
  46. >
  47. </div>
  48. </div>
  49. </div>
  50. </el-container>
  51. </template>

JavaScript代码块

  1. <script setup>
  2. import { ref, onMounted, nextTick, computed, watch } from "vue";
  3. import { ElMessage, ElMessageBox } from "element-plus";
  4. const question = ref(""); //输入框值
  5. const chatList = ref([]); //循环的聊天数组
  6. const scrollbarRef = ref(null);
  7. //创建新的对话数组,加上属性showTime
  8. const messagesWithTimestamps = computed(() => {
  9. return chatList.value.map((item, index) => ({
  10. ...item,
  11. showTime: index === 0 || shouldShowTime(index),
  12. }));
  13. });
  14. //计算两次会话时间是否超过3分钟方法
  15. const shouldShowTime = (index) => {
  16. const current = new Date(chatList.value[index - 1].timestamp);
  17. const next = new Date(chatList.value[index].timestamp);
  18. const diff = next ? next - current : 0;
  19. return diff > 3 * 60 * 1000; // 如果间隔超过3分钟返回true
  20. };
  21. //提问方法
  22. const askClick = (val) => {
  23. if (val != "") {
  24. chatList.value.push({
  25. question: val, //问题
  26. answer: "", //回答
  27. timestamp: new Date(), //时间戳
  28. to: "", //接收者
  29. form: "", //发送者
  30. });
  31. } else {
  32. ElMessage("不能发送空白消息");
  33. }
  34. };
  35. //滚动事件到底部事件
  36. const scrollToBottom = () => {
  37. nextTick(() => {
  38. let chat = document.querySelector(".main_content_center");
  39. scrollbarRef.value.wrapRef.scrollTop = chat.scrollHeight;
  40. });
  41. };
  42. watch(
  43. chatList.value,
  44. (newVal, oldVal) => {
  45. scrollToBottom();
  46. },
  47. { immediate: true }
  48. );
  49. const formatSendTime = (sendTime) => {
  50. const now = new Date();
  51. const sendDate = new Date(sendTime);
  52. // 计算时间差(以毫秒为单位)
  53. const timeDiff = now - sendDate;
  54. const startOfToday = new Date(
  55. now.getFullYear(),
  56. now.getMonth(),
  57. now.getDate()
  58. );
  59. const startOfTargetDate = new Date(
  60. sendDate.getFullYear(),
  61. sendDate.getMonth(),
  62. sendDate.getDate()
  63. );
  64. // 一天内的毫秒数
  65. const oneDay = 24 * 60 * 60 * 1000;
  66. // 如果发送时间在当前时间之前
  67. if (timeDiff < 0) {
  68. return "Invalid time"; // 或者其他错误处理
  69. }
  70. // 发生在同一天
  71. if (startOfToday.getTime() === startOfTargetDate.getTime()) {
  72. return formatTime(sendDate);
  73. }
  74. // 如果发送时间在一天内
  75. if (timeDiff < oneDay) {
  76. return "昨天 " + formatTime(sendDate);
  77. }
  78. // 如果发送时间在二天至七天内
  79. if (timeDiff < 7 * oneDay) {
  80. const weekday = getWeekday(sendDate);
  81. return weekday + " " + formatTime(sendDate);
  82. }
  83. // 如果发送时间超过七天
  84. return (
  85. sendDate.toLocaleDateString("zh-CN", {
  86. year: "numeric",
  87. month: "2-digit",
  88. day: "2-digit",
  89. }) +
  90. " " +
  91. formatTime(sendDate)
  92. );
  93. };
  94. const formatTime = (date) => {
  95. // 格式化时间为“时:分”
  96. const hours = date.getHours().toString().padStart(2, "0");
  97. const minutes = date.getMinutes().toString().padStart(2, "0");
  98. return hours + ":" + minutes;
  99. };
  100. const getWeekday = (date) => {
  101. // 获取星期几的中文表示
  102. const weekdays = [
  103. "星期天",
  104. "星期一",
  105. "星期二",
  106. "星期三",
  107. "星期四",
  108. "星期五",
  109. "星期六",
  110. ];
  111. return weekdays[date.getDay()];
  112. };
  113. </script>

CSS代码块

  1. <style>
  2. .no-border {
  3. border: none;
  4. /* 可选的样式,以去除焦点时的边框(如果需要的话) */
  5. outline: none;
  6. width: none;
  7. height: none;
  8. resize: none;
  9. }
  10. </style>
  11. <style lang="less" scoped>
  12. .el_main_content {
  13. width: 50%;
  14. height: 70%;
  15. border-radius: 5px;
  16. border: 1px solid #e4e7ed;
  17. box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
  18. margin: auto;
  19. .main_content_header {
  20. width: 100%;
  21. height: 50px;
  22. border-radius: 5px;
  23. background-color: #7de0bd;
  24. display: flex;
  25. align-items: center;
  26. justify-content: center;
  27. font-size: 16px;
  28. }
  29. .main_content_center {
  30. width: 100%;
  31. position: relative;
  32. height: calc(100% - 170px);
  33. margin: 10px 0px;
  34. .chat_time {
  35. display: flex;
  36. justify-content: center;
  37. font-size: 10px;
  38. }
  39. .question {
  40. justify-content: flex-end;
  41. }
  42. .chat_question {
  43. background-color: #8ce45f;
  44. margin-right: 5px;
  45. color: #ffffff;
  46. }
  47. .chat_answer {
  48. background-color: #f2f3f5;
  49. margin-left: 5px;
  50. }
  51. .chat {
  52. width: 98%;
  53. margin: 10px auto;
  54. display: flex;
  55. }
  56. .chat_common {
  57. max-width: 40%;
  58. padding: 10px;
  59. border-radius: 2px;
  60. word-break: break-all;
  61. display: flex;
  62. align-items: center;
  63. }
  64. .avatar {
  65. background-color: #409eff;
  66. border: 2px solid #409eff;
  67. }
  68. .me {
  69. font-size: 16px;
  70. color: #ffffff;
  71. font-weight: bold;
  72. }
  73. }
  74. .main_content_footer {
  75. width: 100%;
  76. height: 100px;
  77. border-top: 1px solid #e4e7ed;
  78. .input_box {
  79. width: 100%;
  80. height: 60px;
  81. .chat-input {
  82. width: calc(100% - 20px);
  83. padding: 10px;
  84. margin: auto;
  85. }
  86. }
  87. .btn_box {
  88. width: 100%;
  89. height: 40px;
  90. display: flex;
  91. justify-content: flex-end;
  92. align-items: center;
  93. .btn {
  94. margin-right: 10px;
  95. }
  96. }
  97. }
  98. }
  99. </style>

运行效果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/761355?site
推荐阅读
相关标签
  

闽ICP备14008679号