Vuex 的使用、副作用 | 8月更文挑战

639 阅读1分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

组件开始三不管:

① 组件不管数据存放

② 组件不管数据更新

③ 组件不管数据请求

现在我们用过的所有$前缀的方法、属性:

refsrefs、event、storestore、router、emit()emit()、delete()

这些都是写在所有组件组件(.vue)文件继承的那个类上的,注意我们不能显式地看见它继承的这个类(React能看出来任何组件都继承自React.Component),但实际上确实有一个继承。

image.png

1、可预测状态容器----(predictable state container)

下面的代码利用闭包特性,实现了可预测状态容器:

<script>
function getApi(){
    var a = 0;
    return {
        getA(){
            return a;
        },
        addA(){
            a++;
        },
        cheng(n){
            if(n > 0){
                a *= n;
            }
        }
    }
}

var api = getApi();
api.addA();
api.addA();
api.addA();
api.addA();
api.cheng(3);
console.log(api.getA()); // 12
</script>

现在函数中的局部变量a就变得可预测状态了,虽然我们不知道它何时会变化,但是我们知道它能够发生的各种变化。比如加1,比如乘一个正数。

我们改变一下:

<script>
function getApi(){
    var a = 0;
    return {
        getA(){
            return a;
        },
        commit (str){
            if(str == "JIA"){
                a++;
            }else if(str == "JIAN"){
                a--;
            }
        }
    }
}
var api = getApi();
api.commit("JIA");
api.commit("JIA");
api.commit("JIA");
console.log(api.getA()); // 3
</script>

2、 为什么要用Vuex?

原因1:App.vue总是负责数据,太乱

我们做todo案例的时候,App.vue的data(){}中写了

data(){
    return {
        todo : []
    }
}

我们做图集的时候,App.vue的data(){}中写了

data(){    
    return {       
        info : {            
            mingxing :”yangmi”,            
            idx : 0        
        }    
    }
}

迄今为止,我们的数据都放在了App.vue组件中。

原因2:深层次不方便要数据

当组件层次深的时候,最小的组件不便于直接要数据、改数据。

看看官方的说法:

image1.png

3、Vuex的安装

vuex.vuejs.org/

npm install --save vuex

创建一个stores文件夹,让后创建store.js文件,这个文件向外暴露一个JS对象:

export default {
    state : {
        a : 10
    },
    mutations : {
        JIA(state){
            state.a ++;
        },
        MINUS(state){
            state.a --;
        }
    }
}

state就是数据,mutations是唯一能够改变state的地方!!

即使是actions也必须通过mutations来更改state。怎么改?commit到mutations中来改。

mutations:写没有副作用的地方,commit到mutations里

actions:写有副作用的地方,dispatch到actions里

改变main.js:

import Vue from "vue";
import Vuex from "vuex";
import App from "./App";
import store from "./stores/store";
//使用插件,关于use的机理,以后再说。
Vue.use(Vuex);
new Vue({
    el : "#app",
    render(h){
        return h(App)
    },

    //放置一个store对象
    store: new Vuex.Store(store)
});

4、组件如何得到值

任何组件,不需要任何的加工,不需要任何的包装,不需要任何引包,直接"问天要数据";

<h1>{{$store.state.a}}</h1>

注意,在函数中要加this.$store.state.a

可以用this.$store.commit、this.$store.dispatch来更改store中的数据。

5、组件如何更改值

注意,唯一能够改变state的方式就是使用mutations里面的函数,此时需要利用commit这个词语来调用。commit里面的参数是字符串,这个字符串就是mutations里面定义的函数的名字,通常是全部大写字母。

this.$store.commit("JIA")

易错点:

store.js文件中,注意:

state属性而不是data属性

mutations不是春函数,而是直接改变statestate是一个形参,由系统注入

export default {
//封闭自己的区间, true 是可以加命名空間
    namespaced : true,
    state : {
        a : 10
    },
    mutations : {
        JIA(state){
            state.a ++;
        },
        MINUS(state){

            state.a --;
        }
    }
}

7、刷手册

vuex.vuejs.org/zh/

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

image2.png

8、modules

module就是拆分的store,最终还是合并为一个store

暴露某个store模块 父store引入注册子组件使用子組件store暴露模块使用

import counterStore from "./counterStore";
export default {
    modules : {
        counterStore
    }
}

组件

<template>
    <div>
        <h1>我是Vue,你不要喜欢别人了!!</h1>
        <h1>{{$store.state.counterStore.a}}</h1>
        <button @click="add">加1</button>
        <button @click="minus">减1</button>
    </div>
</template>

<script>
    import Vue from "vue";
    export default {
        created(){
        },
        methods : {
            add(){
                this.$store.commit("counterStore/JIA");
            },
            minus(){
                this.$store.commit("counterStore/MINUS");
            }
        }
    }
</script>

什么是副作用

副作用的精准定义:en.wikipedia.org/wiki/Side_e…

通俗的说:它能产生的反应不确定的时候、有异步,就叫做“有副作用”。

image3.png