• Vue.js 2.x笔记:状态管理Vuex(7)


    1. Vuex简介

      Vuex是为vue.js应用程序开发的状态管理模式,解决的问题:

        ◊ 组件之间的传参,多层嵌套组件之间的传参以及各组件之间耦合度过高问题

        ◊ 不同状态中的行为需要多份复制的问题

      Vuex采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

      核心思想:抽取组件的共享状态,以一个全局单例的模式进行管理。

      核心:store(仓库)

      核心组成:

        ◊ state:存放项目中需要多组件共享的状态变量

        ◊ getters:读取器,从state中派生出状态,如:将state中的某个状态进行过滤然后获取新的状态。

        ◊ mutations:修改器,存放更改state里状态的方法。

        ◊ actions:动作,mutation的加强版,可以通过commit mutations中的方法来改变状态,最重要的是可以进行异步操作。

        ◊ modules:模块化,将状态和管理规则模块化封装。

        

      Vuex文档:https://vuex.vuejs.org/zh/

    2. Vuex基本使用

    2.1 State

      npm安装:

    npm install vuex -S

      基础示例:

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>libing.vue</title>
    
        <script src="node_modules/vue/dist/vue.min.js"></script>
        <script src="node_modules/vuex/dist/vuex.min.js"></script>
    </head>
    
    <body>
        <div id="app">
            Copyright &copy; {{ author }} - 2018 All rights reserved
        </div>
    
        <script>
            Vue.use(Vuex);
    
            const store = new Vuex.Store({
                // 定义状态
                state: {
                    //key: value
                    author: 'Libing'
                }
            });
    
            new Vue({
                el: "#app",
                store: store,
                computed: {
                    author: function () {
                        return this.$store.state.author
                    }
                }
            });
        </script>
    </body>
    
    </html>

      vue-cli示例:

      

      /store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
        // 定义状态
        state: {
            //key: value
            author: 'libing'
        }
    })

      HelloWorld.vue

    <template>
        <div>Copyright &copy; {{ author }} - 2018 All rights reserved</div>
    </template>
    
    <script>
    export default {
        name: "HelloWorld",
        computed: {
            author: function() {
                return this.$store.state.author;
            }
        }
    };
    </script>
    <template>
        <div id="app">
            <HelloWorld/>
        </div>
    </template>
    
    <script>
    import HelloWorld from "./components/HelloWorld";
    
    export default {
        name: "App",
        components: {
            HelloWorld
        }
    };
    </script>
    App.vue

      main.js

    import Vue from 'vue'
    import App from './App'
    
    import store from './store/index'
    
    Vue.config.productionTip = false
    
    new Vue({
        el: '#app',
        store,
        components: {
            App
        },
        template: '<App/>'
    })

      mapState:当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,可以使用 mapState 辅助函数帮助生成计算属性。

      store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 1,
        todos: [{
            id: 1,
            text: 'ToDo',
            status: false
          },
          {
            id: 2,
            text: 'Doing',
            status: false
          },
          {
            id: 3,
            text: 'Done',
            status: true
          }
        ]
      }
    })

      Home.vue

    <template>
        <div class="home">
            <ul>
                <li v-for="todo in todos" :key="todo.id">{{ todo.text }}</li>
            </ul>
        </div>
    </template>
    <script>
    import { mapState } from "vuex"
    
    export default {
        computed: mapState({
            count: state => state.count,
            todos: state => state.todos,
            dones(state) {
                return state.todos.filter(todo => todo.status);
            }
        })
    };
    </script>

    2.2 Getter

      Vuex 允许在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

      Getter 接受 state 作为其第一个参数:

      store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 1,
        todos: [{
            id: 1,
            text: 'ToDo',
            status: false
          },
          {
            id: 2,
            text: 'Doing',
            status: false
          },
          {
            id: 3,
            text: 'Done',
            status: true
          }
        ]
      },
      getters: {
        dones: state => {
          return state.todos.filter(todo => todo.status);
        }
      }
    })

      Getter 会暴露为 store.getters 对象,以属性的形式访问这些值:

      Home.vue

    <template>
        <div class="home">
            <ul>
                <li v-for="todo in dones" :key="todo.id">{{ todo.text }}</li>
            </ul>
        </div>
    </template>
    <script>
    export default {
        computed: {
            dones() {
                return this.$store.getters.dones;
            }
        }
    };
    </script>

      通过方法访问,让 getter 返回一个函数,来实现给 getter 传参。

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 1,
        todos: [{
            id: 1,
            text: 'ToDo',
            status: false
          },
          {
            id: 2,
            text: 'Doing',
            status: false
          },
          {
            id: 3,
            text: 'Done',
            status: true
          }
        ]
      },
      getters: {
        dones: state => {
          return state.todos.filter(todo => todo.status);
        },
        getTodoById: (state) => (id) => {
          return state.todos.find(todo => todo.id === id);
        }
      }
    })

      Getter 也可以接受其他 getter 作为第二个参数:

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 1,
        todos: [{
            id: 1,
            text: 'ToDo',
            status: false
          },
          {
            id: 2,
            text: 'Doing',
            status: false
          },
          {
            id: 3,
            text: 'Done',
            status: true
          }
        ]
      },
      getters: {
        dones: state => {
          return state.todos.filter(todo => todo.status);
        },
        donesCount(state, getters) {
          return getters.dones.length;
        }
      }
    })

    2.3 Mutation

      更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是实际进行状态更改的地方,并且它会接受 state 作为第一个参数。

      不能直接调用一个 mutation handler,要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit()。

      store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment(state) {
          state.count++;
        }
      }
    })

      Home.vue

    <template>
        <div class="home">
            {{ count }}
            <input type="button" value="添加" @click='handleIncrement'>
        </div>
    </template>
    <script>
    export default {
        data() {
            return {
                count: this.$store.state.count
            };
        },
        methods: {
            handleIncrement() {
                this.$store.commit("increment");
                console.log(this.$store.state.count)
            }
        }
    };
    </script>

    2.4 Action

      Action 类似于 mutation,不同在于:

        ◊ Action 提交的是 mutation,而不是直接变更状态。

        ◊ Action 可以包含任意异步操作。

      store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 0
      },
      mutations:{
        increment(state) {
          state.count++;
        }
      },
      actions:{
        plus(context){
          context.commit('increment')
        }
      }
    })

      Home.vue

    <template>
        <div class="home">
            {{ count }}
            <input type="button" value="添加" @click='add'>
        </div>
    </template>
    <script>
    export default {
        computed: {
            count() {
                return this.$store.state.count;
            }
        },
        methods: {
            add() {
                this.$store.dispatch('plus');
            }
        }
    };
    </script>

    3. Vuex插件

    3.1 vuex-persist状态持久化

    3.2 vuex-i18n语言本地化

  • 相关阅读:
    文本查询程序再探
    第15章 面向对象程序设计
    错误和异常处理 使用模板
    PHP会话管理
    身份验证
    表单提交与接收 文件提交与接收
    PHP文件访问
    PHP面向对象
    PHP速学
    第14章 重载运算与类型转换
  • 原文地址:https://www.cnblogs.com/libingql/p/9224333.html
Copyright © 2020-2023  润新知