在vuex中提交 mutation 是更改状态的唯一方法,并且这个过程是同步的,异步逻辑都应该封装到 action 里面。
官网上对于传参,“提交载荷”
案例是基于uni-app的,标签不要大惊小怪
在main.js 挂载 store
mutation 传参
v 1.0
// mutation
mutations: {
add(state,n){
state.count += n;
}
}
// .vue
<view @click="add">点击+</view>
<view>{{count}}</view>
import {mapState} from 'vuex'
computed:mapState(["count"]),
methods:{
add(){
this.$store.commit('add',5)
}
}
v 2.0
// mutation
mutations: {
sub(state,payload){
state.count -= payload.amount
}
}
// .vue
<view>{{count}}</view>
<view @click="sub">点击-</view>
import {mapState} from 'vuex'
computed:mapState(["count"]),
methods:{
sub(){
this.$store.commit({
type:'sub',
amount:2,
})
}
}
action传参
v 1.0
// mutation
mutations: {
addaction(state,n){
state.count += n
}
}
// action
actions: {
addaction(context,arg){
context.commit('addaction',arg)
}
}
//.vue
<view @click="adda">addaction</view>
<view>{{count}}</view>
import {mapState} from 'vuex'
computed:mapState(["count"]),
methods: {
adda(){
// 触发
this.$store.dispatch('addaction',3)
}
}
v 2.0
// mutation
mutations: {
subaction(state,payload){
state.count -= payload.amount
}
}
// action
actions: {
subaction(context,payload){
context.commit('subaction',payload);
}
}
//.vue
<view @click="suba">subaction</view>
<view>{{count}}</view>
import {mapState} from 'vuex'
computed:mapState(["count"]),
methods: {
suba(){
this.$store.dispatch({
type:'subaction',
amount:2
})
}
}
action异步操作
a) 返回promise
// mutation
mutations: {
muiltiplication(state,payload){
state.count *= payload.amount;
}
}
// action
actions: {
asyncMul(context,playload){
return new Promise(((resolve,reject)=>{
setTimeout(()=>{
context.commit('muiltiplication',playload);
resolve('async over');
},2000)
}))
}
}
//.vue
<view @click="multa">mult</view>
<view>{{count}}</view>
import {mapState} from 'vuex'
computed:mapState(["count"]),
methods: {
multa(){
this.$store.dispatch({
type:'asyncMul',
amount:5
}).then((result)=>console.log(result)) //async over
}
}
b) 两个action,第二个要依赖第一个
// mutation
mutations: {
muiltiplication(state,payload){
state.count *= payload.amount;
}
}
// action
actions: {
asyncMul(context,payload){
return new Promise(((resolve,reject)=>{
setTimeout(()=>{
context.commit('muiltiplication',payload);
resolve('async over');
},2000)
}))
},
action2({dispatch,commit},payload){
return dispatch('asyncMul',payload).then(()=>{
commit('muiltiplication',payload);
return "async over2"
})
}
}
//.vue
<view @click="multa2">mult</view>
<view>{{count}}</view>
import {mapState} from 'vuex'
computed:mapState(["count"]),
methods: {
multa2(){
this.$store.dispatch({
type:'action2',
amount:5
}).then((result)=>{
console.log(result) // x *5*5
})
}
}
使用async , await函数
async action2({dispatch,commit},payload){
await dispatch('asyncMul',payload)
commit('muiltiplication',payload)
} // 其他不变
c) api
利用Vuex完成类似于上面数据展示,
api.js
export const urlApi = "http://www.xxxxx:3333";
export function getBookByCateAndPage(categoryId,page,pagesize){ //page 当前页 pagesize 页面容量
return urlApi + "/api/book/bookBy?cid="+categoryId+"&page="+page+"&pagesize="+pagesize;
}
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import {
urlApi,
getBookByCateAndPage
} from '../api/api.js'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
booklist:[]
},
getters:{
},
mutations: {
getbooklist(state,list){
state.booklist = list;
}
},
actions: {
getbooklist(context,arg) {
var booklist;
uni.request({ //mongdb
url: getBookByCateAndPage("5d3d0506e1d8c632cc000862",arg,6),
success: function(res) {
booklist = res.data.item;
console.log(booklist)
context.commit('getbooklist',booklist);
}
})
},
}
})
export default store
index.vue
<view class="guess-section">
<view v-for="(item, index) in booklist" :key="index" class="guess-item" @click="navToDetailPage(item)">
<view class="image-wrapper">
<image :src="item.bookImg" mode="aspectFill"></image>
</view>
<text class="title clamp">{{item.bookName}}</text>
<text class="price">¥{{item.bookPrice}}</text>
</view>
</view>
<view style="display: flex;justify-content: center;align-items: center;margin-bottom: 30upx;">
<button type="primary" size="mini" @click="sub">上一页</button>
<text>{{currentPage}}</text>
<button type="default" size="mini" @click="add">下一页</button>
</view>
import {mapState} from 'vuex'
data() {
return {
isActive: false, //搜索栏动态效果
titleNViewBackground: '',
swiperCurrent: 0,
swiperLength: 0,
carouselList: [],
goodsList: [],
currentPage:1,
};
},
created() {
this.$store.dispatch('getbooklist',1); //初始数据
}
computed:{...mapState(['booklist'])},
methods: {
sub(){
if(this.currentPage < 2){
this.currentPage = 1;
}else{
this.currentPage--
};// 优化 按键太快可能反应迟钝
this.$store.dispatch('getbooklist',this.currentPage)
},
add(){
if(this.currentPage > 9){
this.currentPage = 10;
}else{
this.currentPage++;
}
this.$store.dispatch('getbooklist',this.currentPage)
}
}