The safest way to try to get what you want is to try to deserve what you want

Vue学习笔记(Vuex)

Posted on By Frank·J

Vuex 是什么?

照例先把官网地址给一下: Vuex ,简单清晰明了,所以读完了,我都不知道该写什么了!作为学习 Vue 笔记的一部分,Vuex 是必不可少的。所以以下内容我只会写一下简单的 demo。

这节的标题是 Vuex 是什么,其实我认为他是什么不重要,重要的是他能为我们解决什么样的问题,如果你之前做过较为庞大的项目,遇到过组件之间通信繁琐、共享数据麻烦的问题,那么目前来说 Vuex 就是你的终极解决方案。

番外篇 – Redux

其实我在开始学习 Vue 之前是不知道有 Vuex 这个东西的,再说回来我之前做过一个较为大型的项目使用的框架是 Angular,开发过程中发现组件之间的通信以及数据共享简直就是恶梦,特别是越来越多的组件需要通信和共享数据时。当时的解决方案是 Redux 完美解决了这个问题。其实 Redux 是可以结合 Vue 开发的,但是当我完了 Vuex 的开发文档之后我就知道我是不可能在 Vue 项目中使用 Redux 的(这辈子都不可能的),因为 Vuex 看起来太简洁了(好吧,我承认就是因为我懒,哪个方便用哪个)。

在项目中使用 Vuex

在 src 文件夹下新建一个 stroe 文件夹,在 stroe 文件夹下新建一个 modules 文件夹用来存放各个状态模块,再在 stroe 文件夹下新建一个 index.js 用来统一管理使用模块,文件结构如下:

|--store  // 状态文件
    |--modules  // 分模块
        |--moduleA.js
        |--moduleB.js
    |--index.js // 配置文件

以下是模块 A 的简单结构,麻雀虽小五脏俱全,其它的模块可以按照这个样子写。

const state = {
    pageTitle: 'this is moduleA!',
    userInfo: {
        name: 'frank',
        age: 18
    }
}

// getters
const getters = {
    getPageTitle: state => state.pageTitle,
    getUserInfo: state => state.userInfo,
    getUserName: state => state.userInfo.name
}

// actions 处理异步事件
const actions = {
    setTitleAsyncAction(context, title) {
        setTimeout(() => {
            context.commit('setPageTitle', title)
        }, 1000)
    },
    setUserNameAsyncAction(context, name) {
        setTimeout(() => {
            context.commit('setUserName', name)
        }, 1000)
    }
}

// mutations 处理同步事件
const mutations = {
    setPageTitle: (state, flag) => {
        state.pageTitle = flag
    },
    setUserName: (state, flag) => {
        state.userInfo.name = flag
    }
}

// 倒出模块
export default {
    state,
    getters,
    actions,
    mutations
}

index.js 文件

import Vue from 'vue'
import Vuex from 'vuex'
import modeleA from './modules/modeleA'
import modeleB from './modules/modeleB'

Vue.use(Vuex)

const debug = process.env.NODE_ENV !== 'production'

export default new Vuex.Store({
    modules: {
        modeleA,
        modeleB
    },
    strict: process.env.NODE_ENV !== 'production'
})

PS: 官方文档有个 购物车示例 我就是参考这个来写的。顺便说一下,我觉得 命名空间 这个东西还是看需求吧,如果需要使用的话,就把公共部分拿出来,再去区分各个模块。

如何使用

<template>
    <div>
        <h1>HomePage</h1>

        姓名: <br />
        年龄: <br />

        <input type="text" v-model="userName">
    </div>
</template>

<script>
// 这里引入辅助函数,帮助我们生成计算属性
import { mapActions, mapState, mapGetters } from 'vuex'

export default {
    name: 'HomePage',
    data() {
        return {

        }
    },
    computed: {
        userName: {
            set(name) {
                this.$store.dispatch('setUserNameAsyncAction', name)
            },
            get() {
                return this.$store.getters.getUserName
            }
        },
        // ES6 扩展运算符
        ...mapGetters(['getUserInfo']),
    }
}
</script>