zoukankan      html  css  js  c++  java
  • 从零开始的vue学习笔记(七)

    前言

    今天花一天时间阅读完vuex的官方文档,简单的做一下总结和记录

    Vuex是什么

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,以前的符合“单向数据流”理念的示意图:

    它包含三个部分:

    • state,驱动应用的数据源;
    • view,以声明方式将 state 映射到视图;
    • actions,响应在 view 上的用户输入导致的状态变化。

    当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:

    • 多个视图依赖于同一状态。
    • 来自不同视图的行为需要变更同一状态。

    实际上就是一个组件间通讯的问题,原来是用$ref直接引用子组件,或者多层嵌套组件,或者依赖注入provideinject等暴力方式,在应用和组件复杂的情况下复杂度和可维护性都会成为巨大问题。

    所以,vuex就诞生了,vuex的原理图:

    这个图描述了vuex的数据传导逻辑,绿色虚线部分为vuex插件本身

    1. 首先,Vuex自身提供了一个store(仓库),数据结构为树形的,采用单例设计,里面用key-value(value可以是string、数字、数组、Object等)的形式包含了一个应用的各种状态值,并提供了响应式的状态更新,提供给vue组件Render来渲染。
    2. 传统的Vue组件接受用户对界面的操作后,通过分发(Dispatch)这些前端事件或者说响应给Vuex的Action,在Action中可以用来添加自己的业务逻辑,同时可以异步调用一些其他的后端API
    3. Action通过Commit来提交对应的Mutations里的方法,达到调用Mutations里的方法的目的,这个时候可以用Devtools插件来追踪状态数据在Mutations里的方法调用前后的数据变化,形成快照等(Mutations里的方法必须同步的)
    4. Mutations里的一些mutation(变异)方法体执行,改变应用的一些State状态属性,这些mutation是Vuex改变状态的唯一途径,直接修改State状态值是不允许的(数据不可追踪),从而形成了单向数据流的完整链路,同时状态是可维护可追踪响应式可复用

    下面就一起来看看Vuex的各个详细部分:

    安装

    • 直接下载(推荐)或者CDN引入
      从https://unpkg.com/vuex下载下来,然后通过js引入:

        <script src="/path/to/vue.js"></script>
        <script src="/path/to/vuex.js"></script>
      
    • npm/yarn

        //npm
        npm install vuex --save
        //yarn  
        yarn add vuex
      
    • 模块化的打包系统

      import Vue from 'vue'
      import Vuex from 'vuex'
      //前面vue基础部分就有Vue.use()引入插件的用法,
      //下面这句在打包系统中是必备的
      Vue.use(Vuex)
      

    核心概念

    • State
      首先,Vuex的所有概念都只有一个api:围绕Vuex.Store(...options) 这个构造器展开,类似Vue的概念都围绕Vue的构造器展开一样;State的作用就类似于Vue里面的data,简单的new Vuex的例子:
        // 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)
      
        const store = new Vuex.Store({
        state: {
            count: 0
        },
        mutations: {
            increment (state) {
            state.count++
            }
        }
        })
      
      这样,在我们的Vue插件里就可以用computed计算属性来获取这些state值:
        // 创建一个 Counter 组件
        const Counter = {
        template: `<div>{{ count }}</div>`,
        computed: {
            count () {
            return store.state.count
            }
        }
        }
      

    为了简化写法(少些代码),官方提供了一个mapState辅助函数避免写store.state.count这一长串,其他的辅助函数mapGettersmapActionsmapMutations都是类似的作用,API链接

    例子:

      // 在单独构建的版本中辅助函数为 Vuex.mapState
    import { mapState } from 'vuex'
    
    export default {
      // ...
      computed: mapState({
        // 箭头函数可使代码更简练
        count: state => state.count,
    
        // 传字符串参数 'count' 等同于 `state => state.count`
        countAlias: 'count',
    
        // 为了能够使用 `this` 获取局部状态,必须使用常规函数
        countPlusLocalState (state) {
          return state.count + this.localCount
        }
      })
    }
    
    • Getter
      单纯的用State里的状态值还不够强大,所以Vuex提供了Getter来对State作进一步的复杂逻辑处理,类似于Vue里面的computed计算属性对data的进一步处理一样。
      例子:
        const store = new Vuex.Store({
        state: {
            todos: [
            { id: 1, text: '...', done: true },
            { id: 2, text: '...', done: false }
            ]
        },
        getters: {
            doneTodos: state => {
            return state.todos.filter(todo => todo.done)
            }
        }
        })
      

    如果对更多的语法细节感兴趣,可以阅读官方链接

    • Mutation
      Mutaion中文解释是变异,用来执行对State状态改变的同步方法,可以简单的类比Vue中的methods,只不过Vue中的methods没有区分同步异步方法,而Vuex中为了追踪数据状态,用Mutation执行同步方法,Action直观性异步方法,做了这种拆分,让Devtools等工具发挥作用。
      例子:

        const store = new Vuex.Store({
        state: {
            count: 1
        },
        mutations: {
            increment (state) {
            // 变更状态
            state.count++
            }
        }
        })
      

      更多的语法细节参考链接

    • Action
      Action 类似于 mutation,不同在于:

      • Action 通过commit提交的是 mutation,而不是直接变更状态。
      • Action 可以包含任意异步操作
        例子:
        const store = new Vuex.Store({
        state: {
            count: 0
        },
        mutations: {
            increment (state) {
            state.count++
            }
        },
        actions: {
            increment (context) {
            context.commit('increment')
            }
        }
        })
      

      组件里通过store.dispatch 来出发actions

        store.dispatch('increment')
      

      更多语法细节见链接

    • Module
      如果只靠一个大的store里的state状态树来维护整个应用,当规模巨大,势必会有问题,所以引入Module做模块化的拆分,拆成按照命名空间的子状态树。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。
      例子:

        const moduleA = {
        state: { ... },
        mutations: { ... },
        actions: { ... },
        getters: { ... }
        }
      
        const moduleB = {
        state: { ... },
        mutations: { ... },
        actions: { ... }
        }
      
        const store = new Vuex.Store({
        modules: {
            a: moduleA,
            b: moduleB
        }
        })
      
        store.state.a // -> moduleA 的状态
        store.state.b // -> moduleB 的状态
      

      引入namespaced: true 确保每个模块的独立命名空间,更多语法细节见链接

    • 其他
      其他的主题包括:

      • 项目结构
      • 插件
      • 严格模式
      • 表单处理
      • 测试
      • 热重载

    这些主题不是核心问题,在需要看的时候或者自己感兴趣的再来看,详见链接

  • 相关阅读:
    关于ActionScript中那些你不知道的事情
    Flash Player 11 Stage3D学习大杂烩
    Qt 控制台输入输出(支持中文)
    Redis消息发布订阅的稳定性验证结论
    C++11 Lambda表达式(匿名函数)用法详解
    vue中“:”、“.”、“@”意义
    QT中printf输出不同步的解决办法
    QT5中使用SQLite
    QT 调用user32.dll移动鼠标
    10分钟学会Visual Studio将自己创建的类库打包到NuGet进行引用(net,net core,C#)
  • 原文地址:https://www.cnblogs.com/huangmengke/p/11681552.html
Copyright © 2011-2022 走看看