Search code examples
typescriptvue.jsvue-property-decorator

Vue @Watch not triggering on a boolean change


I'm trying to use watch functions in vue-ts. I've set up a watch function that fires whenever a Boolean variable value is changed, it doesn't fire at all and I can't figure out why.

my code:

here's the data declaration

<script lang="ts">
import { Vue, Component, Prop, Watch } from "vue-property-decorator";
import { CSSModule } from "@/Services/Modules/CSSModule";

@Component({})
export default class CommentCard extends Vue {
  @Prop() comment!: Object;
  @Prop() cmEditor!: Object;
  @Prop() nextCommentDistance!: number;
  @Prop({ default: 300 }) width!: number;
  @Prop() commentIndex!: number;
  private initialHeight: string;
  private textMarker: Object;
  private cssModule: Object;
  private isFocused: boolean;

on mounted I'm changing the data value, so the watch should be triggered

  mounted() {
    this.setDivHeight();
    this.isFocused = false;
  }

And here's the function

  @Watch("isFocused")
  highlightComment() {
    if (this.textMarker) {
      this.textMarker.clear();
    }
    const css = this.isFocused
      ? "background-color: " +
        this.cssModule.hexToRgba(this.comment.typeColor, 0.5)
      : "background-color: " +
        this.cssModule.hexToRgba(this.comment.typeColor, 0.8) +
        "; box-shadow: 5px 5px 4px rgb(23,24,26)";
    let locations = this.comment.serialize.replace("N", "");
    locations = locations.split(",");
    let startLocation = locations[0].split(":");
    let endLocation = locations[1].split(":");
    this.textMarker = this.cmEditor.markText(
      { line: parseInt(startLocation[0]), ch: parseInt(startLocation[1]) },
      { line: parseInt(endLocation[0]), ch: parseInt(endLocation[1]) },
      {
        css: css,
      }
    );
  }

It doesn't get called at all, and I'm even changing the value of isFocused with a button after mounting, but it still fire the watch.

Thanks.


Solution

  • You have to initialise your properties for them to be reactive.

    Instead of:

    private isFocused: boolean;
    

    Use

    private isFocused: boolean = false;
    

    You should do this for every property in your Vue application. Note that you can use null; as long as the property is not undefined, it will work.

    For more informations, see: https://v2.vuejs.org/v2/guide/reactivity.html