vuex 详解(2)

vuex 详解(2)

1. mutations 状态更新

  • vuex的store状态更新的唯一方式:提交mutation
    (官方文档说明!!!)

  • Mutation主要包括两部分:

    1. 字符串的事件类型(type)
    2. 一个回调函数(handler),该回调函数的第一个参数就是state

mutation定义方式:

mutation:{
    increment(state){
        state.counter++
    }
}

//定义increment函数修改state中的数据

mutation更新方式:

increment(){
    this.$store.commit('increment')
}

//在组件里面使用函数,实现state状态的改变

2. mutations 参数传递

  • 需求:通过mutation传入参数,实现数据一次加5,一次加10
    mutations定义函数:
mutations:{
        incrementCount(state, count){
            state.counter += count;
        }
    },
    //除了传入状态state外,还传入了参数count

组件内mutation实现数据更新:

methods:{
      incrementCount(count ){
        this.$store.commit('incrementCount',count)
      }
  }
//然后@click = 'incrementCount(5)' 就可以实现需求
  • 而加入我们想传递多于一个的参数呢?
    这个时候我们会以对象的形式传递,也就是paylode是一个对象。
    再从paylode读取我们想要的信息。

  • 以对象的方式传递:

incrementCount(count ){
        this.$store.commit({
          type:'incrementCount',
          count
        })
      },
  • 调用:
incrementCount(state, payload){
        state.counter += payload.count;
    },
    //通过payload.count 来读取相应的数据

3. mutations 代码风格优化

  • 普通风格
methods:{
      incrementCount(count ){
        this.$store.commit('incrementCount',count)
      }
  }
  • 特殊风格
methods:{
      incrementCount(count ){
        this.$store.commit({
            type:'incrementCount',
            count
        })
      }
  }

这种方式传递过去的count将会是一个对象,确切的说他就是payload,是一个对象,而如果你要使用count的话应该这样使用:

  mutations:{
        incrementCount(state, payload){
            state.counter += payload.count;
        }
    },

4.响应式原理

  • vue官方明确定义,vuex实现响应式的最基本要求是,state状态定义了变量,才可以实现数据的响应式。
  • 举个例子:
state:{
	info:{
            name:'康家豪',
            age:20,
            lab:'xiyounet'
        }
}
//现在在state中定义一个info数据,info中定义了name,age,lab属性。

先将数据渲染在组件的页面内,再通过按钮点击事件,我将对info数据进行修改:

 mutations:{
 	changeInfo(state){
       state.info.name = 'kangjiahao',
       state.info.age = 100,
       state.info.lab = 'netxiyou'
//注意:因为我的name, age ,lab 属性都已经再state中定义过了,所以修改后,页面View层中的数据就会实现响应式更新。
		state.info['address'] = 'home'
		//这个数据就不会实现响应式渲染在页面上因为他没有再state中定义,不能实现响应式。
      
    }
}
  • 那么我如何实现没有在state中定义过的状态以响应式的方式渲染在页面上呢?

  • vue.set() 响应式控制数据,
    调用方法:Vue.set( target, key, value )
    target:要更改的数据源(可以是对象或者数组)
    key:要更改的具体数据
    value :重新赋的值

  • vue.delete() 响应式删除数据
    调用方法:Vue.set( target, key, )
    target:要更改的数据源(可以是对象或者数组)
    key:要更改的具体数据

 mutations:{
 	changeInfo(state){
       vue.set(state.info,'address','home')
       //vue.set()  实现将数据以响应式的方式渲染在组件内
		state.info['address'] = 'home'
		
		//响应式删除
		Vue.delete(state.info,'age')
		//vue.delete
      
    }
}

5.mutations同步函数和异步函数的区别

  • mutations同步函数 (为什么要用到actions)
    (vue官方文档说明 mutation中函数最好为同步函数)
    因为我们使用了devtools工具来跟踪状态的改变,所以当mutation函数为同步状态时
//devtools中数据  原始数据
baseState{
    info:Object
            name:"康家豪"
            age:20
            slab:"xiyounet"
}

执行xiugai函数:

 xiugai(state){
       state.info.name = 'kangjiahao',
       state.info.age = 100,
       state.info.lab = 'netxiyou'
    }
//devtools中数据   修改数据
xiugai{
    info:Object
        name:"kangjiahao"
		age:100
		lab:"netxiyou"
           //数据发生了实时的改变,
}
  • 那么问题来了,因为我们使用了devtools开发工具,mutations中使用异步函数函数会让我们无法跟踪state状态的改变。因为state中的数据和页面响应的数据不一致

  • 而如果我使用异步函数:

 xiugai(state){
       setTimeout(()=>{
        state.info.name = 'kangjiahao',
        state.info.age = 100,
        state.info.lab = 'netxiyou'
       },1000)
    }

这个时候devtools中数据原始数据和修改后的info中是一样的,但是数据已经更新了。这就让我们无法再devtools中跟踪state状态
以上数据均在devtools中查看

6.actions的使用

vue官方文档强调,不要在Mutation中进行一些异步操作,比如网络请求,必然是异步的,时候怎么处理呢?
Actions类似于Mutations,但是用来代替Mutation继续异步操作的。

  • Action的使用:
//在mutations中定义函数 xiugai ,在actions中异步使用

	//函数xiugai
	xiugai(state){
       state.info.name = 'kangjiahao',
       state.info.age = 100,
       state.info.lab = 'netxiyou'
    }
	//actions异步使用xiugai
   actions:{
        UpData(context){
            setTimeout(()=>{
                context.commit('xiugai')
            })
        }
    },
	//  将修改绑定到元素身上。
    xiugai(){
        this.$store.dispatch('UpData')
      }
  

这样使用devtools中的state状态也会实时发生改变。

  • actions也可以传参
actions:{
        xiugai(context,payload){
            setTimeout(()=>{
                context.commit('xiugai',payload)
                console.log(payload)
            })
        }
    },
  • 上面这种方式只能解决传递一个参数,那么如果我要传递两个参数呢?
    使用promise方法:超级优雅的代码
 actions:{
        xiugai(context,payload){
           return new Promise((resolve, reject)=>{
            setTimeout(()=>{
                context.commit('xiugai',payload)
                resolve(payload);
            },2000);
           
           })
        }
    },

     xiugai(){
        this.$store
        .dispatch('xiugai','我是携带的信息')
        .then(res=>{
          console.log('里面完成了提交');
          console.log(res);
        })
      }

      //在action中return一个promise对象,在修改函数中,.then返回结果和下一步操作
  • 注意actions中不在使用commit而是使用dispatch

7.modules的使用

  • question one
    vue官方文档不是推荐单一状态树嘛!!!
    那么为什么我们在vuex中使用模块呢?
    vue推荐我们使用单一状态树,也就意味着很多状态都会交给vuex来管理。
    当应用变得非常复杂时,store对象就有可能变得非常臃肿
    为了解决这个问题,vuex允许在module中让我们可以去划分新的module,
    新的module可以有state,mutations,actions,getters,以及新的module
    +基本代码演示
const moduleA = {
	 state:{},
    mutations:{},
    actions:{},
    getters:{},
    modules:{}
}

const store = new Vuex.Store({
    state:{},
    mutations:{},
    actions:{},
    getters:{],
    modules:{
        a:moduleA
    }
})
  • 那么新的moduleA中的数据如果我要渲染在页面上该怎么操作?
const moduleA = {
	 state:{
        name:'康家豪2号'
    },
    mutations:{
        changeData(state,payload){  
            state.name = payload
        }
    },
    getters:{
        fullName(state){
            return state.name = state.name + '康家豪二号'
        },
        fullName2(state,getters){
            return getters.fullName  + '222';
        },
        fullName3(state,getters,rootState){
            return rootState.counter;
        }
    },
    actions:{
        changeData2(context,payload){    //这里的context取到的是自己模块里面的mutations
            setTimeout(()=>{
                context.commit('changeData',payload)
            },1000)
        }
    },
    modules:{}
}
  • 在相关组件中使用:
state数据使用: $store.state.a.name
我原本以为是这样的{{ $store.modules.a.state.name }}
然而是错的 
正确的是这样的:{{ $store.state.a.name }}
vue会将你modules中的state放入最大的state总管的state里面

mutations,getters,actions,都和之前使用一样

8.store文件目录结构

  • 可以把mutations, getters,actions,modules 抽离成一个js文件,
  • 方便代码管理和后期维护。
  • 而modules或许会有好几个模块,所以需要放在module文件夹下。
  • 我的store文件的目录结构
    在这里插入图片描述

嗯嗯 现在为止 基本 vuex 能掌握的都差不多了

————————————————————————————————————
我曾七次鄙视自己的灵魂:
第一次,当它本可进取时,却故作谦卑;
第二次,当它空虚时,用爱欲来填充;
第三次,在困难和容易之间,它选择了容易;
第四次,它犯了错,却借由别人也会犯错来宽慰自己;
第五次,它自由软弱,却把它认为是生命的坚韧;
第六次,当它鄙夷一张丑恶的嘴脸时,却不知那正是自己面具中的一副;
第七次,它侧身于生活的污泥中虽不甘心,却又畏首畏尾。
————————————————————————————————————

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue.js是一个流行的JavaScript框架,它允许您构建动态Web应用程序。Vuex是一个专为Vue.js应用程序开发的状态管理模式。它允许您在应用程序中管理和维护状态,例如用户信息、购物车、主题等。Vuex将状态存储在一个集中的存储库中,称为storeVuex的核心概念包括state、mutations、actions和getters。 - state:存储应用程序级别的状态,可以通过store.state访问。 - mutations:用于更改状态的函数,必须是同步函数。可以通过store.commit方法调用。 - actions:用于处理异步操作的函数,可以包含任意异步操作。可以通过store.dispatch方法调用。 - getters:用于从store中获取状态的函数,可以通过store.getters访问。 下面是一个简单的示例,演示如何在Vue.js应用程序中使用Vuex: 1.安装Vuex ```shell npm install vuex --save ``` 2.创建store ```javascript import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { incrementAsync ({ commit }) { setTimeout(() => { commit('increment') }, 1000) } }, getters: { getCount: state => { return state.count } } }) export default store ``` 3.在Vue组件中使用store ```javascript <template> <div> <p>Count: {{ count }}</p> <button @click="increment">Increment</button> <button @click="incrementAsync">Increment Async</button> </div> </template> <script> import { mapGetters, mapActions } from 'vuex' export default { computed: { ...mapGetters([ 'getCount' ]) }, methods: { ...mapActions([ 'increment', 'incrementAsync' ]) } } </script> ``` 在上面的示例中,我们创建了一个名为count的状态,并定义了一个名为increment的mutation和一个名为incrementAsync的action。我们还定义了一个名为getCount的getter,用于从store中获取count状态。在Vue组件中,我们使用mapGetters和mapActions帮助程序将getter和action映射到组件中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值