vue.js中管理数据状态的库,集中数据存储,供所有组件访问;
- 根组件 = > props =>子组件 => event事件 = > 根组件;
- vuex(getter/mutation);
- 借鉴了Flux、Redux、the Elm Architecture ;
npm淘宝镜像安装,提升速度;
npm i vuex --save / yarn add vuex
简单的使用:
- state 驱动应用的数据源
- view 声明方式将state映射到视图
- actions 响应在view上的用户输入导致的状态变化
state
一般不用store.state._name此方法调用修改原始state数据,不利于检测和维护;使用getter获取数据,mutations/actions修改数据;
// store/store.js导出
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
// 严格模式下,事件触发用mutations
strict:true,
state:{
products:[
{name:'马云',price:'200'},
{name:'马化腾',price:'180'}
]
}
})
// main.js引入
import {store} from './store/store.js'
new Vue({
store:store,
el:'#app',
render:h=>h(app)
})
<!-- test1.vue -->
<template>
<ul>
<li v-for="it in products">{{it}}</li>
</ul>
</template>
<script>
export default{
computed:{
products(){
return this.$store.state.products;
},
}
}
<script>
<style scoped></style>
<!-- test2.vue -->
<template>
<ul>
<li v-for="it in sale">{{it}}</li>
</ul>
</template>
<script>
export default{
computed:{
products(){
return this.$store.state.products;
},
sale(){
var saleProducts = this.$store.state.products.map(
it =>{
return {
name : "**" + it.name + "**",
price: it.price / 2
}
}
);
return saleProducts;
}
}
}
<script>
<style scoped></style>
getters
如果多组件使用saleProducts
数据,可以抽离放入store.js
;
组件引用 => computed 动态获取;
通过store.getters._name调用;
state数据更新触发getters的更新问题?貌似官方已经解决;删除state下“数组/对象”属性的时候,组件里需要watch
数据的变化,以重新DOM渲染;
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state:{
products:[
{name:'马云',price:'200'},
{name:'马化腾',price:'180'}
]
},
getters:{
saleProducts:(state)=>{
var saleProducts = state.products.map(
it =>{
return {
name : "**"+it.name+"**",
price:it.price/2
}
}
);
return saleProducts;
}
}
})
<!-- test3.vue -->
<template>
<ul>
<li v-for="it in sale">{{it}}</li>
</ul>
</template>
<script>
export default{
computed:{
products(){
return this.$store.state.products;
},
sale(){
return this.$store.getters.saleProducts;
}
}
}
<script>
<style scoped></style>
mutation
存储数据用state类似date;获取数据用getter类似computed;触发事件改变数据用mutation类似methods,可以追查事件;action => 分发异步触发mutation;
通过store.commit("_name",{传参})调用;
Chrome浏览器插件vue devtools安装
第一位参数固定为state
,其他为传入参数,顺传;
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state:{
products:[
{name:'马云',price:'200'},
{name:'马化腾',price:'180'}
]
},
getters:{
saleProducts:(state)=>{
var saleProducts = state.products.map(
it =>{
return {
name : "**"+it.name+"**",
price:it.price/2
}
}
);
return saleProducts;
}
},
mutations:{
reducePrice:(state)=>{
state.products.forEach(it =>{
it.price -=1;
})
}
}
})
<!-- test4.vue -->
<template>
<ul>
<li v-for="it in saleProducts">{{it}}</li>
</ul>
<button type="button" @click="reduce">降价</button>
</template>
<script>
export default{
computed:{
products(){
return this.$store.state.products;
},
saleProducts(){
return this.$store.getters.saleProducts;
}
},
methods:{
reduce(){
// this.$store.state.products.forEach(it =>{
// it.price -= 1;
// })
this.$store.commit('reducePrice');
}
}
}
<script>
<style scoped></style>
actions
类似于mutation,不同:
actions提交的时mutations,而不是直接变更状态;
可以包含任意异步操作;
dispath(fn,payload)分发方法触发actions中调用mutations函数;
mutations中直接setTimeout()实现异步不好调试,可以用actions实现异步调用mutations中函数;
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state:{
products:[
{name:'马云',price:'200'},
{name:'马化腾',price:'180'}
]
},
getters:{
saleProducts:(state)=>{
var saleProducts = state.products.map(
it =>{
return {
name : "**"+it.name+"**",
price:it.price/2
}
}
);
return saleProducts;
}
},
actions:{
reduceLayout:(context,payload)=>{
setTimeout(function(){
context.commit("reducePrice",payload)
},3000)
}
},
mutations:{
reducePrice:(state,payload) => {
state.products.forEach(it => {
it.price -= payload;
})
}
}
})
<!-- test5.vue -->
<template>
<ul>
<li v-for="it in saleProducts">{{it}}</li>
</ul>
<button type="button" @click="reduce(4)">降价</button>
</template>
<script>
export default{
computed:{
products(){
return this.$store.state.products;
},
saleProducts(){
return this.$store.getters.saleProducts;
}
},
methods:{
reduce(amount){
this.$store.dispatch('reduceLayout',amount);
}
}
}
<script>
<style scoped></style>
mapState/mapGetters/mapMutations/mapActions 辅助函数
举个栗子:ES6中...mapGetters(['saleProducts'])
和...mapActions(['reduceLayout'])
批量调用函数
mapState:
//test.vue
import {mapState} from "vuex";
data(){
return {
localCount:50;
}
},
computed:mapState({
//箭头函数中this指向store中的state数据
products:state => state.products,
//为了this获取当前局部的data/compputed数据,使用常规函数
salaProducts(state){
return state.products + this.localCount;
}
})
mapGetters、mapActions:
<!-- test5.vue -->
<template>
<ul>
<li v-for="it in saleProducts">{{it}}</li>
</ul>
<button type="button" @click="reduce(4)">降价</button>
</template>
<script>
//先注入依赖
import {mapGetters} from 'vuex'
import {mapActions} from 'vuex'
export default{
computed:{
// products(){
// return this.$store.state.products;
// },
// saleProducts(){
// return this.$store.getters.saleProducts;
// },
...mapGetters(["products","saleProducts"])
},
methods:{
reduce(amount){
//this.$store.dispatch('reduceLayout',amount);
var amount = 0.5;//五折
this.reduceLayout(amount);
},
...mapActions(["reduceLayout"])
}
}
<script>
<style scoped></style>
…mapGetters([“dataName1”,“dataName2”]),类似
computed
数据引用;
…mapMutatains([“methodName1”,“methodsName2”]),类似methods
方法引用,并传参this.nethodName1(argu)
;…mapActions同理;