一个Vue应用中,会使用到大量的组件,如果有些数据是全局的,比如说登录以后的用户信息,有很多组件会使用到用户信息,那么父组件,子组件,孙组件都用到用户的信息的情况下,我们通常需要使用参数传递的方式,通过props传参,一层层传递,若应用很复杂,这个代码的过程就需要很细致,代码也变得难以维护,一改全改。因此,我们采用Vuex来解决这个问题。将全局需要共享的数据,都保存在一个类似于单例对象中,存取十分方便。
简单示例(计数器demo)
- Vuex管理内容的设置
const store = new Vuex.Store({
// 存放全局状态
state: {
count: 0
},
// 对state中的数据的一个包装加工(类似于计算属性)
getter: {
},
// 若要修改全局状态,一定要通过mutations来修改,若直接修改state对象,会造成特性的丢失
mutations: {
// 传入state参数对其进行操作
increment (state) {
state.count += 1; // 访问到state的count进行操作
},
decrement (state) {
state.count -= 1;
}
},
// 存放一些淡出的业务逻辑,不涉及页面行为
actions: {
}
})
- 把store注册到组件实例中
new Vue({
el: '#app',
router,
components: {App},
template: '<App/>',
store
})
- 在父组件中
<template>
<div id="app">
{{ count }}
<router-view/>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: "App",
// 引入Vuex的mapState方法,放在计算属性中,传入一个数组,把要使用的state给映射进来
// mapState返回一个类似于计算属性函数的数组,用...解构后平摊到computed中
computed: {
...mapState(['count'])
}
}
</script>
- 我们这个时候再在子组件里面去修改state中count的状态
<template>
<div>
<button @click="increase">增加</button>
<button @click="decrease">减少</button>
</div>
</template>
<script>
import {mapMutations} from 'vuex'
export default {
name: "HelloWorld",
// 同样的,我们用...解构,把对state的操作一一映射到methods中以便调用
methods: {
...mapMutations(['increment', 'decrement']),
// 这里用方法调用映射出来的操作
increase () {
this.$stroe.commit('increment')
},
decrease () {
this.$stroe.commit('decrement')
}
}
}
</script>
这个时候,点击按钮,就会对count数字进行加减的修改,这个时候打开Vue-devtool插件,可以看到具体的修改记录。
- 另一种写法
<script>
import {mapMutations} from 'vuex'
export default {
name: "HelloWorld",
// 同样的,我们用...解构,把对state的操作一一映射到methods中以便调用
methods: {
...mapMutations(['increment', 'decrement']),
// 这里用方法调用映射出来的操作
increase () {
// this.$stroe.commit('increment')
this.increment()
},
decrease () {
// this.$stroe.commit('decrement')
this.decrement()
}
}
}
</script>
注意:一定要避免直接对state中的状态进行修改,虽然直接在methods中写
this.$store.state.count +=1,也能递增,但是在Vue-devtool中是没有记录的,这样就不符合开发流程,没有规范。
进阶demo
actions中存放的是业务逻辑,我们也可以通过它来修改状态,并且可以避免mutations中的操作直接修改状态
- store文件的设置
const store = new Vuex.Store({
// 存放全局状态
state: {
count: 0
},
// 对state中的数据的一个包装加工(类似于计算属性)
getter: {
},
// 若要修改全局状态,一定要通过mutations来修改,若直接修改state对象,会造成特性的丢失
mutations: {
// 传入state参数对其进行操作
increment (state) {
state.count += 1; // 访问到state的count进行操作
},
decrement (state) {
state.count -= 1;
}
},
// 存放一些淡出的业务逻辑,不涉及页面行为
actions: {
// 我们把对state的操作通过actions来调用
myIncrease (context) {
context.commit('increment')
},
myDecrease (context) {
context.commit('decrement')
}
}
})
- 子组件的修改
<script>
import {mapMutations, mapActions} from 'vuex'
export default {
name: "HelloWorld",
methods: {
...mapMutations(['increment', 'decrement']),
...mapActions(['myIncrease', 'myDecrease']),
// 这里用方法调用映射出来的actions操作
increase () {
this.myIncrease()
},
decrease () {
this.myDecrease()
}
}
}
</script>
效果与之前的增加减少一样的,一般情况下,把状态的改变逻辑写在mutations里面,把复杂的业务逻辑写在actions中,如果actions中需要改变state的状态,就调用mutations中的改变状态的逻辑。
getter的用法
getter类似于计算属性
// 对state中的数据的一个包装加工(类似于计算属性)
getter: {
myCount (state) {
return `这是${state.count}`
}
},
- 在父组件中引入一下,直接当计算属性使用就可以
import {mapState, mapGetter} from 'vuex'
export default {
name: "App",
computed: {
...mapState(["count"]),
...mapGetter(["myCount"])
}
}











网友评论