state

通过前文的讲解,我们知道 state 的主要作用是保存状态,通俗来讲,状态是由 “键-值对” 组成的对象,那么在 Vue 的组件中,读取状态最简单的方法就是在计算属性中返回某个状态。下面先定义一个根实例,如示例代码 6-3-1 所示。

示例代码 6-3-1 store 注册根实例
<!-- 根实例挂载的DOM对象 app -->
<div id="app">
    <counter />
</div>
const app = Vue.createApp({
    components: {
        'counter': counter
    }
})
app.use(store)
app.mount("#app")

在上面的代码中,通过在根实例中注册 store 选项,该 store 实例会注入根组件下的所有子组件中,且子组件能通过 this.$store 访问 store 选项。然后,更新 storecounter 组件的实现,如示例代码 6-3-2 所示。

示例代码 6-3-2 获取 state 的值1
const store = Vuex.createStore({
    state: {
        count: 3
    }
})
const counter = {
    template: '<div>{{ count }}</div>',
    computed: {
        count () {
            return this.$store.state.count // 通过this.$store.state可以获取到state
        }
    }
}

在上面的代码中,counter 组件将 count 作为一个计算属性,然后通过 this.$store.state 就可以获取到 store 中的 state,得到 state 中的 count 值,并将 count 值赋值给计算属性中的 count,这样就构成了一条响应式的链路,一旦 store 中的 state 中的 count 值改变,就会触发计算属性中的 count 改变,进而达到动态地更新。

使用 mapState 可以直接将 store 中的 state 映射到局部的计算属性中,这样就可以直接在计算属性中使用 state,而无须定义一个 computed 的属性值,然后在属性值中获取 state 了,如示例代码 6-3-3 所示。

const store = Vuex.createStore({
    state: {
        count: 3
    }
})
const counter = {
    template: '<div>{{ count }}</div>',
    computed: Vuex.mapState({
        count: state => state.count,
    })
}

mapStateVuex 提供的一个非常方便的工具,可以简化在组件中访问 store 状态的过程。通过字符串数组和对象的两种形式,你可以灵活地映射 store 的状态到组件的计算属性中,并在需要时结合局部状态和模块化的 store 使用。

Vuex 中,mapState 是一个帮助函数,用于将 Vuex store 中的状态(state)映射到组件的计算属性(computed properties)中,从而简化在组件中访问和使用 store 状态的过程。

基本用法

mapState 可以在组件的 computed 属性中使用,将 Vuex store 的状态直接映射为组件的计算属性。它有两种主要的用法:

  1. 使用字符串数组

    • 这种方式适用于直接映射 store 中的状态字段。

  2. 使用对象

    • 这种方式适用于重命名计算属性或使用计算属性函数。

使用字符串数组

假设你的 Vuex store 中有如下状态:

const store = new Vuex.Store({
  state: {
    count: 0,
    message: 'Hello, Vuex!'
  }
});

在组件中,你可以使用 mapState 将这些状态映射为计算属性:

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Message: {{ message }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState(['count', 'message'])
  }
};
</script>

在这个示例中,countmessage 被映射为组件的计算属性,直接引用 store 中的状态。

使用对象

当你需要重命名计算属性或使用计算属性函数时,可以使用对象形式:

<template>
  <div>
    <p>My Count: {{ myCount }}</p>
    <p>Reversed Message: {{ reversedMessage }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState({
      myCount: 'count', // 将 `count` 状态映射为 `myCount`
      reversedMessage(state) { // 使用函数来处理状态
        return state.message.split('').reverse().join('');
      }
    })
  }
};
</script>

在这个示例中:

  • myCount 映射了 store 中的 count 状态。

  • reversedMessage 是一个计算属性函数,它基于 store 中的 message 状态,返回其反转的字符串。

结合局部状态

如果组件中既需要使用 Vuex store 状态,又需要使用组件的局部状态,可以将它们结合起来:

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Local Message: {{ localMessage }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  data() {
    return {
      localMessage: 'This is local'
    };
  },
  computed: {
    ...mapState(['count'])
  }
};
</script>

在这个示例中,组件既有来自 Vuex store 的 count 状态,也有组件自己的 localMessage 数据。

模块化 Vuex

在使用 Vuex 模块化时,可以指定模块名称来访问嵌套的状态:

const store = new Vuex.Store({
  modules: {
    myModule: {
      state: () => ({
        count: 0,
        message: 'Hello from module!'
      })
    }
  }
});

在组件中:

<template>
  <div>
    <p>Module Count: {{ count }}</p>
    <p>Module Message: {{ message }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState('myModule', ['count', 'message'])
  }
};
</script>

在这个示例中,myModule 模块中的 countmessage 状态被映射为组件的计算属性。