zoukankan      html  css  js  c++  java
  • Vue入门笔记三(Vuex)

    《Vue.js项目实战》

    Vuex

    集中式的状态管理

    • Vuex从Flux(由Facebook开发)的概念中获取得灵感。Flux又一系列指导原则构成,阐明了如何使用集中式store来实现组件之间的单向数据流。
    • Vuex的核心元素是store,是进行数据存储和数据处理的主要架构。
      store包含如下信息:
    state            // 存储应用状态的响应式数据对象
    getter          // 等价于store的计算属性
    mutation     // 用来改变应用状态的函数
    action         // 通常用来调用异步API的函数,然后使用mutation改变数据
    

    Vuex store

    1.安装vuex

    npm i -S vuex
    

    然后新建store文件夹,并创建index.js来安装Vuex插件:

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    

    2.使用Vuex.Store构造函数创建store:

    const store = new Vuex.Store({
        // TODO 选项
    })
    

    3.导出store:

    export default store
    

    4.在main.js文件中,导入store:

    import store from './store'
    

    5.为了让store在应用中生效,我们还需要像注入路由器一样注入它:

    const app = new Vue({
        router,
        store,
        el: '#app',
        ...App,
      })
    

    state是唯一数据源

    state是store的主要组成部分,它展示了应用中组件的所有共享数据。

    • state是共享数据的唯一数据源
    • state是只读的
      (1)在store选项中添加state函数,该函数返回一个对象:
    const store = new Vuex.Store({
      state () {
        return {
          user: null
        }
      },
    })
    

    (2)在组件中读取状态:

    this.$store.state.user
    

    使用mutation修改状态

    • mutation是修改state的唯一方式
    • mutation接受state作为第一个参数,同时接受一个可选的载荷(payload)参数,以此来更新state
    • 不应该在mutation中使用异步操作
    • 严格模式:避免在mutation中使用异步函数strict: true
    • 不要在生产环境下启用严格模式,以免影响性能strict: process.env.NODE_ENV !== 'production'
      (1)添加一个mutation:
    const store = new Vuex.Store({
        state () { /* ... */ },
        mutations: {
            user: (state, user) => {
                state.user = user
            }
        }
    })
    

    (2)表明调用mutation的用词是submit,在组件中:

    this.$store.commit('user', userData)
    

    使用getter计算和返回数据

    (1)创建一个getter:

    const store = new Vuex.Store({
        // ...
        getter: {
            user: state => state.user,
        }
    })
    

    (2)在组件中,可以用这个getter代替之前直接获取状态的方法:

    this.$store.getter.user // this.$store.state.user
    

    使用action操作store

    • action不仅可以提交mutation,还能做异步操作
    • action的声明由一个类型和一个处理函数构成store.dispath('action-type', payloadObject)
    • action的处理函数接收两个参数:
      1.context
      2.payload
      (1)创建action:
    actions: {
        login ({ commit }) {
          const userData = {
            profile: {
              displayName: 'Mr Cat',      
            },
          }
         commit('user', userData)
        },
        // ...
    },
    

    (2)在组件中使用:

    this.$store.dispatch('login')
    

    辅助函数

    Vuex提供了一系列辅助函数供添加state、getter、mutation以及action。出于将组建中的状态和逻辑分离的考虑,我们只应该在组件中使用getter和action,所以只会用到mapGetters和mapActions。

    辅助函数的参数可以是:
    1.类型的数组,其中的每一个元素对应于组件中的同名数据
    2.对象,其中的键是组件中数据的别名,值则是类型
    数组语法例如:

    mapGetters(['a', 'b'])
    // 等价于
    {
        a () { return this.$store.getters.a },
        b () { return this.$store.getters.b },
    }
    

    对象语法例如:

    mapGetters({ x: 'a', y: 'b' })
    // 等价于
    {
        x () { return this.$store.getters.a },
        y () { return this.$store.getters.b },
    }
    

    (1)在组件中导入:

    import { mapGetters, mapActions } from 'vuex'
    

    (2)然后将组件修改为:

    
    export default {
      computed: {
        ...mapGetters([
          'user',
          'userPicture',
        ]),
      },
    
      methods: {
        ...mapActions({
            centerOnUser: 'login',
            logout: 'logout'
        }),
      },
    
    }
    

    Vuex模块

    创建两个模块:

    • maps
    • posts
      (1)在store文件夹中新建一个maps.js文件。它导出一个默认模块定义,其中包括地图的state:
    export default {
        namespaced: true,
    
        state () {
            return {
                center: {
                    lat: 48.8538302,
                    lng: 2.2982161,
                }
            }
        }
    
    }
    
    

    (2)将模块添加到store中,在store/index.js文件中添加modules选项:

    import maps from './maps'
    
    const store = new Vuex.Store({
        // ...
        modules: {
            maps,
        }
    })
    

    默认情况下,模块中getter、mutation、action的状态也会成为这个模块的状态。这里它是store.state.maps。

    带命名空间的模块

    上面的namespaced选项告诉Vuex在该模块的所有getter、mutation、action前添加maps/命名空间,还会在这个模块内的commit和dispatch调用中添加它们。

    // getter模块
    getters: {
        center: state => state.center,
    }
    

    maps/center getter 会被添加到store中。使用时可以这么写:
    1.getters

    this.$store.getters['maps/center']
    

    2.使用getter辅助函数:

    mapGetters({
        center: 'maps/center',
    })
    

    3.可以指定命名空间:

    mapGetters('maps', [
        'center'
    ])
    

    4.使用createNamespacedHelpers方法生成基于某个命名空间的辅助函数:

    import { createNamespacedHelpers } from vuex
    import { mapGetters } = createNamespacedHelpers('maps')
    
    export default {
        computed: mapGetters([
            'center',
        ])
    }
    

    访问全局元素

    1.在getter中
    你可以在命名空间模块的getter中访问到根状态和根getter(即所有的getter):

    someGetter: (state, getters, rootState, rootGetters) => { /* ... */}
    

    2.在action中
    你可以访问到上下文的rootGetters,还可以在commit和dispatch调用中使用{ root: true }选项:

    myAction({ dispatch, commit, getters, rootGetters }) {
        getters.a // store.getters['maps/a']
        rootGetters.a // store.getters['a']
        commit('someMutation') // 'maps/someMutation'
        commit('someMutation', null, { root: true }) // 'someMutation'
        dispatch('someAction') // 'maps/someAction'
        dispatch('someAction', null, { root: true }) // 'someAction'
    }
    
  • 相关阅读:
    几个函数小练习
    结构体和枚举类型
    结构体
    几个函数小练习
    函数简介
    网页端滚轮滑动事件
    碰撞检测
    Ajax前后台交互函数
    事件绑定与解除js
    移动端的屏幕适配问题
  • 原文地址:https://www.cnblogs.com/siluo2000/p/11296851.html
Copyright © 2011-2022 走看看