vue-vuex

概念

  • vuex是一个专为vue.js应用程序开发的状态管理模式,它采用的集中式存储管理应用所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。vuex也集成到vue的官方调试工具。
  • 状态管理模式、集中管式存储管理,其实可以理解成把多个组件需要共享的变量存储在一个对象里面;然后将这个对象放在顶层的vue组件示例中,让其他组件也可以使用。
  • 自己也可以封装一个对象,但不能保证所有的属性都是响应式的
  • 一般在大型项目开发中,比如用户的登录状态、用户名称、头像、地理位置等都是需要在组件之间共享的状态

单界面状态管理

<template>
  <div id="app">
    <div>Hello</div>
    <div>{{count}}</div>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>

<script>


export default {
  name: 'App',
  data:function(){
    return {
      count:0
    }
  },
  components: {

  },
  methods:{
    increment(){
      this.count++;
    },
    decrement(){
      this.count--;
    }

  }
}

state:data中count
view:视图层,template中显示count
action:@click 事件
在这里插入图片描述

多界面状态管理

全局单例模式

  • 将共享的状态抽取出来,交给我们的大管家统一管理
  • 之后每个视图,按照规定,进行访问和修改等操作

Vue Components–>Action–>Mutation–>State–>Vue Components(正常操作,action可以有异步操作)
Vue Components—>Mutation (只能是同步操作)

Mutation<---->Devtools(插件)
在这里插入图片描述

基本使用

注意:

  • Vuex不是constructor
  • 创建对象时用的是Vuex.Store,这个也跟我们创建文件名store是一致的

//store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
// 1安装插件
Vue.use(Vuex)
//2创建对象
const store = new Vuex.Store({
    state:{
        count:0
    },
    mutations:{
        //state默认参数,不需要我们自己传,和store对象中的state是一样的
        increment(state){
            state.count++;
        },
        decrement(state){
            state.count--;
        }
    },
    action:{},
    getters:{
    },
    modules:{
    }

})
//3导出对象
export default store

//app.vue

<template>
  <div id="app">
    <div>Hello</div>
    <div>{{count}}</div>
    <button @click="incrementAction">+</button>
    <button @click="decrementAction">-</button>
  </div>
</template>

<script>


export default {
  name: 'App',
  data:function(){
    return {
    }
  },
  //定义一个计算属性,属性的值经常变化
  computed:{
    count: function () {
      return this.$store.state.count;
    }

  },
  components: {

  },
  methods:{
    incrementAction(){
      this.$store.commit('increment')
    },
    decrementAction(){
      this.$store.commit('decrement')
    }

  }
}
</script>

总结:

  1. 提取出一个公共的store对象,用于保存在多个组件中共享的状态

  2. 将store对象放置在new vue对象中,这样可以保证在所有的组件中都可以使用

  3. 在其他组件中使用store对象中保存的状态即可
    通过this.$store.state.属性的方式来访问状态;

    通过this.$store.commit(‘mutation中方法’)来修改状态;

  4. 我们是通过mutation的方式,而非直接改变store.state.count,这是因为Vuex可以更明确的追踪状态的变化,所以不要直接改变store.state.count的值

Getters的使用

单一状态树(Single Source of Truth)
如果你的状态信息保存到多个store对象中,那么之后的管理和维护等等都会变的特别困难,随意vuex使用了单一状态树来管理应用层的全部状态,单一状态树能够让我们最直接的方式找到某个状态的片段,而且之后的维护和调试过程中,也可以非常方便的管理和维护

Getter类似Computed中的属性

//store/index.js

const store = new Vuex.Store({
    state:{
        count:0,
        students:[
            {id:1,name:'kobe',age:12},
            {id:2,name:'james',age:14},
            {id:3,name:'kuli',age:10},
        ]
    },

    getters:{
        greaterAgeCount:state=>{
            return state.students.filter(item=>item.age>11);
        }

    },


})
<template>
  <div id="app">
    <div>{{greater11}}</div>
  </div>
</template>

<script>


export default {
  name: 'App',

  computed:{
    greater11:function(){
      return this.$store.getters.greaterAgeCount;
    }
  },

}
</script>
Getters传参数

注意:getters默认是不能传递参数的,如果希望传递参数,那么只能让getters本身返回另一个函数
//vue/index.js

const store = new Vuex.Store({
    state:{
        count:0,
        students:[
            {id:1,name:'kobe',age:12},
            {id:2,name:'james',age:14},
            {id:3,name:'kuli',age:10},
        ]
    },

    getters:{
    
        greaterAge:state=>{
        //返回一个函数,可接受参数age
            return (age)=>{
                return state.students.filter(item=>item.age>age)
            }
        },
    },

})

// App.vue

<template>
  <div id="app">
    <div>Hello</div>
    <div>{{count}}</div>
    <button @click="incrementAction">+</button>
    <button @click="decrementAction">-</button>
    <div>{{greater11}}</div>
    <div>{{greaterAge}}</div>
  </div>
</template>

<script>


export default {
  name: 'App',
  computed:{
    greaterAge:function(){
      return this.$store.getters.greaterAge(12);
    }
  },


}
</script>

Mutations状态更新

vuex中的state状态更新的唯一方式:提交Mutaiton
Mutation主要包括两部分:

  • 字符串的事件类型,如果increment
  • 一个回调函数(handler),该回调函数的第一参数就是state,如increment后面的函数
    在这里插入图片描述
    定义方式:
    mutations:{
        //state默认参数,不需要我们自己传,和store对象中的state是一样的
        increment(state){
            state.count++;
        },
        decrement(state){
            state.count--;
        }
    },

更新方式:

  methods:{
    incrementAction(){
      this.$store.commit('increment')
    },
    decrementAction(){
      this.$store.commit('decrement')
    }

  }
Mutations传递参数

在通过mutation更新数据的时候,有可能我们携带一些额外的参数

  • 参数被成为是mutation的载荷(Payload)
  • 如果参数不是不止一个,通常我们会以对象的形式传递
    //定义
    mutations:{
        incrementCount(state, count) {
            state.count = state.count + count;
        }
    },

//调用

  methods:{
    incrementCountAction(){
      this.$store.commit('incrementCount',5)
    }
  }
Mutations响应规则

Vuex中的store是响应式的,当state中的数据发生改变,vue组件会自动更新
规则:

  1. 提前在store中初始化所需要的属性
  2. 当给state中的对象添加属性时,使用下面的方式:
    方式一:使用vue.set(obj,‘newProp’,123)
    方式二:用新对象给老对象赋值

初始化所有属性响应式

    mutations:{
        addstudent(state){
            state.students.push({
                id:4,
                name:'test',
                age:13,
            });
        }
    },

添加属性非响应式

const store = new Vuex.Store({
    state:{
        info:{
            name:'ly',
            age:18
        }
    },
    mutations:{

        updateInfo(state){
            state.info['address']='jx'
        }
    },

})
  methods:{
    updateInfo(){
      this.$store.commit('updateInfo');
    }
  }

添加属性响应式

  • 方式一:Vue.set
        updateInfo(state){
            Vue.set(state.info,'address','jx')
        }

在这里插入图片描述

  • 方式二:用新对象给老对象赋值
        updateInfo(state){
            state.info={...state.info,'address':'jx'}
        }

删除属性非响应式

        updateInfo(state){
            delete state.info.age
        }

删除属性相应式

        updateInfo(state){
            Vue.delete(state.info,'age')
        }

mutations const

定义
store/mutationtype.js

export const INCREMENT ='increment';

使用
//store/index.js

    mutations:{
        //state默认参数,不需要我们自己传,和store对象中的state是一样的
        [INCREMENT](state){
            state.count++;
        },
        }

//app.vue

  methods:{
    incrementAction(){
      this.$store.commit(INCREMENT)
    },
    }
Mutations同步函数

通常情况下,vuex要求我们Mutation中的方法必须是同步方法

  • 主要是因为当我们使用devtool时,devtool可以帮助我们捕捉mutation的快照
  • 但是如果是异步操作,devtools将不能很好的追踪这个操作什么时候会被完成
  • 当执行异步操作时,你会发现界面上的数据更新了,但是devtool中的state的数据没有更新

Actions

Actions类似于Mutations,用来替代Mutation进行异步操作
可以返回promise中

Actions的基本使用

定义
store/index.js

    actions: {
        aUpdatename(context) {
            setTimeout(() => {
                //context.state.info.name="ssh";不要这样修改
                context.commit('updatename');
            }, 1000);
        }
    },

App.vue
调用

    updatename() {
      this.$store.dispatch('aUpdatename');
    }

store/index.js
传参

    mutations:{
        updatename(state, pageload){
            setTimeout(()=>{
                state.info.name = pageload;
            },1000)
        }
    },
        actions: {
        aUpdatename(context,payload) {
            setTimeout(() => {
                //context.state.info.name="ssh";不要这样修改
                context.commit('updatename',payload);
                console.log(payload);
            }, 1000);
        }
    },

App.vue

methods:{
    updatename() {
      //this.$store.commit('updatename');
      this.$store.dispatch('aUpdatename','我是pageload');
    }
}

执行成功,回调
方式一:(不建议)
App.vue

    updatename() {
      this.$store.dispatch('aUpdatename', ()=>{
        console.log("执行成功");
      });
    }

index.js

    actions: {
        aUpdatename(context, payload) {
            setTimeout(() => {
                context.commit('updatename',payload);
                console.log(payload);
                payload();
            }, 1000);
        }
    },

方式二 promise

        aUpdatename(context, payload) {
            return new Promise((resolve,reject)=>{
                setTimeout(() => {
                    context.commit('updatename',payload);
                    console.log(payload);
                    resolve('success');
                }, 1000);
            })
        }
    updatename() {
      this.$store.dispatch('aUpdatename', 'pageload').then(res=>{
        console.log(res);

      });
    }

mudules

vue使用单一状态树,那么也意味着很多状态都会交给vuex来管理
当应用变得非常复杂时,store对象就有可能变得相当臃肿,为了解决这个问题,vuex允许我们将store分割成块(module),而每个模块拥有自己得state,mutations,actions,getters等

state得使用

<div>{{$store.state.a.name}}</div>
    modules:{
        a:{
            state:{
                name:'modelue A'
            },
        }
    }

mutations的使用

    mutations:{
        updatename(state) {
            state.info.name = 'ss';
        }
    },
    modules:{
        a:{
            state:{
                name:'modelue A'
            },
            mutations:{
                updatename(state){
                    state.name="module aleter name"
                }
            }            
        }
    }

当在App.vue中调用时

    updatename(){
      this.$store.commit("updatename");
    }

优先在mutations中找,然后再从modules中得mutations中找

getters的使用

定义

    modules:{
        a:{
            getters:{
                fullname(state){
                    return state.name + "11111";
                },
               fullname2({state,getters,rootState}) {
                    return gutters.fullname + 2222;
                }
            }    
        }
    }

app.vue

    <div>{{$store.getters.fullname}}</div>
    <div>{{$store.getters.fullname2}}</div>

如果根store中与module中的store有相同的getter是,会报错误
在这里插入图片描述
actions的用法

    modules:{
        a:{
                    mutations:{
                updatename(state){
                    state.name="module aleter name"
                }
            },
            actions:{
                aUpdatename({state,commit,rootState}){
                    setTimeout(()=>{
                        context.commit('updatename');
                    },1000)

                }
            }            
        }
    }
methods:{
    aUpdateName(){
      this.$store.dispatch("aUpdatename");
    }
}

store 项目结构的优化

import Vue from 'vue'
import Vuex from 'vuex'
import Mutations from './mutations'
import Acions from './actions'
import Getters from './getters'
import ModuleA from './modules/moduleA'
// 1安装插件
Vue.use(Vuex)
const obj = {
    name:'lls',
    age:18,
    height:170
  }
  const {name ,age, height}= obj
  
  console.log(name)
//2创建对象
const store = new Vuex.Store({
    state: {
        count: 0,
        students: [
            { id: 1, name: 'kobe', age: 12 },
            { id: 2, name: 'james', age: 14 },
            { id: 3, name: 'kuli', age: 10 },
        ],
        info: {
            name: 'ly',
            age: 18
        }
    },
    mutations: Mutations,
    actions: Acions,
    getters: Getters,
    modules: {
        a: ModuleA
    }

})
//3导出对象
export default store

mutations,actions,getters,modules都抽到对应的文件里去,这样好维护,代码看起来也简洁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值