vuex学习笔记

组件是Vue最强大的功能之一,而组件实例的作用域是相互独立的,意味着不同组件之间的数据是无法相互使用。组件间如何传递数据就显得至关重要,这篇文章主要是介绍Vuex。尽量以通俗易懂的实例讲述这其中的差别,希望对小伙伴有些许帮助。

一、Vuex 是什么?

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

二、什么是“状态管理模式”?

一个简单的 Vue 计数应用开始:

new Vue({	
  // state	
  data () {	
    return {	
      count: 0	
    }	
  },	
  // view	
  template: `	
    <div>{{ count }}</div>	
  `,	
  // actions	
  methods: {	
    increment () {	
      this.count++	
    }	
  }	
})

这个状态自管理应用包含以下几个部分:

state,驱动应用的数据源; view,以声明方式将 state 映射到视图; actions,响应在 view 上的用户输入导致的状态变化。640?wx_fmt=pngstate 的数据会在 view 上显示出来,用户会根据 view 上的内容进行操作,从而触发 actions,接着再去影响 state(vue 是单向数据流的方式驱动的)。

当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏。下面的图,是把组件的共享状态抽取出来,以一个全局单例模式管理。

640?wx_fmt=png

三、核心概念

1. state

state:页面状态管理容器对象。集中存储Vue components中data对象的零散数据,以进行统一的状态管理。页面显示所需的数据从该对象中进行读取。

  <div>	
    {{ $store.state.count }}	
  </div>	
   console.log(this.$store.state.count)
2. getters

getters:Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。(getters从表面是获得的意思,可以把他看作在获取数据之前进行的一种再编辑,相当于对数据的一个过滤和加工。getters就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。)

定义getter:

  getters: {	
    done(state) {    	
      return state.count + 1;	
    },	
  }
3. mutations

mutations:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

const store = new Vuex.Store({	
  state: {	
    count: 1	
  },	
  mutations: {	
    increment (state) {	
      // 变更状态	
      state.count++	
    }	
  }	
})

组件通过commit提交mutations的方式来请求改变state

this.$store.commit('increment')

提交载荷(Payload) mutations方法中是可以传参的,具体用法如下:

  mutations: {	
    // 提交载荷 Payload	
    add(state, n) {	
      state.count += n	
    }	
  },	
this.$store.commit('add', 10)
 4.Action

Action:类似于 mutation,不同在于Action 提交的是 mutation,而不是直接变更状态; Action 可以包含任意异步操作。

const store = new Vuex.Store({	
  state: {	
    count: 0	
  },	
  mutations: {	
    increment (state) {	
      state.count++	
    }	
  },	
  actions: {	
    increment (context) {	
      context.commit('increment')	
    }	
  }	
})

不同于 mutations使用 commit方法, actions使用 dispatch方法。

this.$store.dispatch('incrementAsync')

context context是与 store 实例具有相同方法和属性的对象。可以通过context.state和context.getters来获取 state 和 getters。 以载荷形式分发

incrementAsyncWithValue (context, value) {	
  setTimeout(() => {	
    context.commit('add', value)	
  }, 1000)	
}	
this.$store.dispatch('incrementAsyncWithValue', 5)
5.Module

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

const moduleA = {	
  state: { ... },	
  mutations: { ... },	
  actions: { ... },	
  getters: { ... }	
}	
	
const moduleB = {	
  state: { ... },	
  mutations: { ... },	
  actions: { ... }	
}	
	
const store = new Vuex.Store({	
  modules: {	
    a: moduleA,	
    b: moduleB	
  }	
})	
	
store.state.a // -> moduleA 的状态	
store.state.b // -> moduleB 的状态

模块的局部状态 对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象。

const moduleA = {	
  state: { count: 0 },	
  mutations: {	
    increment (state) {	
      // 这里的 `state` 对象是模块的局部状态	
      state.count++	
    }	
  },    	
  getters: {	
    doubleCount (state) {	
      return state.count * 2	
    }	
  }	
}

Vuex计数器的例子: 在src目录下创建一个store文件夹。

store/store.js

import Vue from 'vue'	
import Vuex from 'vuex'	
	
Vue.use(Vuex)	
	
const store = new Vuex.Store({	
  state: {	
    count: 0,	
    show: ''	
  },	
  getters: {	
    counts: (state) => {	
      return state.count	
    }	
  },	
  mutations: {	
    increment: (state) => {	
      state.count++	
    },	
    decrement: (state) => {	
      state.count--	
    },	
    changVal: (state, v) => {	
      state.show = v	
    }	
  }	
})	
export default store

state就是我们的需要的状态,状态的改变只能通过提交mutations,例如:

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

带有载荷的提交方式:

changObj () {	
      this.$store.commit('changVal', this.obj)	
}

载荷也可以是一个对象,这样可以提交多个参数。

changObj () {	
      this.$store.commit('changVal', {	
          key:''	
      })	
}

在main.js中引入store.js

import store from './store/store'	
export default new Vue({	
  el: '#app',	
  router,	
  store,	
  components: {	
    App	
  },	
  template: '<App/>'	
})

在组件中使用 在组建可以通过$store.state.count获得状态 更改状态只能以提交mutation的方式。

<div class="store">	
  <p>	
    {{$store.state.count}}	
  </p>	
  <button @click="increase"><strong>+</strong></button>	
  <button @click="decrease"><strong>-</strong></button>	
  <hr>	
  <h3>{{$store.state.show}}</h3>	
  <input	
    placeholder="请输入内容"	
    v-model="obj"	
    @change="changObj"	
    clearable>	
  </input>	
</div>	
</template>	
<script>	
export default {	
  data () {	
    return {	
      obj: ''	
    }	
  },	
  methods: {	
    increase() {	
      this.$store.commit('increment')	
    },	
    decrease() {	
      this.$store.commit('decrement')	
    },	
    changObj () {	
      this.$store.commit('changVal', this.obj)	
    }	
  }	
}	
</script>

640?wx_fmt=jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值