Home > database >  VueJS: Determine the source that triggers the watch callback
VueJS: Determine the source that triggers the watch callback

Time:06-25

I watch a property of an object device.flow. When the property changes, the callback gets triggered. That all works and is fine.

I only want though that the callback gets triggered if the user actually manipulates the form component that uses that watched property as model.

There's also a periodic API call to get the current data of the device as it might change due to other circumstances than just user input. The slider should then adjust accordingly as well but the web socket event should not be emitted because that is unnecessary.

To illustrate what I want to achieve, I attached a simple component below and added a comment, where I want to distinguish the source of the property change.

Is this even possible?

<script setup lang="ts">
import type DeviceAirValve from "../../../model/DeviceAirValve";
import {reactive, ref, watch} from "vue";
import {useSocketIO} from "../../../plugins/vueSocketIOClient.js";
import type {Socket} from "socket.io-client";

interface Props {
  device: DeviceAirValve
}

const props = defineProps<Props>();
const io = useSocketIO() as Socket;

let device = reactive<DeviceAirValve>(props.device);

watch(
    () => device.flow,
    flow => {
        // Determine whether the callback gets called because 
        // the value was changed by the user through the v-slider component,
        // or if the device.flow property has been updated by something else
        // (for example a periodic poll from an API) -> isFormInput variable
        if (isFormInput) {
            flowChangeHandler(flow)
        }
    }
);

const flowChangeHandler = (newFlow: number): void => {
  io.emit('deviceUpdate', {
    deviceId: props.device.deviceId,
    data: {flow: newFlow}
  });
};
</script>

<template>
    <v-slider v-model="device.flow"></v-slider>
</template>

CodePudding user response:

One solution is to replace the watcher with an event handler for v-slider's update:modelValue event (the event that drives v-model, which is only triggered by user input):

<v-slider @update:modelValue="flowChangeHandler" />

demo

  • Related