vuex-State

2019-07-06  本文已影响0人  coffee1949

安装 Vuex 之后,让我们来创建一个 store。创建过程直截了当——仅需要提供一个初始 state 对象和一些 mutation:

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

现在,你可以通过 store.state 来获取状态对象,以及通过 store.commit 方法触发状态变更:

store.commit('increment')

console.log(store.state.count) // -> 1

再次强调,我们通过提交 mutation 的方式,而非直接改变 store.state.count,是因为我们想要更明确地追踪到状态的变化。这个简单的约定能够让你的意图更加明显,这样你在阅读代码的时候能更容易地解读应用内部的状态改变。此外,这样也让我们有机会去实现一些能记录每次状态改变,保存状态快照的调试工具。有了它,我们甚至可以实现如时间穿梭般的调试体验。

由于store中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可触发变化也仅仅是在组件的 methods 中提交 mutation


#单一状态树

Vuex 使用单一状态树——是的,

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

#在 Vue 组件中获得 Vuex 状态

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

// 创建一个 Counter 组件
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}

每当 store.state.count 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM。
然而,这种模式导致组件依赖全局状态单例。在模块化的构建系统中,在每个需要使用 state 的组件中需要频繁地导入,并且在测试组件时需要模拟状态。

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

const app = new Vue({
  el: '#app',
  // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
  store,
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

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

const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}




**state **

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vuex</title>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    <script type="text/javascript" src="https://unpkg.com/vuex@3.1.1/dist/vuex.js">
    </script>
</head>
<body>
    <div id="app">
        {{msg}}
        {{word}}
        <home/>
    </div>
    
    <!-- home组件template模板 -->
    <script type="text/x-template" id='home'>
        <div>
            <table border='1'>
                <tr>
                    <td>id</td>
                    <td>姓名</td>
                    <td>年龄</td>
                    <td>性别</td>
                </tr>

                <tr v-for='item in students'>
                    <td>{{item.id}}</td>
                    <td>{{item.name}}</td>
                    <td>{{item.age}}</td>
                    <td>{{item.sex}}</td>
                </tr>
            </table>
        </div>
    </script>
    <script type="text/javascript">
        // 第一步实例化一个store
        // 第二步在根组件上挂载store,详见87行
        // 第三步在组件或者子组件中使用this.$store.state.students
        var store = new Vuex.Store({
            state: {
                students: [
                    {
                        id: 1,
                        name: '张三',
                        age: 18,
                        sex: 'man'
                    },
                    {
                        id: 1,
                        name: '李四',
                        age: 18,
                        sex: 'man'
                    }
                ]
            }
        })
        // home组件
        var home = {
            template: '#home',
            data(){
                return {
                    
                }
            },
            computed: {
                students(){
                    return this.$store.state.students
                }
            }
        }
        // 根组件
        var app = new Vue({
            data: {
                msg: 'hello'
            },
            computed: {
                word(){
                    return this.msg + ', world'
                }
            },
            // 子组件
            components: {
                home
            },
            store
        }).$mount('#app')

    </script>

</body>
</html>
上一篇下一篇

猜你喜欢

热点阅读