组件之间的通讯:vuex状态管理,state,getters,mutations,actons的简单使用(一)

之前的文章中讲过,组件之间的通讯我们可以用$children、$parent、$refs、props、data。。。

但问题来了,假如项目特别大,组件之间的通讯可能会变得十分复杂。。。

这个时候了我们就用vuex进行组件通讯 。

至于什么是vuex,简单的说就是一个状态管理器,它管理着我们所有想要它管理的状态,这也就意味某一状态一经变化,其他使用到这个状态的其他组件中数据也会变化

还是一如既往的我不安装,vue-cli开发环境

使用vuex先要引入vuex,创建一个vues.Store();

vuex.Store({

  state:{},//状态数据集   

      getters:{},//公共状态数据集

      mutations:{},//主要用于改变状态

     actions:{}  //是可以解决异步问题

})

1)组件中访问状态数据(this.$store.state.状态名),如果你的状态较少,我们可以直接配合vue的计算属性computed使用

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="../lib/vue.js">
        </script>
        <script src="../lib/vuex.js"></script>
    </head>

    <body>
        <div id="app">
            <ul>
                <li v-for="item in unregisteredUsers">{{item.name}}</li>
            </ul>
            <app-registration></app-registration>
            <app-registrations></app-registrations>
        </div>
    </body>

</html>
<script>
    const ch1 = {
        template: `<div>
            <span>这是第一个子组件</span>
            <p>---------------------------------</p>
             <div class="row" v-for="item in users">
                <p>{{item.name}}</p>
                 <button @click="registerUser(item)">registerUser</button>
             </div>
        </div>`,

        //        props:{用了vuex就不需要使用props
        //            registration:Array
        //        },
        computed: {
            users() {
                return this.$store.state.users.filter(user => {
                    return !user.registred;
                });

            }

        },
        methods: {
            registerUser(user) {
                user.registered = true;
                const date = new Date;
                this.$store.state.registrations.push({ userId: user.id, name: user.name, date: date.getMonth() + '/' + date.getDay() });
            }

        }
    };
    const ch2 = {
        template: `<div>
            <span>这是第2个子组件</span>
            <p></p>
            
        </div>`,
        //        props:{
        //            users:Array
        //        },
        //           
    };

    const store = new Vuex.Store({
        state: {
            //填充用于管理状态的共享变量
            registrations: [],
            users: [
                { id: 1, name: 'Max', registered: false },
                { id: 2, name: 'Anna', registered: false },
                { id: 3, name: 'Chris', registered: false },
                { id: 4, name: 'Sven', registered: false }
            ]
        }
    })

    //Vue.use(Vuex);
    var myvue = new Vue({
        el: '#app',
        store,
        computed: {
            unregisteredUsers() {
//                return this.$store.state.users.filter((user) => {
//                    return !user.registered;
//                });
               return this.$store.state.registrations;
            }

        },
        components: {
            appRegistration: ch1,
            appRegistrations: ch2
        }

    });
</script>

 

2)getters 主要用于对多出使用的数据做集中处理

访问方式:this.$store.getters.状态名;

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="../lib/vue.js">
        </script>
        <script src="../lib/vuex.js"></script>
    </head>

    <body>
        <div id="app">
            <ul>
                <li v-for="item in unregisteredUsers">{{item.name}}</li>
            </ul>
            <app-registration></app-registration>
            <app-registrations></app-registrations>
        </div>
    </body>

</html>
<script>
    const ch1 = {
        template: `<div>
            <span>这是第一个子组件</span>
            <p>---------------------------------</p>
             <div class="row" v-for="item in users">
                <p>{{item.name}}</p>
                 <button @click="registerUser(item)">registerUser</button>
             </div>
        </div>`,

        //        props:{用了vuex就不需要使用props
        //            registration:Array
        //        },
        computed: {
            users() {
                return this.$store.state.users.filter(user => {
                    return !user.registred;
                });
            }
        },
        methods: {
            registerUser(user) {
                user.registered = true;
                const date = new Date;
                this.$store.state.registrations.push({ userId: user.id, name: user.name, date: date.getMonth() + '/' + date.getDay() });
            }
        }
    };
    const ch2 = {
        template: `<div>
            <span>这是第2个子组件</span>
            <p>--------没注册的用沪------------</p>
            <ul>
                <li v-for="item in unregistration">{{item.name}}</li>
            </ul>
        </div>`,
        computed:{
            unregistration(){        
                return this.$store.getters.unregisterdUsers;
            }            
        }        
    };

    const store = new Vuex.Store({
        state: {
            //填充用于管理状态的共享变量
            registrations: [],
            users: [
                { id: 1, name: 'Max', registered: false },
                { id: 2, name: 'Anna', registered: false },
                { id: 3, name: 'Chris', registered: false },
                { id: 4, name: 'Sven', registered: false }
            ]
        },
        getters:{
            unregisterdUsers(state){
                return state.users.filter(user=>{
                    return !user.registered;
                });    
            },
            registeredUser(state){
                return state.user.filter(user=>{
                    return user.registered;
                });
            },
            totalregisteration(state){
                return state.registrations.length;
            }
            
            
        }
    })

    //Vue.use(Vuex);
    var myvue = new Vue({
        el: '#app',
        store,
    
        computed: {
        unregisteredUsers() {
                return this.$store.state.users.filter((user) => {
                    return !user.registered;
                });
               return this.$store.state.registrations;
            }

        },
        components: {
            appRegistration: ch1,
            appRegistrations: ch2
        }

    });
</script>

 

3)如果组件想要改变vuex中状态值,我们需要借助于mutations了、

首先组件自己得定义一个方法,使用this.$store.commit({type:'addNum',n:n,m:m  });触发这个方法,其中n、m是参数

然后要在mutations中定义这个addNum方法 

mutations:{//mutations中的函数第一个参数是state
     addNum(state,ob){
        state.count+=ob.n;    
    }            
},     
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="../lib/vue.js"></script>
        <script src="../lib/vuex.js"></script>
    </head>
    <body>
        <p>
            mutation的作用就是,是的子组件可以请求 修改store中state的数据
        </p>
        
        <div id="app">
            <p>我是父组件中的实例:{{parentdata}}</p>
            
            <first-child></first-child>
            
        </div>
    </body>
</html>
<script>
    //定义一个子组件
    const ch1={
        template:`
        <div>
          <p>你可以进行数据操作,改变store中state的数据:{{varity}}</p>
          
          <button @click="add(varity)"> 点击试试</button>
        </div>
        `,
        computed:{
            varity(){
                return this.$store.state.count;
            }    
        },
        methods:{
            add:function(n){//子组件通过其自己的方法,直接commit,触发mutations中的方法进而改变状态
                //方式一:
                this.$store.commit({
                    type:'addNum',
                    n:n             
                });
                //方式e二:
                //this.$store.commit('addNum',{n:n});
            }
            
        }
    };
    
    
    var store=new Vuex.Store({
        state:{
            count:1,
            users:[{name:'han',age:23},{name:'tom',age:22},{name:'jarry',age:33}],    
        },
        getters:{
                       
        },
        mutations:{//mutations中的函数第一个参数是state
            addNum(state,ob){
                state.count+=ob.n;    
            }            
        },        
    });    
    var myvue=new Vue({
        el:"#app",
        store,
        components:{
            firstChild:ch1,
        },
        computed:{
            parentdata(){
                return this.$store.state.count;               
            }            
        }                        
    });    
</script>

 

4)actions 用于解决多个函数执行的异步问题 ,

本质上也是改变状态嘛,我们使用mutations貌似就可以改变状态了,但是不能解决异步的问题,居然mutations能改变状态,那我们在他的基础上加点什么东西是不是就能 解决异步的问题呢?没错就是actions,

methods----------------------------------------$store.dispatch------------------------------->actions------------------------------->mutations

[解决异步问题,就是在mutations上多了个ations这个步骤,这样解释只是为了大家更好的接受而已,不一定正确]

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="../lib/vue.js"></script>
        <script src="../lib/vuex.js"></script>
    </head>
    <body>
        <p>关于action:
        官方说的是为了解决异步的问题,
        因为mutations中可能有多个无方法接口,同步执行会大大的降低效率,因此我们急切需要一种方法,及action</p>
        <div id="app">
            <first-child></first-child>
        </div>        
    </body>
</html>
<script>        
    const ch1={
        template:`
           <div>
           <p>这是我的第一个组件</p>
           <p> <button @click="adds(num)">通过action进行操作</button>:  <span>{{num}}</span></p>               
           <p> <button @click="add(num)">通过mutations进行操作</button>:<span>{{num}}</span></p>             
           </div>
        `,
        methods:{
            adds:function(n){                 
                //this.$store.dispatch('addCount',n);\n
                this.$store.dispatch({type:'addCount',n:n});
            },
            add:function(n){
                //this.$store.commit('addNum',n);
                this.$store.commit({                    
                    type:'addNum',
                    n:n
                });
            }                        
        },
        computed:{
            num(){
                return this.$store.state.smalldata;
            }            
        }               
    };
    
//    const ch2={
//        template:`
//           <div>
//           <p>这是我的第二个组件</p>
//           <span>{{}}</span>
//           </div>
//        `,
//        
//    };
//      
    const store=new Vuex.Store({
        state:{
            smalldata:1,        
        },
        getters:{},
        mutations:{
            addNum(state,obj){
                state.smalldata+=obj.n;        
            }          
        },
        actions:{
//          addCount(co,n){
//              co.commit('addNum',n);
//          },
            addCount({commit},obj){
                commit('addNum',obj);                
            }            
        },              
    });
    const myvue=new Vue({
        el:'#app',
        store,
        components:{
            firstChild:ch1,
            //secondChild:ch2,
        }        
    });
</script>

 

posted @ 2017-08-09 20:23  BuleDog  阅读(846)  评论(0编辑  收藏  举报