简体   繁体   English

如何在 Vue.js 3 中将共享存储与多个单文件组件链接起来?

[英]How to link a shared store with multiple single file components in Vue.js 3?

I have a Vue.js 3 app.我有一个 Vue.js 3 应用程序。 This app includes multiple single file components.此应用程序包含多个单文件组件。 I'm trying to figure out how to implement the simplest global state management.我试图弄清楚如何实现最简单的全局状态管理。 The docs make sense to me.这些文档对我来说很有意义。 However, the limited docs show a reactive object returned from the data function of multiple components.但是,有限的文档显示了从多个组件的data函数返回的reactive对象。 This example assumes the reactive object and components are all in the same file.这个例子假设reactive对象和组件都在同一个文件中。 The challenge I'm running into is using a shared store across multiple files.我遇到的挑战是在多个文件中使用共享存储。 Currently I have:目前我有:

  • app.vue应用程序
  • component-a.vue组件-a.vue
  • component-b.vue组件-b.vue
  • store.js商店.js

These files looks like this:这些文件如下所示:

app.vue应用程序

<template>
    <div>        
      <div>How much money do you have?</div>
      <input type="number" v-model="currentAmount" />
      <br />
      <div>How much money do you want?</div>
      <input type="number" v-model="desiredAmount" />
    </div>
</template>

<script>
  import ComponentA from './component-a.vue';
  import ComponentB from './component-b.vue';

  export default {
     components: {
       ComponentA,
       ComponentB
     },

     data() {
         return {
           currentAmount: 0,
           desiredAmount: 0
         }
     },
  }
</script>

component-a.vue组件-a.vue

<template>
    <div>        
      <div>You have {{ remainingAmount }} to reach your goal.</div>
    </div>
</template>

<script>
  export default {
     data() {
         return {
           remainingAmount: 0
         }
     },
  }
</script>

component-b.vue组件-b.vue

<template>
    <div>        
      <div>You are {{ progress }}% of the way there!</div>
      <button @click="increaseGoal">increase goal by $10</button>
    </div>
</template>

<script>
  export default {
     data() {
         return {
           progress: 0
         }
     },

     methods: {
        increaseGoal() {
           // need to increase targetAmount by $10
           store.targetAmount += 10; 
        }
     }
  }
</script>

store.js商店.js

import { reactive} from 'vue';

const store = reactive({
  startingAmount: 0,
  targetAmount: 0
});

The UI renders.用户界面呈现。 However, clearly the data is not getting propagated across the components.但是,很明显,数据并没有在组件之间传播。 I can clearly see that there's not a link between store and the three .vue files.我可以清楚地看到 store 和三个 .vue 文件之间没有链接。 There's nothing that ties the store with the UI.没有任何东西可以将商店与 UI 联系起来。 I don't know how to get the store.js associated with the three .vue files properly though.我不知道如何让store.js与三个.vue文件,即使正确关联。

How do you link a shared store with multiple single file components?您如何将共享存储与多个单文件组件链接起来? Please note: I do not want to use Vuex.请注意:我不想用Vuex。

To get hold of the store on a global level you can make vue use() it so that you will be able to call this.$store from any component within the VueApp要在全局级别上获取商店,您可以使用 vue use()它,以便您能够从 VueApp 中的任何组件调用this.$store

main.js主文件

import { createApp } from 'vue';
import store from './store/index'; // OR the path to your
import router from './router/index';
import App from './App.vue';


createApp(App).use(router).use(store).mount('#app');

I created a store-folder because I use the store within multiple modules.我创建了一个商店文件夹,因为我在多个模块中使用了商店。 In the store folder is the index.js which hold the basics store and all modules. store 文件夹中是index.js ,其中包含基本存储和所有模块。

store/index.js商店/index.js

import { createStore } from 'vuex';

const store = createStore({
  modules: {},
  state() {
    return {};
  },
  mutations: {},
  actions: {},
  getters: {},
});

export default store;

By doing that you can call the store from any component.通过这样做,您可以从任何组件调用商店。

component.vue组件.vue

export default {
  name: 'users-list',
  created() {
    console.log(this.$store);
  },
}

The variables in your store's state should not be altered directly.不应直接更改商店状态中的变量。

The store has 3 types of procedures.这家商店有3种程序。

Actions - Do elaborated Stuff行动- 做精心设计的东西


The Actions are used to do the heavy work of a given change in data.操作用于完成给定数据更改的繁重工作。 This is where you would cross-feed the function from different store modules, make axios calls and similar.在这里,您可以从不同的商店模块交叉馈送功能,进行 axios 调用等。 Therefore Actions is the only procedure group that can access the store it-self.因此,Actions 是唯一可以访问存储本身的过程组。 the first argument is basically the whole store.第一个参数基本上是整个商店。 Actions are triggered by calling dispatch('NameOfModule/NameOfAction', ValuetoPass) .动作是通过调用dispatch('NameOfModule/NameOfAction', ValuetoPass)触发的。

Mutations - Beloved Setter Functions突变- 心爱的 Setter 函数


The Mutations are used to mutate a state, and ONLY Mutations should mutate the state in order to keep reactivity and workflows clean. Mutations 用于改变状态,并且只有 Mutations 应该改变状态以保持反应性和工作流干净。 The Mutations therefore only get passed their own local state as first parameter.因此,Mutations 只会将它们自己的本地状态作为第一个参数传递。 Mutations will be triggered by commit('NameOfMutation', ValueToPass)突变将由commit('NameOfMutation', ValueToPass)触发

Getters - Pretty self-explanatory, isn't it? Getters - 不言自明,不是吗?


The getters are used to, well yeah, get States.吸气剂习惯于,是的,获取状态。

As you said, you don't need to use Vuex to create global state.正如您所说,您不需要使用 Vuex 来创建全局状态。 Thanks to composition-api we can use composables.多亏了 composition-api 我们可以使用可组合物。

First, create directory /composables and add javascript file (it's good practice to create file beginning with use word) useState.js:首先,创建目录/composables并添加javascript文件(创建以use word开头的文件是一个好习惯)useState.js:

import { reactive, toRefs } from "vue";

const state = reactive({
  isMenuOpened: false
});

const toggleMenuState = () => {
  state.isMenuOpened = !state.isMenuOpened;
};

export default {
  ...toRefs(state),
  toggleMenuState
};

toRefs converts all of the properties, to a plain object with properties that are refs toRefs 将所有属性转换为具有 refs 属性的普通对象

Now you can use composable in vue components:现在你可以在 vue 组件中使用可组合了:

<script>
import useState from "./composables/useState";

export default {
  setup() {
    const { isMenuOpened, toggleMenuState } = useState;

    return {
      isMenuOpened,
      toggleMenuState,
    };
  },
};
</script>

Demo: https://codesandbox.io/s/happy-chandrasekhar-o05uv?file=/src/App.vue演示: https : //codesandbox.io/s/happy-chandrasekhar-o05uv?file=/ src/ App.vue

About composition api and composables: https://v3.vuejs.org/guide/composition-api-introduction.html关于组合 api 和可组合: https : //v3.vuejs.org/guide/composition-api-introduction.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM