Vue状态管理之Vuex快速入门

2 篇文章 0 订阅

一、Vuex介绍

1.Vuex是什么?

1.是一个专为 Vue.js 应用程序开发的状态管理模式
2.集中式存储管理应用的所有组件的状态
3.Vuex 也集成到 Vue 的官方调试工具 devtools extension

2.什么情况下我应该使用 Vuex?

1.如果应用够简单,最好不要使用 Vuex,一个简单的 store模式 就足够了
2.如果需要构建一个中大型单页应用,很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

二、Vuex安装

npm
npm install vuex --save

三、应用

1.最简单的 Store
import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        count: 0,
        token: ''
    },
    mutations: {
        increment(state) {
            state.count++
        }
    },
    actions: {
        incrementAsync(context) {
            setTimeout(() => {    
                context.commit('increment');	   
            }, 1000);
        }
    }
})

通过 store.commit 方法触发状态变更
通过 store.dispatch 方法异步触发状态变更
通过 store.state 来获取状态对象

store.commit('increment');
store.dispatch('incrementAsync');
console.log(store.state.count); 
2.在 Vue 组件中操作 Vuex 状态

1.创建store.js模块,注册state、mutations、actions、getters

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
    state: {
        count: 0,
        todos: [{ id: 1, text: 'abc', done: true }, { id: 2, text: 'def', done: false }]
    },
    mutations: {
        increment(state) {
            state.count++;
        }
    },
    actions: {
        incrementAsync(context, flag) {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    if (flag) {
                	    context.commit('increment');
                	    resolve('成功');
                	} else {
                	    reject('失败');
                	} 
                }, 1000);
            });
        }
    },
    getters: {
        doneTodos(state, getters) {
            return state.todos.filter(todo => todo.done);
        },
        doneTodosCount(state, getters) {
            return getters.doneTodos.length;
        },
        getDoneById(state) {
        	return id => state.todos.find(todo => todo.id === id);
        },
        getTodosLength(state) {
            return state.todos.length;
        }
    }
});

export default store;

2.注册到根组件
main.js

import Vue from 'vue';
import App from './App.vue';
import store from './store';

Vue.config.productionTip = false;

new Vue({
    store,
    render: h => h(App)
}).$mount('#app');

App.vue

<template>
    <div id="app">
        <img alt="Vue logo" src="./assets/logo.png" />
        <HelloWorld msg="Welcome to Your Vue.js App" />
    </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue';

export default {
    name: 'app',
    components: {
        HelloWorld
    }
};
</script>

<style>
#app {
    font-family: 'Avenir', Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
}
</style>

3.在子组件中使用
HelloWorld.vue

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
        <div>
            计数器{{count}}
            <button @click="$store.commit('increment')">使用mutations增加计数</button>

            <button @click="$store.dispatch('incrementAsync', true)">使用actions增加计数</button>
            <button @click="incrementAsync(true)">使用actions增加计数</button>
        </div>
        <ul>
            <li v-for="(doneTodo, index) in doneTodos" :key="index">{{doneTodo.text}}</li>

            <li>doneCount共计: {{doneCount}}</li>
            <li>数组共计长度: {{getTodosLength}}</li>
        </ul>

        <p>{{$store.getters.getDoneById(2)}}</p>
    </div>
</template>

<script>
import { mapState, mapGetters, mapActions } from 'vuex';

export default {
    name: 'HelloWorld',
    props: {
        msg: String
    },
    data() {
        return {
            localCount: 3
        };
    },
    computed: {
        doneTodos() {
            return this.$store.getters.doneTodos;
        },

        // ...mapState({
        //     count: state => state.count,
        //     countAlias: 'count',
        //     // 为了能够使用 `this` 获取局部状态,必须使用常规函数
        //     countPlusLocalState(state) {
        //         debugger;
        //         return state.count + this.localCount;
        //     }
        // })
        ...mapState(['count']),
        ...mapGetters({
            // 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
            doneCount: 'doneTodosCount'
        }),
        ...mapGetters(['getTodosLength'])
    },
    methods: {
        ...mapActions(['incrementAsync'])
    }
};
</script>

四、注意点

1.不要直接修改state,必须通过mutations修改
2.有异步调用的情况下,必须通过actions修改

五、大型应用项目结构及Vuex分割模块示例:

├── public  
│   └── index.html
├── src
│   ├── assets
│   ├── components
│   │  └── HelloWorld.vue  
│   └── store
│       ├── index.js          # 我们组装模块并导出 store 的地方
│       ├── actions.js        # 根级别的 action
│       ├── mutations.js      # 根级别的 mutation
│       └── modules
│          ├── cart.js       # 购物车模块
│          └── products.js   # 产品模块
├── App.vue
└── main.js

六、个人对vuex与vue的一些设计共性理解

属性描述
state相当于vue中的data
mutations相当于vue中的methods,而且必须为同步函数, 官方建议常量命名
actions作用是处理异步后再提交mutations
getters相当于vue中的computed

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值