最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to make Global State in vue 3? - Stack Overflow

programmeradmin3浏览0评论

I have created a reactive value but I want it to change from the entire application.

To create the reactive state I have src/store/index.js that contains

// ** src/store/index.js

export function useTimer() {
  const timer = ref(false);

  const toggleTimer = () => {
    if (timer.value == false) {
      timer.value = true;
    } else {
      timer.value = false;
    }
  };

  return { timer, toggleTimer };
}

And I am using these values in ponents

// ** src/app.vue 

<template>
  <Scores/>
  <button @click="switchtimer()">switch at app</button>
</template>

<script>
import { isRef } from "vue";
import { useTimer } from "./store";
import Scores from "./ponents/Scores.vue";

export default {
  ponents: {
    Scores
  },
  setup() {

    const { timer, toggleTimer } = useTimer();

    function switchtimer() {
      console.log(isRef(timer));    // true
      toggleTimer();

    }
    return { switchtimer };
  },
};
</script>
// ** src/ponents/Scores.vue

<template>
  <button @click="switchtimer()">switch at scores</button>
  <p>{{ timer }}</p>
</template>

<script>
import { isRef } from "vue";
import { useTimer } from "../store";

export default {
  name: "Scores",
  setup() {

    const { timer, toggleTimer } = useTimer();

    function switchtimer() {
      console.log(isRef(timer));    // true
      toggleTimer();

    }
    return { timer, switchtimer };
  },
};
</script>

Scores.vue is imported in app.vue as ponent. There is no importing issue in the app even if there is any mistakes I did in this description. That mistake might have occurred during rewriting while posting this.

When switch at scores button pressed the timer toggles in scores ponent, but switch at app button pressed the timer does not toggles in scores ponent.

I want to have timer as global state, so that when changed it from app.vue, the changed value also shown in scores.vue.

I have created a reactive value but I want it to change from the entire application.

To create the reactive state I have src/store/index.js that contains

// ** src/store/index.js

export function useTimer() {
  const timer = ref(false);

  const toggleTimer = () => {
    if (timer.value == false) {
      timer.value = true;
    } else {
      timer.value = false;
    }
  };

  return { timer, toggleTimer };
}

And I am using these values in ponents

// ** src/app.vue 

<template>
  <Scores/>
  <button @click="switchtimer()">switch at app</button>
</template>

<script>
import { isRef } from "vue";
import { useTimer } from "./store";
import Scores from "./ponents/Scores.vue";

export default {
  ponents: {
    Scores
  },
  setup() {

    const { timer, toggleTimer } = useTimer();

    function switchtimer() {
      console.log(isRef(timer));    // true
      toggleTimer();

    }
    return { switchtimer };
  },
};
</script>
// ** src/ponents/Scores.vue

<template>
  <button @click="switchtimer()">switch at scores</button>
  <p>{{ timer }}</p>
</template>

<script>
import { isRef } from "vue";
import { useTimer } from "../store";

export default {
  name: "Scores",
  setup() {

    const { timer, toggleTimer } = useTimer();

    function switchtimer() {
      console.log(isRef(timer));    // true
      toggleTimer();

    }
    return { timer, switchtimer };
  },
};
</script>

Scores.vue is imported in app.vue as ponent. There is no importing issue in the app even if there is any mistakes I did in this description. That mistake might have occurred during rewriting while posting this.

When switch at scores button pressed the timer toggles in scores ponent, but switch at app button pressed the timer does not toggles in scores ponent.

I want to have timer as global state, so that when changed it from app.vue, the changed value also shown in scores.vue.

Share Improve this question asked Nov 12, 2020 at 2:33 Rupam KairiRupam Kairi 1113 silver badges10 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 9

The fix is very simple, you need to make the ref variable persistent

// ** src/store/index.js

const timer = ref(false); // <=== outside of function scope

export function useTimer() {
  const toggleTimer = () => {
    if (timer.value == false) {
      timer.value = true;
    } else {
      timer.value = false;
    }
  };

  return { timer, toggleTimer };
}

By taking it out of the function scope, you will no longer create a new timer variable every time you call the function, but rather reference the same one, like a singleton.

This seems like a perfect fit for dependency injection. Since there will be absolutely one instance of the timer state in the whole app, it's good to delegate the responsibility of "updating the single state(s)" to the service provider (in this case, the App.vue) and have the handler inject-ed by child ponents.

Your approach and Daniel's will work — and this is probably debatable to the extent of whether or not to have singletons actually coupled to factory functions, but I would resort to DI for this particular case.

App.vue (parent)

import { defineComponent, provide, ref } from 'vue';

export default defineComponent({
  setup() {
    const timer = ref(false);

    const toggleTimer = () => {
      timer.value = !timer.value;
    }

    provide('toggleTimer', toggleTimer);

    return { toggleTimer }
  }
})

Scores.vue (child)

import { defineComponent, inject } from 'vue';

export default defineComponent({
  name: 'Home',

  setup() {
    const toggleTimer = inject('toggleTimer');

    return {
      toggleTimer
    }
  }
})
发布评论

评论列表(0)

  1. 暂无评论