如果你之前使用过vue.js,你一定知道在vue中各个组件之间传值的痛苦,在vue中我们可以使用vuex来保存我们需要管理的状态值,值一旦被修改,所有引用该值的地方就会自动更新,那么接下来我们就来学习一下vuex是如何修改状态值的:
先说说Vuex是什么
Vuex是一个专为Vue.js应用程序开发的状态管理模式
这个状态我们可以理解为在data中的属性,需要共享给其他组件使用的部分,即Vuex进行统一集中式的管理需要共享的data
什么是“状态管理模式”
- 其包含一下几个部分:
- state:驱动应用的数据源
- view:以声明方式将state映射到视图
-
actions:响应在view上的用户输入导致的状态变化
下面是一个表示“单向数据流”理念的简单示意图
Vuex和单纯的全局对象有何不同?
1.Vuex的状态存储是响应式的
当Vuex组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会相应的得到高效更新
2.你不能直接改变store中的状态
改变store中的状态的唯一途径就是显示地提交(commit)mutation,方便我们跟踪每一个状态的变化
总结一下什么情况下我们应该使用Vuex?
- 适用于:
- 大小型单页应用,你可能会考虑如何让把组件的共享状态抽取出来,以一个全局单例模式管理,不管在哪个组件,都能获取状态/触发行为,解决问题如下:
- ①多个视图使用于同一个状态:传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力
- ②不同视图需要变更同一状态:采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝,通常会导致无法维护的代码
- 大小型单页应用,你可能会考虑如何让把组件的共享状态抽取出来,以一个全局单例模式管理,不管在哪个组件,都能获取状态/触发行为,解决问题如下:
- 不适用:
- 小型简单应用,用Vuex是繁琐冗余的,更适合使用简单的store模式
开始Vuex的使用吧
1.首先创建一个vue-cli项目
执行下面的命令,创建一个名称为app的项目
vue init webpack app
2.创建完成后,我们进入文件夹下,并且运行项目
cd app/
npm run dev
接下来我们在src目录下创建一个vuex文件夹再vuex文件夹下创建一个index.js文件
3.下载引入vuex
在命令行输入下面命令安装vuex
npm install vuex --sav
// index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
})
// main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
-
state:
// index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state= {
count: 0
}
export default new Vuex.Store({
state
})
// main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
然后在任意组件中使用就能看到count了
这里我们在helloWorld中使用一下,去除helloworld.vue中不用的标签
<template>
<div class="hello">
<h3>{{$store.state.count}}</h3>
</div>
</template>
打开刚才运行项目的浏览器,就可以看到已经使用成功了
并且在vue开发工具中我们可以看到我们定义的变量count
-
Mutations:
提交mutations修改count值,该对象中有两个方法,mutations里面的参数,第一个默认为state,接下来的为自定义参数。
我们在mutations中定义两个方法,增加和减少,并且设置一个参数n,默认值为0
// index.js
const mutations = {
mutationsAddCount(state, n = 0) {
return (state.count += n)
},
mutationsReduceCount(state, n = 0) {
return (state.count -= n)
}
}
export default new Vuex.Store({
state,
mutations
})
helloworld.vue:
<template>
<div class="hello">
<h3>{{$store.state.count}}</h3>
<div>
<button @click="handleAddClick(10)">增加</button>
<button @click="handleReduceClick(10)">减少</button>
</div>
</div>
</template>
<script>
export default {
methods: {
handleAddClick(n){
this.$store.commit('mutationsAddCount',n);
},
handleReduceClick(n){
this.$store.commit('mutationsReduceCount',n);
}
}
}
</scrptt>
来看看浏览器的效果吧
-
actions:
前面我们使用mutations达到了修改store中状态值的目的,但是,官方并不介意我们这样直接去修改store里面的值,而是让我们去提交一个actions
actions是异步操作
这里我在两个方法中使用了两个不同的参数,一个是context,它是一个和store对象具有相同对象属性的参数。在第二个函数中,我是直接使用了这个对象的commit的方法。
// index.js
const actions = {
actionsAddCount(context, n = 0) {
console.log(context)
return context.commit('mutationsAddCount', n)
},
actionsReduceCount({ commit }, n = 0) {
return commit('mutationsReduceCount', n)
}
}
export default new Vuex.Store({
state,
mutations,
actions
})
在helloWorld.vue中,增加两个方法,使用dispath来触发
<div>异步操作</div>
<div>
<button @click="handleActionsAdd(10)">异步增加</button>
<button @click="handleActionsReduce(10)">异步减少</button>
</div>
handleActionsAdd(n){
this.$store.dispatch('actionsAddCount',n)
},
handleActionsReduce(n){
this.$store.dispatch('actionsReduceCount',n)
}
-
getters:
我们一般使用getters来获取我们的state,因为它相当于vue中的computed计算属性,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算,这里我们可以通过定义vuex的Getter来获取,Getters 可以用于监听、state中的值的变化,返回计算后的结果
// index.js
const getters = {
getterCount(state, n = 0) {
return (state.count += n)
}
}
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
helloWorld.vue
<h4>{{count}}</h4>
const getters = {
getterCount(state) {
return (state.count += 10)
}
}
vuex官方给了我们一个更简单的方式来使用vuex, 也就是 {mapState, mapMutations, mapActions, mapGetters},这里我们采用了es6的扩展运算符
<script>
import {mapState, mapMutations, mapActions, mapGetters} from 'vuex'
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
methods: {
...mapMutations({
handleAddClick: 'mutationsAddCount',
handleReduceClick: 'mutationsReduceCount'
}),
...mapActions({
handleActionsAdd: 'actionsAddCount',
handleActionsReduce: 'actionsReduceCount'
})
// handleAddClick(n){
// this.$store.commit('mutationsAddCount',n);
// },
// handleReduceClick(n){
// this.$store.commit('mutationsReduceCount',n);
// },
// handleActionsAdd(n){
// this.$store.dispatch('actionsAddCount',n)
// },
// handleActionsReduce(n){
// this.$store.dispatch('actionsReduceCount',n)
// }
},
computed: {
...mapGetters(['count'])
}
}
</script>
网友评论