Vue基础技能【八、vuex讲解运用】

1、Vue全家桶介绍

  • vue 核心框架
  • Vue-router 路由
  • Vuex 状态管理器
  • axios 数据请求库

2、vuex介绍

  • 作用: 大型项目的数据管理、 大型项目里的组件之间的通信。

  • 基础使用:

    • 引入Vue,引入vuex. 切记先后顺序

      <script src="vue.js"></script>
      <script src="vuex.js"></script>
      
    • 实例化一个仓库对象

      let store = new Vuex.Store({
      	  state:{
      	      // 组件共享的数据
      	  }
      })
      
    • 挂载到vue实例对象上面去

      new Vue({
       		el:"",
       		data:{},
       		store:store  //简写: store
      })
      // 我们的Vue实例和组价里面this上面将会有一个$store表示这个仓库对象
      

3、vuex核心概念

  • 含义: 核心概念其实就是Vuex实例化仓库的时候里面的配置对象

3.1、state

  • 作用: 所有组件共享的数据。可以理解为data

  • 使用:

    // 仓库中定义
    let store = new Vuex.Store({
    	  state:{
    	      // 组件共享的数据
          msg:"你好"
    	  }
    })
    
    // 组件中如何获取
    
    // 组件的配置选项中computed中
    computed:{
       //mymsg(){    // 页面中 通过  {{mymsg}}  来进行数据展示
       msg(){    //  标识符统一起来。 
         return this.$store.state.msg
       }
    }
    
    
  • 问题出现了: 组件的computed 使用来对当前组件的data数据进行处理。如果这样,这个里面将有双重含义。一部分是为了获取仓库里的数据,一部分是组件自己的计算属性。 如果多了,将难以管理,和区分。

  • 解决: 通过辅助函数mapState

    computed:{
       //msg(){    //  标识符统一起来。 
         //return this.$store.state.msg
       //}
      ...Vuex.mapState(['msg'])
      // 下面就是该组件的计算属性
    }
    
    
  • 代码实现:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <!-- 引入vue.js -->
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <!-- 引入vuex.js  一定要引入在vue之后 -->
        <script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            #app{
                width: 600px;
                height: 400px;
                background-color: #eee;
                margin: 0 auto;
                text-align: center;
            }
            .aa,.bb{
                width: 300px;
                height: 330px;
                float: left;
            }
            .aa{
                background-color: red;
            }
            .bb{
                background-color: orange;
            }
            .line{
                clear: both;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <h4>我是根组件</h4>
            <hr>
            {{msg}}
            {{str}}
            {{nums}}
            <div class="line"></div>
            <aa></aa>
            <bb></bb>
        </div>
    
        <template id="aa">
            <div class="aa">
                AA 组件
                <br>
                {{msg}}
            </div>
        </template>
    
        <template id="bb">
            <div class="bb">
                BB 组件
                <br>
                {{msg}}
            </div>
        </template>
    
    </body>
    <script>
        Vue.component('aa',{
            template:"#aa",
            created(){
                console.log(this);
                console.log(this.$store.state);
            },
            computed:{
                msg(){
                    return this.$store.state.msg
                }
            }
        })
        Vue.component('bb',{
            template:"#bb",
            created(){
                console.log(this);
                console.log(this.$store.state);
            },
            computed:{
                msg(){
                    return this.$store.state.msg
                }
            }
        })
    
        //第1步: 实例化一个vuex store实例
        // let store = new Vuex.Store({仓库配置对象});
        let store = new Vuex.Store({
            state:{  // 所有组件要共享的数据
                msg:"我是共享的msg",
                nums:1000,
                str:"我是str"
            }
        });
    
        
    
        // 第2步:将这个vuex的store实例挂载到vue实例里面去
        new Vue({
            el:"#app",
            // store:store
            store,
            created(){
                console.log(this);
                console.log(this.$store.state);
            },
            // computed:Vuex.mapState(['nums','msg','str'])
            computed:{
                ...Vuex.mapState(['nums','msg','str'])
                // 这些计算属性只是为了访问仓库里面的数据
                // msg(){
                //     return this.$store.state.msg
                // },
                // nums(){
                //     return this.$store.state.nums
                // },
                // str(){
                //     return this.$store.state.str
                // }
    
                // 当前Vue实例的一些计算属性,用于对data中数据处理展示
                // ...
            }
        })
    
    
        // 渲染:我们 不可以 直接使用 {{ $store.state.变量名  }} 去渲染数据,因为后期数据变化,不更新
        // 如何渲染:   
                // 在组件内部通过定义  computed 来显示
    
    </script>
    </html>
    

3.2、getters

  • 作用: 有时候我们希望拿到的时候对仓库中的数据进行处理后的结果。 类似于computed。 对state立面的数据进行处理。

  • 使用:

    // 仓库中定义
    let store = new Vuex.Store({
    	  state:{
    	      // 组件共享的数据
          msg:"你好"
    	  },
    	  getters:{
    	  	newmsg(state){   // 切记getters 每个选项都是一个函数,且必须有返回值
    	  	   return state.msg+',大家好才是真的好'
    	  	}
    	  }
    })
    
    // 组件中如何获取
    
    // 组件的配置选项中computed中
    computed:{
    		//mynewmsg(){
    			//return this.$store.getters.newmsg
    		//}
      	newmsg(){
          	return this.$store.getters.newmsg
        }
    }
    
    
  • 问题出现: 和state的问题一样。同样会导致 computed难以管理。

  • 解决办法:

    // 组件中如何获取
    
    // 组件的配置选项中computed中
    computed:{
    		//mynewmsg(){
    			//return this.$store.getters.newmsg
    		//}
      	//newmsg(){
          	//return this.$store.getters.newmsg
        //}
        ...Vuex.mapGetters(['newmsg'])
    }
    
  • 代码实现:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <!-- 引入vue.js -->
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <!-- 引入vuex.js  一定要引入在vue之后 -->
        <script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            #app{
                width: 600px;
                height: 400px;
                background-color: #eee;
                margin: 0 auto;
                text-align: center;
            }
            .aa,.bb{
                width: 300px;
                height: 330px;
                float: left;
            }
            .aa{
                background-color: red;
            }
            .bb{
                background-color: orange;
            }
            .line{
                clear: both;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <h4>我是根组件</h4>
            <hr>
            {{arrlen}}
            <div class="line"></div>
            <aa></aa>
            <bb></bb>
        </div>
    
        <template id="aa">
            <div class="aa">
                AA 组件
                <br>
            </div>
        </template>
    
        <template id="bb">
            <div class="bb">
                BB 组件
                <br>
            </div>
        </template>
    
    </body>
    <script>
        Vue.component('aa',{
            template:"#aa",
        })
        Vue.component('bb',{
            template:"#bb",
        })
    
        //第1步: 实例化一个vuex store实例
        // let store = new Vuex.Store({仓库配置对象});
        let store = new Vuex.Store({
            state:{  // 所有组件要共享的数据    类似于data
                msg:"我是共享的msg",
                arr:[11,22,33,44,5,66,7,8]
            },
            getters:{  // 类似于计算属性  类似computed     对state里面的数据进行处理
                arrlen:function(state){  // state就是上面的state
                    return state.arr.length
                }
            }
        });
    
        // 第2步:将这个vuex的store实例挂载到vue实例里面去
        new Vue({
            el:"#app",
            // store:store
            store,
            created(){
                console.log(this.$store);
            },
            computed:{
                // arrlen:function(){
                //     return this.$store.getters.arrlen
                // }
                ...Vuex.mapGetters(['arrlen'])
            }
            
        })
    
    
        //   getters的作用: 对state里面的数据进行处理,加工 。 对外部进行共享
        //   getter的使用: 非常类似于computed
                /*   
                    getter:{
                        变量名(state){  // state就是仓库中的共享数据对象
                            return state.变量 +1   // 处理
                        }
                    }
                */
            // 外部的组件如果想用这个getters里面的变量
                    // 在组件或者Vue实例的计算属性里面
                    /*
                        computed:{
                            自定义一个变量(){
                                return this.$store.getters.变量名
                            }
                        }
                    */
    
    </script>
    </html>
    

3.3、mutations

  • 作用: 修改仓库中的数据。切记仓库中的数据修改不可以是通过 this.$store.state.变量 = 新值 这种方式。所有的仓库数据修改都是通过mutations。

  • 使用:

    // 仓库中定义
    let store = new Vuex.Store({
    	  state:{
    	      // 组件共享的数据
          msg:"你好"
    	  }
    	  mutations:{
    	  		CHANGEMSG:function(state,参数){
        				console.log(参数)
      					state.msg = "我是新的"+state.msg
    				}
    	  }
    })
    
  • 如何去调用CHANGEMSG

    //组件里面
    this.$store.commit('CHANGEMSG',传参)
    //  将这个修改事件挂载到组件this上面去。
    methods:{
       ...Vuex.mapMuations(['CHANGEMSG'])  // 组件this上面将会有 CHANGEMSG   this.CHANGEMSG()
    }
    

3.4、actions

  • actions也是用来修改state。但是他不是直接修改。他是触发mutations。属于间接修改, 为什么要多一层呢?因为actions可以包含异步。

  • 使用:

    // 仓库中定义
    let store = new Vuex.Store({
    	  state:{
    	      // 组件共享的数据
          msg:"你好"
    	  }
    	  mutations:{
    	  		CHANGEMSG:function(state,参数){
        				console.log(参数)
      					state.msg = "我是新的"+state.msg
    				}
    	  },
    	  actions:{
    	  		changemsg:function(context,参数啊){  // context 是当前的仓库对象
    	  			context.commit('CHANGEMSG',参数啊);
    	  		}
    	  }
    })
    
    //组件里面
    this.$store.dispatch('changemsg',传参A)
    //  将这个修改事件挂载到组件this上面去。
    methods:{
       ...Vuex.mapActions(['changemsg'])  // 组件this上面将会有 changemsg this.changemsg('实参')
    }
    
发布了10 篇原创文章 · 获赞 0 · 访问量 125

猜你喜欢

转载自blog.csdn.net/qq_32620027/article/details/104379540
今日推荐