Vue 3's equivalent to useEffect (React)
Asked Answered
T

1

14

This code is working, but I'm new to Vue.js and I can't help but think there's a cleaner way of doing this.

In particular I mean the parts that set the data upon entrance and update (of store state) in case it's the first page you visit (or reload). I have a store that fetches data from the backend when the site loads, but that's probably obvious.

I just feel like I'm repeating myself when calling this.getTodo(); from both watch and mounted.

<template>
  <div>
    <h2>Details Page</h2>
    {{ title }}
    {{ content }}
    {{ lastEditTime }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: '',
      content: '',
      lastEditTime: ''
    }
  },
  methods: {
    getTodo () {
      if (this.$store.state.list.length > 0) {
        const id = this.$route.params.id;
        const todoItem = this.$store.getters.getItem(id);
        Object.assign(this, todoItem);
      }
    }
  },
  watch: {
    '$store.state.list': {
      handler() {
        this.getTodo();
      }
    } 
  },
  mounted () {
    this.getTodo();
  }
}
</script>
Tranship answered 22/11, 2021 at 20:46 Comment(0)
E
17

Add immediate flag to your watcher. That way it runs on mounted as well as every time the $store.state.list changes.

  watch: {
    '$store.state.list': {
      handler() {
        this.getTodo();
      },
      immediate: true
    } 
  }

Update:

As pointed out by @Thomas, you can also use watchEffect : https://v3.vuejs.org/api/computed-watch-api.html#watcheffect

Escobedo answered 22/11, 2021 at 21:38 Comment(4)
Or use v3.vuejs.org/api/computed-watch-api.html#watcheffectGodmother
Just curios, is watchEffect accessible via Options API?Escobedo
should be as it is documented in the general area not the composition APIGodmother
Thomas's solution is more equivalent because watchEffect can depend on multiple states same as useEffectGunthar

© 2022 - 2024 — McMap. All rights reserved.