创新实训——前端聊天界面的侧边栏

介绍

侧边栏对会话组进行了管理,保存用户的历史会话,方便查看,便于双屏对照内容,提高工作效率。其具有显示历史会话、新建会话、删除会话和修改会话标题等功能。

显示会话

从本地存储(localStorage)中加载聊天对话列表,确保即使没有保存的对话或者保存的数据损坏,应用也能正确地初始化对话列表,并能够在有有效数据时加载这些数据。

loadConversationFromLocal() {
      // 尝试从localStorage获取保存的对话列表
      const savedConversations = localStorage.getItem('conversations');

      // 检查是否有数据,如果有,解析JSON格式的字符串转换回数组
      if (savedConversations) {
        try {
          // 将JSON字符串转换成JavaScript对象
          this.setConversationList(JSON.parse(savedConversations));

        } catch (e) {
          // 如果解析出错,可能是数据损坏或格式不正确
          console.error('Failed to parse conversations from localStorage:', e);
          // 可以选择清空损坏的数据或给出错误提示
          this.conversations = [];
        }
      } else {
        // 如果本地存储中没有对话列表,初始化为空数组
        this.conversations = [];
      }
    }

新建会话

创建一个新的会话对象,将该对象添加到会话列表的前面,保存所有会话到本地存储,并选择最新的会话作为活动状态。

当用户在输入框中点击发送按钮且没有现有会话时,将通过总线机制在兄弟组件间传递消息以创建新的会话。具体来说,总线系统会监听bus-send事件,一旦该事件被触发,busSend方法就会被调用。这个方法会检查Vuex中的会话ID,并在会话列表中寻找对应的会话。如果没有找到,则会创建一个新的会话对象,并将其消息列表设置为当前的messageList,确保用户刚输入的消息成为新会话的一部分。

newChat(msgList) {
      this.chatTitle = "New chat";
      document.title = "New chat";

      let newConv = {
        "id": Date.now(),
        "title": "New chat",
        "msgList": msgList,
      }

      //add the conv to the list
      this.unshiftConversationList(newConv);
      //save the conv list to local storage
      this.saveConversations();
      this.selectConversation(this.conversations.length - 1);
    }

unshiftConversationList方法将新创建的会话对象newConv添加到现有会话列表的前面。unshift是JavaScript数组的一个方法,它会在数组的开头添加一个或多个元素,并返回新的长度。

saveConversations方法调用保存所有会话到本地存储,以便即使页面刷新或重新加载,会话也能持久化保存。

saveConversations() {
      var conversations = JSON.parse(JSON.stringify(this.getConversationList));
      for (let idx in conversations) {
        var conv = conversations[idx];
        delete conv.editable;
        delete conv.selected;
        delete conv.delete;
      }
      let convs = JSON.stringify(conversations);
      localStorage.setItem("conversations", convs);
    }

selectConversation方法选择最新的会话,即刚创建的会话,使它成为活动状态,用户可以看到并与之交互。

selectConversation(cidx) {
      if (cidx < 0 || cidx >= this.getConversationList.length) {
        console.log("invalid index")
        return;
      }
      //get the conversation which you want to select by index
      var conv = this.getConversationByIndex(cidx);
      //if the conversation is already selected, return
      if (this.oldConv && this.oldConv.id == conv.id) {
        console.log("same conversation")
        return;
      }
      //set the old conversation to unselected
      if (this.oldConv) {
        this.oldConv.selected = false;
      }
      //set the new conversation to selected
      conv.selected = true
      this.setSelectedIdx(cidx);
      this.oldConv = conv;

      document.title = conv.title || "chatai";
      this.chatTitle = conv.title || "chatai";

      //set the conversation to vuex
      this.setConversation(conv);
      this.conversations[cidx] = conv;

    }

删除会话

state是一个包含聊天会话列表的状态对象,index是要从列表中删除的会话的索引,删除指定索引的聊天会话。在不可变数据结构的应用中,通常会返回一个新的状态对象而不是修改原始对象。

delConversationByIndex(state:stateType, index:number) {
            if (state.conversationList != null&&state.conversationList.length>index)
            state.conversationList.splice(index, 1);

            else console.log("delConversationByIndex fail",state.conversationList,index);
        }

清空所有历史会话

clearConversations() {
      this.conversations = []
      this.saveConversations();
    }

会话选择

选择一个特定的聊天对话,并更新页面状态以反映这一选择。在用户选择不同的对话时,更新当前状态,包括选中的对话、浏览器标签页的标题和可能的状态管理库中的状态。

selectConversation(cidx) {
      if (cidx < 0 || cidx >= this.getConversationList.length) {
        console.log("invalid index")
        return;
      }
      //get the conversation which you want to select by index
      var conv = this.getConversationByIndex(cidx);
      //if the conversation is already selected, return
      if (this.oldConv && this.oldConv.id == conv.id) {
        console.log("same conversation")
        return;
      }
      //set the old conversation to unselected
      if (this.oldConv) {
        this.oldConv.selected = false;
      }
      //set the new conversation to selected
      conv.selected = true
      this.setSelectedIdx(cidx);
      this.oldConv = conv;

      document.title = conv.title || "chatai";
      this.chatTitle = conv.title || "chatai";

      //set the conversation to vuex
      this.setConversation(conv);
      this.conversations[cidx] = conv;

    }

修改会话

用户可编辑指定索引的聊天对话标题,提供了一个用户友好的方式来编辑聊天对话的标题,通过设置对话的可编辑状态,并提供自动聚焦输入框的功能。

下述方法会将对应会话的editable属性设置为true,表明会话标题现在处于可编辑状态。同时,方法还会将会话当前的title存储在convTitletmp变量中,以便在需要时恢复原始标题。一旦editable属性被设置为true,这将触发v-if指令,进而改变DOM的渲染。原本显示标题的文本将转换成一个输入框,其初始内容为convTitletmp变量的值。这样用户就可以直接在输入框中编辑标题,而无需手动点击输入框。

editTitle(cidx) {
      if (cidx < 0 || cidx >= this.conversations.length) {
        alert("invalid index")
        console.log("invalid index")
        return;
      }
      var conv = this.conversations[cidx];
      this.convTitletmp = conv.title;
      conv.editable = true;
      this.conversations[cidx] = conv;
      setTimeout(() => {
        document.getElementById("titleInput").focus();
      }, 150)
    }

取消修改

在用户取消编辑对话标题时,将对话的editable属性设置为false,并更新对话列表(如果取消注释的话),以确保用户界面正确地反映出对话标题的编辑状态。

cancelChangeConvTitle(idx, conv) {
      conv.editable = false;
      //this.conversations[idx] = conv;
    }

确认修改

修改会话对象的标题,调用方法修改vuex中全局的conversationList对象,调用saveConversations方法,把conversations保存到loacalStorage中。

changeConvTitle(idx, conv) {
      conv.title = this.convTitletmp;
      this.setConversationByIndex({ cidx: idx, conv: conv });
      this.saveConversations();
      this.cancelChangeConvTitle(idx, conv)
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值