Search code examples
javascriptvue.jswatch

Why watch is not execute when history is change


<script setup>
import InputChat from '../components/InputChat.vue'
import Chat from '../components/Chat.vue'
import Layout from "@/components/Layout.vue";
import Sidebar from "@/components/Sidebar.vue";
import ChatVue from '@/components/Chat.vue';
import { ChatManager } from '../../lib/ChatManager';
import { ref, watch } from 'vue';
const manager = new ChatManager()
const historys = ref(manager.historys)

watch( historys ,(newHistory)=>{
  console.log("Watch execute");
  console.log(newHistory)
  console.log(historys.value);
},{deep:true})
const handleSentMessage = (value)=>{
  console.log(value + "Parent receive yet");
  manager.sentChat(value)
}
</script>

<template>
  <Layout>
    <template #sidebar>
      <Sidebar />
    </template>
    <template #chat>
      <Chat :history="manager.history"/>
    </template>
    <template #input-chat>
      <InputChat @sent-message = "handleSentMessage"/>
    </template>
  </Layout>
</template>


export class ChatManager {
   

  constructor() {
    this.url = import.meta.env.VITE_API_URL || 'http://localhost:11434/api'
    this.historys = [];
    
  }
  async sentChat(message){
    const messageTemplate = {
      request:{
        role:"user",
        content: ''
      },
      response:{
        role:'assistant',
        content:''
      }
    }
    
    try {
      messageTemplate.request.content = message

      
      this.historys.push(messageTemplate)
      const response = await fetch(`${this.url}/chat`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          model: "llama2",
          messages: [
            {
              role: "user",
              content: message
            }
          ],
          stream: false
        })
      });

      const data = await response.json();
      console.log(data)
       this.historys[this.historys.length-1].response.content = data.message.content
       this.historys[this.historys.length-1].response.role = data.message.role
      return data;

  }
  catch(error){
    console.log(error);
  }
}

}

When history is change why watch is not execute i want when history is change watch is execute but now when history is change watch is not execute please help me


Solution

  • ChatManager refers non-reactive historys array that cannot be watched.

    The class should either explicitly use reactive for the fields, or can be made reactive when instantiated:

    const manager = reactive(new ChatManager())
    const historys = toRef(manager, 'historys')
    
    watch(historys, ...)
    

    Reactive classes have several pitfalls that require to implement them in a restricted way that's compatible with Vue reactivity. None of them are applicable to ChatManager so far.