在实际项目中遇到了全局变量和状态管理的问题,搜了一下,推荐使用vuex插件进行问题解决,参考了参考文档,学习了vuex的使用方法。记录vuex的使用。
-
安装vuex插件
vuex使用的前提是你已经创建了vue的项目,在此基础上使用npm进行vuex的安装,命令为:cnpm install vuex --save-dev
-
创建store文件夹
新建文件夹store,并在此文件夹下新建store.js文件。项目目录,如下:
然后再main.js文件中引入vuex文件,即store.js文件
最后在store.js文件添加如下代码:
//引入我们的vue和vuex。
import Vue from 'vue'
import Vuex from 'vuex'
//使用我们vuex,引入之后用Vue.use进行引用
Vue.use(Vuex);
- vuex的具体使用
①在helloworld.vue文件中修改代码,如下:
<template>
<div class="hello">
<h2>{{msg}}</h2>
<hr/>
<h3>{{$store.state.count}}</h3>
<div>
<button @click="$store.commit('add')">+</button>
<button @click="$store.commit('reduce')">-</button>
</div>
</div>
</template>
<script>
import store from '../store/store.js'
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vuex App'
}
},
store //声明
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
②store.js文件中添加如下代码:
//引入我们的vue和vuex。
import Vue from 'vue'
import Vuex from 'vuex'
//使用我们vuex,引入之后用Vue.use进行引用
Vue.use(Vuex);
const state = {
count:1
}
const mutations={
add(state){
state.count+=1;
},
reduce(state){
state.count-=1;
}
}
export default new Vuex.Store({
state,mutations
});
③页面显示
点击+或-按钮,上面的数字会随之改变,说明数据状态绑定已经成功了。
state访问状态对象(重要)
学习状态对象赋值给内部对象,也就是把store.js中的值赋值给我们模板里data中的值。有三种赋值方式:
通过computed的计算属性直接赋值
通过mapState的对象来赋值
通过mapState的数组来赋值
一. 通过computed的计算属性直接赋值
在helloworld.vue中添加计算属性(computed):
computed:{
count(){
return this.$store.state.count;
}
}
完整代码为:
<template>
<div class="hello">
<h2>{{msg}}</h2>
<h3>{{count}}</h3>
<hr/>
<h3>{{$store.state.count}}</h3>
<div>
<button @click="$store.commit('add')">+</button>
<button @click="$store.commit('reduce')">-</button>
</div>
</div>
</template>
<script>
import store from '../store/store.js'
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vuex App'
}
},
computed:{
count(){
return this.$store.state.count;
}
},
store //声明
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
这里需要注意的是 return this.
s
t
o
r
e
.
s
t
a
t
e
.
c
o
u
n
t
这
一
句
,
一
定
要
t
h
i
s
,
要
不
你
会
找
不
到
store.state.count这一句,一定要this,要不你会找不到
store.state.count这一句,一定要this,要不你会找不到store的.
二. 通过mapState的对象来赋值
在helloworld.vue中添加代码:
import {mapState} from 'vuex';//用import引入mapState。
computed:mapState({
count:state=>state.count //理解为传入state对象,修改state.count属性
}),
通过vuex中的mapState进行复制,完整代码为:
<template>
<div class="hello">
<h2>{{msg}}</h2>
<h3>{{count}}</h3>
<hr/>
<h3>{{$store.state.count}}</h3>
<div>
<button @click="$store.commit('add')">+</button>
<button @click="$store.commit('reduce')">-</button>
</div>
</div>
</template>
<script>
import store from '../store/store.js'
import {mapState} from 'vuex';
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vuex App'
}
},
computed:mapState({
count:state=>state.count //理解为传入state对象,修改state.count属性
}),
// computed:{
// count(){
// return this.$store.state.count;
// }
// },
store //声明
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
三. 通过mapState的数组来赋值
computed:mapState(["count"])
这个是最简单的写法,在实际项目开发当中也经常使用
完整代码为:
<template>
<div class="hello">
<h2>{{msg}}</h2>
<h3>{{count}}</h3>
<hr/>
<h3>{{$store.state.count}}</h3>
<div>
<button @click="$store.commit('add')">+</button>
<button @click="$store.commit('reduce')">-</button>
</div>
</div>
</template>
<script>
import store from '../store/store.js'
import {mapState} from 'vuex';
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vuex App'
}
},
computed:mapState(["count"]),
// computed:mapState({
// count:state=>state.count //理解为传入state对象,修改state.count属性
// }),
// computed:{
// count(){
// return this.$store.state.count;
// }
// },
store //声明
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
**
Mutation修改状态
**
他是同步事务.
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
前面我们已经用到过了
要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法:
提交载荷(Payload)
你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload):
现在store.js文件里给add方法加上一个参数n。
const mutations={
add(state,n){
state.count+=n;
},
reduce(state){
state.count-=1;
}
}
在Count.vue里修改按钮的commit( )方法传递的参数,我们传递10,意思就是每次加10.
<button @click="$store.commit('add',10)">+10</button>
<button @click="$store.commit('reduce')">-1</button>
模板获取Mutations方法
实际开发中我们也不喜欢看到$store.commit( )这样的方法出现,我们希望跟调用模板里的方法一样调用。
例如:@click=”reduce” 就和没引用vuex插件一样。
在helloworld.vue上进行如下更改
import { mapState,mapMutations } from 'vuex';
methods:mapMutations([
'add','reduce'
]),
<button @click="add(10)">+10</button>
<button @click="reduce">-1</button>
完整代码为:
<template>
<div class="hello">
<h2>{{msg}}</h2>
<h3>{{count}}</h3>
<hr/>
<h3>{{$store.state.count}}</h3>
<div>
<button @click="add(10)">+10</button>
<button @click="reduce">-1</button>
</div>
</div>
</template>
<script>
import store from '../store/store.js'
import { mapState,mapMutations } from 'vuex';
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vuex App'
}
},
computed:mapState(["count"]),
methods:mapMutations([
'add','reduce' //映射方法
]),
store //声明
// computed:mapState({
// count:state=>state.count //理解为传入state对象,修改state.count属性
// }),
// computed:{
// count(){
// return this.$store.state.count;
// }
// },
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
界面:
也可这样写:
<button @click="add10(10)">+10</button>
<button @click="reduce1">-1</button>
methods:{
...mapMutations({
add10: 'add' ,// 将this.add10() 映射为 this.$store.commit(<template>
<div class="hello">
<h2>{{msg}}</h2>
<h3>{{count}}</h3>
<hr/>
<h3>{{$store.state.count}}</h3>
<div>
<button @click="add10(10)">+10</button>
<button @click="reduce1">-1</button>
</div>
</div>
</template>
<script>
import store from '../store/store.js'
import { mapState,mapMutations } from 'vuex';
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vuex App'
}
},
methods:{
...mapMutations({
add10: 'add' ,// 将this.add10() 映射为 this.$store.commit('add')
reduce1:'reduce'//其实就是方法又命名了一下
})
},
computed:mapState(["count"]),
// methods:mapMutations([
// 'add','reduce' //映射方法
// ]),
store //声明
// computed:mapState({
// count:state=>state.count //理解为传入state对象,修改state.count属性
// }),
// computed:{
// count(){
// return this.$store.state.count;
// }
// },
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
)
reduce1:'reduce'//其实就是方法又命名了一下
})
},
完整代码:
<template>
<div class="hello">
<h2>{{msg}}</h2>
<h3>{{count}}</h3>
<hr/>
<h3>{{$store.state.count}}</h3>
<div>
<button @click="add10(10)">+10</button>
<button @click="reduce1">-1</button>
</div>
</div>
</template>
<script>
import store from '../store/store.js'
import { mapState,mapMutations } from 'vuex';
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vuex App'
}
},
methods:{
...mapMutations({
add10: 'add' ,// 将this.add10() 映射为 this.$store.commit('add')
reduce1:'reduce'//其实就是方法又命名了一下
})
},
computed:mapState(["count"]),
// methods:mapMutations([
// 'add','reduce' //映射方法
// ]),
store //声明
// computed:mapState({
// count:state=>state.count //理解为传入state对象,修改state.count属性
// }),
// computed:{
// count(){
// return this.$store.state.count;
// }
// },
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
getters计算过滤操作
getters从表面是获得的意思,可以把他看作在获取数据之前进行的一种再编辑,相当于对数据的一个过滤和加工。你可以把它看作store.js的计算属性。
getters基本用法:
比如我们现在要对store.js文件中的count进行一个计算属性的操作,就是在它输出前,给它加上100.我们首先要在store.js里用const声明我们的getters属性。
完整代码:
<template>
<div class="hello">
<h2>{{msg}}</h2>
<h3>{{count}}</h3>
<hr/>
<h3>{{$store.state.count}}</h3>
<div>
<button @click="add10(10)">+10</button>
<button @click="reduce1">-1</button>
</div>
</div>
</template>
<script>
import store from '../store/store.js'
import { mapState,mapMutations } from 'vuex';
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vuex App'
}
},
methods:{
...mapMutations({
add10: 'add' ,// 将this.add10() 映射为 this.$store.commit('add')
reduce1:'reduce'//其实就是方法又命名了一下
})
},
//computed:mapState(["count"]),
// methods:mapMutations([
// 'add','reduce' //映射方法
// ]),
computed:{
...mapState(["count"]),
count(){
return this.$store.getters.count; //使用了getter
}
},
store //声明
// computed:mapState({
// count:state=>state.count //理解为传入state对象,修改state.count属性
// }),
// computed:{
// count(){
// return this.$store.state.count;
// }
// },
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
用mapGetters简化模板写法
首先用import引入我们的mapGetters
import { mapState,mapMutations,mapGetters } from 'vuex';
在computed属性中加入mapGetters
...mapGetters(["count"])
完整代码:
<template>
<div class="hello">
<h2>{{msg}}</h2>
<h3>{{count}}</h3>
<hr/>
<h3>{{$store.state.count}}</h3>
<div>
<button @click="add">+10</button>
<button @click="reduce">-1</button>
</div>
</div>
</template>
<script>
import store from '../store/store.js'
import { mapState,mapMutations,mapGetters } from 'vuex';
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vuex App'
}
},
methods:{
// ...mapMutations({
// add10: 'add' ,// 将this.add10() 映射为 this.$store.commit('add')
// reduce1:'reduce'//其实就是方法又命名了一下
// })
},
//computed:mapState(["count"]),
methods:mapMutations([
'add','reduce' //映射方法
]),
computed:mapState({
...mapGetters(["count"]),
}),
store //声明
// computed:mapState({
// count:state=>state.count //理解为传入state对象,修改state.count属性
// }),
// computed:{
// count(){
// return this.$store.state.count;
// }
// },
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
module模块组
随着项目的复杂性增加,我们共享的状态越来越多,这时候我们就需要把我们状态的各种操作进行一个分组,分组后再进行按组编写。那今天我们就学习一下module:状态管理器的模块组操作。
const moduleA={
state
}
export default new Vuex.Store({
modules:{a:moduleA}
})
<h3>{{$store.state.a.count}}</h3>
或
computed:{
count(){
return this.$store.state.a.count;
}
},
store.js完整代码:
//引入我们的vue和vuex。
import Vue from 'vue'
import Vuex from 'vuex'
//使用我们vuex,引入之后用Vue.use进行引用
Vue.use(Vuex);
const state = {
count:1
}
const mutations={
add(state,n){
state.count+=n;
},
reduce(state){
state.count-=1;
}
}
const actions= {
addAction(context){
setTimeout(() => {
context.commit('add',10)
},3000)
},
reduceAction({commit}){
commit('reduce')
}
}
const getters = {
count:function(state){
return state.count +=100;
}
}
const moduleA = {
state,mutations,actions,<template>
<div class="hello">
<h2>{{msg}}</h2>
<h3>{{count}}</h3>
<hr/>
<!-- <h3>{{$store.state.count}}</h3> -->
<div>
<button @click="addAction(10)">+10</button>
<button @click="reduceAction">-1</button>
</div>
</div>
</template>
<script>
import store from '../store/store.js'
import { mapState,mapMutations,mapGetters,mapActions} from 'vuex';
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vuex App'
}
},
methods:{
...mapMutations([
'add','reduce'
]),
...mapActions([
'addAction','reduceAction'
])
},
// computed:mapState(["count"]),
// methods:mapMutations([
// 'add','reduce' //映射方法
// ]),
computed:mapState({
...mapGetters(["count"]),
}),
store //声明
// computed:mapState({
// count:state=>state.count //理解为传入state对象,修改state.count属性
// }),
// computed:{
// count(){
// return this.$store.state.count;
// }
// },
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
}
export default new Vuex.Store({
modules:{a:moduleA}
});
helloworld.vue完整代码:
<template>
<div class="hello">
<h2>{{msg}}</h2>
<h3>{{count}}</h3>
<hr/>
<!-- <h3>{{$store.state.count}}</h3> -->
<div>
<button @click="addAction(10)">+10</button>
<button @click="reduceAction">-1</button>
</div>
</div>
</template>
<script>
import store from '../store/store.js'
import { mapState,mapMutations,mapGetters,mapActions} from 'vuex';
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vuex App'
}
},
methods:{
...mapMutations([
'add','reduce'
]),
...mapActions([
'addAction','reduceAction'
])
},
// computed:mapState(["count"]),
// methods:mapMutations([
// 'add','reduce' //映射方法
// ]),
computed:mapState({
...mapGetters(["count"]),
}),
store //声明
// computed:mapState({
// count:state=>state.count //理解为传入state对象,修改state.count属性
// }),
// computed:{
// count(){
// return this.$store.state.count;
// }
// },
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
本文主要参考了开头提示的技术博客,也让我对vuex有了比较深刻的认识,感谢各位技术大佬