关于vuex
vuex时vue工程的状态管理工具;
主要用来处理vue各个组件之间值传递的问题;
适用于比较复杂的工程;
主要概念:
1)this.$store : 我们可以通过 this.$store 在vue的组件中获取
vuex的实例。
2)State : vuex中的数据源,我们可以通过 this.$store.state 获取
我们在vuex中声明的全局变量的值。
3)Getter: 相当于vue中的computed , 及 计算属性, 可以用于监听、
计算 state中的值的变化
4)Mutation: vuex中去操作数据的方法 (只能同步执行)
5)Action: 用来操作 Mutation 的动作 , 他不能直接去操作数据源,
但可以把mutation变为异步的
6)Module: 模块化,当你的应用足够大的时候,你可以把你的vuex分成多个
子模块
1.安装
cd 工程目录;
输入命令:
npm install vuex --save
2.使用
1)使用vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
2)new一个Vuex实例
需要配置几个属性:state、getters、 mutations、actions
const store = new Vuex.Store({
state: {},
getters: {},
mutations:{},
actions:{}
})
也可以将这几个属性分成多个js文件来单独配置,然后统一在index.js中引入之后在新建Vuex实例时使用;
3)在main.js中引入
import store from './store/index'
new Vue(
el:'#app',
store,
...
)
3.具体实例
1)在工程的src目录下新建一个store目录;
在store目录下新建一个index.js;
import Vue from 'vue'
import Vuex from 'vuex'
//使用vuex
Vue.use(Vuex);
//新建vuex实例
const store=new Vuex.Store({
state:{
message:'Vuex示例',
t1:'产品表一号',
t2:'产品表二号',
products: [
{name: '鼠标', price: 20},
{name: '键盘', price: 40},
{name: '耳机', price: 60},
{name: '显示屏', price: 80}
]
},
getters:{},
mutations:{},
actions:{}
});
//导出vuex实例
export default store;
2)在main.js中引用
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/index'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store, //注册vuex
components: { App },
template: '<App/>'
})
3)在测试组件HelloWorld.vue中使用
HelloWorld组件有两个子组件part1和part2;
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<div>-----------------------------------</div>
<part1/>
<div>-----------------------------------</div>
<part2/>
</div>
</template>
<script>
import part1 from './part_01'
import part2 from './part_02'
export default {
name: 'HelloWorld',
data () {
return {
msg:this.$store.state.message
}
},
components:{
part1,
part2
}
}
</script>
4)子组件
part1
<template>
<div class="part1">
<h1>{{ title01 }}</h1>
<ul>
<li v-for="item in list01">{{item.name}}:{{item.price}} </li>
</ul>
</div>
</template>
<script>
export default {
name: 'part1',
data () {
return {
title01:this.$store.state.t1,
list01:this.$store.state.products
}
}
}
</script>
part2
<template>
<div class="part1">
<h1>{{ title02 }}</h1>
<ul>
<li v-for="item in list02">{{item.name}}:{{item.price}} </li>
</ul>
</div>
</template>
<script>
export default {
name: 'part2',
data () {
return {
title02:this.$store.state.t2,
list02:this.$store.state.products
}
}
}
</script>
结果:
4.state
state的作用相当于存放整个工程的全局变量;
子组件可利用 this.$store.state.xxx 可获取state里的变量的值;
5.getters
getter可以用来获取state里面变量的值;
也可以将获取的数据计算后再返回出去;
但是不会改变state里的值;
使用 this.$store.getter.xxx 来获取getters里面的方法的返回值;
getters里的方法有一个固定参数 state和可选参数payload
state相当于存放全局变量的state ,而payload时自定义的方法中可传入参数
1)再index.js里的getters中添加一个半价方法
getters:{
//半价
halfPrice: (state) => {
let saleProducts = state.products.map( product => {
return {
name: product.name,
price: product.price/2
}
})
return saleProducts;
}
},
2)将part1中的数据获取方式从直接由state获取改为getter获取
data () {
return {
title01:this.$store.state.t1,
list01:this.$store.getters.halfPrice
}
}
结果:
可以看出用了getter获取的数据实现了半价;使用state获取的数据还是没变化说明getter不会改变state里的值;
6.mutations
mutations 用来更改state里面的数据;
有一个参数 state和可选的自定义参数payload;
需要用 this.$store.commit(xxx) 来提交定义的方法;
提交方法后将改变state里的值,除非网页刷新;
1)再index里添加一个mutations方法
mutations:{
minusPrice (state, payload ) {
let newPrice = state.products.forEach( product => {
product.price -= payload
})
}
},
2)修改组件part1
再methods中添加一个用来降价的方法;
方法中用 this.$store.commit(xxx)来提交mutation;
再模板中添加一个按钮来绑定该方法;
关键代码:
<button @click="lowerPrice">点我降价</button>
data () {
return {
title01:this.$store.state.t1,
list01:this.$store.state.products
}
},
methods:{
lowerPrice(){
//提交mutations中定义的方法
this.$store.commit('minusPrice',1);
}
}
结果:点击降价按钮后
可以看到,组件2的值也被修改了;说明mutation被提交后会改变state里的值
7.actions
actions的作用时提交 mutation;
actions可包含异步操作;
有两个参数 context 和自定义的payload;
context参数 相当于this.$store,可调用commit方法来提交mutation;
可用 this.$store.dispatch(xxx,xx)来提交action;
1)给index.js添加一个action
actions:{
munusPriceAction( context, payload ) {
setTimeout( () => {
context.commit( 'minusPrice', payload ); //context提交
}, 2000)
}
}
2)修改组件part2
添加一个减价方法;
添加一个button来绑定该方法;
<button @click="lowerAction">两秒过后降价</button>
methods:{
lowerAction(){
this.$store.dispatch('minusAction',2);
}
}
运行结果: