Vue 学习2 - 核心概念State

本文教程来自官网:https://vuex.vuejs.org/zh/

State

单一状态树

Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。这次它便作为一个 “唯一数据源” 而存在。这也意味着,每个应用仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地获取整个当前应用的快照。

在 Vue 组件中获得 Vuex 状态

那么我们如何在 Vue 组件中展示状态呢?由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方式就是在 计算属性 中返回某个状态:

<template>
    <div> 
        <hr />
        <h3>{{ $store.state.count }}h3>
    div>
template>

<script>
import store from '@/vuex/store';
export default {
    name: 'Count',
    computed: {
        count() {
            return store.state.count;
        }
    },
    store,
}
script>

Vue 学习2 - 核心概念State_第1张图片
每当 store.state.count 变化时,都会重新计算属性,并且触发更新相关联的 DOM。

然而,这种模式导师组件依赖全局状态单例。在模块化的构建系统中,在每个需要使用 state 的组件中需要频繁地导入,并且在测试组件时需要模拟状态。

Vuex 通过 store 选项,提供了一种机制将状态从根组件 “注入” 到每一个子组件中(需要调用 Vue.use(Vuex)

import Vue from 'vue'
import App from './App.vue'
import router from './router/router';
import store from './vuex/store';

Vue.config.productionTip = false

new Vue({
  store,
  router,
  render: h => h(App),
}).$mount('#app')

通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到。让我们更新下 Count 的实现:

<template>
    <div> 
        <hr />
        <h3>{{ count }}h3>
        <p><button @click="$store.commit('add')">增加button>p>
        <p><button @click="$store.commit('reduce')">减少button>p>
    div>
template>

<script>
export default {
    name: 'Count',
    computed: {
        count() {
            return this.$store.state.count;
        }
    }
}
script>

mapState 辅助函数

当一个组件需要获取多个状态时候,将这些状态声明为计算属性会有些重复和荣誉。

为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键:

<template>
    <div> 
        <hr />
        <h3>{{ count }}h3>
        <p><button @click="$store.commit('add')">增加button>p>
        <p><button @click="$store.commit('reduce')">减少button>p>
    div>
template>

<script>
import { mapState } from 'vuex';
export default {
    name: 'Count',
    computed: mapState({
       count: state => {
           state.count;
       },
    }),
}
script>

当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 穿一个字符串数组。

<template>
    <div> 
        <hr />
        <h3>{{ count }}h3>
        <p><button @click="$store.commit('add')">增加button>p>
        <p><button @click="$store.commit('reduce')">减少button>p>
    div>
template>

<script>
import { mapState } from 'vuex';
export default {
    name: 'Count',
    computed: mapState(['count']),
}
script>

对象展开运算符

mapState 函数返回的是一个对象。我们如何将它与局部计算属性混合使用呢?通常,我们需要使用一个工具函数将多个对象合并为一个,以使我们可以将最终对象传给 computed 属性。但是自从有了对象展开运算符,我们可以极大的简化写法:

<template>
    <div> 
        <hr />
        <h3>{{ count }}h3>
        <p><button @click="$store.commit('add')">增加button>p>
        <p><button @click="$store.commit('reduce')">减少button>p>
    div>
template>

<script>
import { mapState } from 'vuex';
export default {
    name: 'Count',
    computed: {
        // 本地计算属性代码
        localComputed() {"/.../"},
        // 使用对象展开运算符将 mapState 生成的对象展开
        ...mapState({
            // 辅助函数代码
            // ...
        })
    }
}
script>

组件仍然保有局部状态

使用 Vuex 并不意味着你需要将所有的状态放入 Vuex。虽然将所有的状态放入 Vuex 会是状态变化更显示,更容易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。

你可能感兴趣的:(Vue.js)