Vuex的基本使用

一、安装

NPM

npm install vuex --save

Yarn

yarn add vuex

在main.js引入使用

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

创建store文件夹,里面创建一个js文件 store/index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)  // 必须显式地通过 Vue.use() 来安装 Vuex

export default new Vuex.Store({
  state: {
    addCount: 0, // 显示的数值
    subCount: 1
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

二、开始使用(显示)---state

在vue中state有三种用法(显示)
第一种

<div>增加的数量1:{{$store.state.addCount}}</div>

第二种

<div>减少的数量:{{countTest}}</div>
<script>
export default {
  data() {
    return {
      countTest: null
    }
  },
  mounted() {
    this.countTest = this.$store.state.subCount;  
  },
}
</script>

第三种

<div>增加的数量2:{{addCount}}</div>
<script>
import {mapState} from 'vuex'
export default {
  computed: {
    ...mapState(['addCount'])
  },
}
</script>

三、Mutation

Mutation用于变更Store中的数据
① 只能通过mutation变更Store数据,不可以直接操作Store中的数据。
② 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。

  mutations: {
    /*
    add 函数接收两个参数
    state: store里面的state对象(和mutition平级的state)
    data: 外界传入的值,可以随意命名,a,b,c都可以
    */ 
    add(state,data) {
      // 每点击一次,在原来的基础上加 data数值
      state.addCount += data;
    }
  },

触发mutations的第一种方式

  methods: {
    handleAdd() {
      // commit 的作用, 就是调用某个 mutation 函数
      this.$store.commit('add',2)
    }
  },

触发mutations的第二种方式

export default new Vuex.Store({
  state: {
    addCount: 0, // 显示的数值
    subCount: 1,
    aTest: '我是测试1'
  },
  mutations: {
    /*
    add 函数接收两个参数
    state: store里面的state对象(和mutition平级的state)
    data: 外界传入的值,可以随意命名,a,b,c都可以
    */ 
    add(state,data) {
      // 每点击一次,在原来的基础上加 data数值
      state.addCount += data;
    },
    sub(state,step) {
      state.aTest = step;
    }
  },
})
<script>
// 从vuex 中 按需导入 mapMutations 函数
import {mapState, mapMutations} from 'vuex'
export default {
  computed: {
    ...mapState(['addCount'])
  },
// 通过导入的mapMutations函数,将需要的mutations函数,映射为当前组件的methods方法
  methods: {
  // 讲指定的mutations 函数,映射为当前组件的methods 函数
    ...mapMutations(['sub']),
    handleAdd() {
      this.$store.commit('add',2)
    },
    handleTihuan() {
      this.sub('嘿嘿嘿!!!')
    }
  },
}
</script>

四、Actions

Actions 用于处理异步任务。
如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据。
触发actions的第一种方式:

export default new Vuex.Store({
  state: {
    addCount: 0, // 显示的数值
  },
  mutations: {
    add(state) {
      state.addCount += 1;
    },
  },
  actions: {
    asyncAdd(context) {
      setTimeout(()=>{
        context.commit('add')
      },1000)
    }
  },
})
-----------------
  methods: {
    handleAdd() {
      this.$store.dispatch('asyncAdd')   // store 里面的方法名是哪个就在dispatch里面写哪个方法名
    },
  },

触发actions异步任务时携带参数:

  actions: {
    asyncAdd(context,step) {
      setTimeout(()=>{
        context.commit('add',step)
      },1000)
    }
  }
-----
this.$store.dispatch('asyncAdd',2)

触发actions的第二种方式:

  actions: {
    asyncSub(context,step) {
      setTimeout(()=>{
        context.commit('sub',step)
      },1000)
    } 
  },

------
import {mapState, mapMutations, mapActions} from 'vuex'
  methods: {
    ...mapMutations(['sub']),
    ...mapActions(['asyncSub']),
    handleSub() {
      this.asyncSub(1);
    },
  },
------
// 或者直接在DOM元素中使用
<div>减少的数量:{{$store.state.subCount}}</div>
    <!-- <el-button type="warning" @click="handleSub">减少</el-button> -->
    <el-button type="warning" @click="asyncSub(2)">减少</el-button>

五、Getters

Getters用于对Store中的数据进行加工处理形成新的数据
① Getters 可以对Store 中已有的数据加工处理之后形成新的数据,类似于Vue的计算属性。
② Store 中数据发生变化,Getters 的数据也会跟着变化。
使用getters的第一种方式:

  getters: {
 // 这里的state 是store 里面state
    showNumber: state => {
      return '当前最新的数据是【'+ state.testCount +'】'
    }
  },
-----------
  // this.$store.getters.名称
 this.$store.getters.showNumber

使用getters的第二种方式:

import {mapState, mapMutations, mapActions, mapGetters} from 'vuex'
--------------
 computed: {
    ...mapGetters(['showNumber'])
  },
-----------
<div>{{showNumber}}</div>

六、modules(我这里后面更新的是vuex@4以上的)

1、先在store文件夹创建一个modules文件夹,里面新建你要见名知意的文件,我这里就使用home.js

modules.png

2.store文件夹里面的index.js文件

import {createStore} from 'vuex'
import home from './modules/home'
const store = createStore({
  state() {
    return {
      counter: 100
    }
  },
  mutations: {
    increment(state) {
      state.counter++;
    },
    decrement(state) {
      state.counter--;
    }
  },
  actions: {},
  getters: {},
  modules: {
    home
  }
})

export default store

3.modules文件夹里面的home.js

export const homeModule = {
 /* 官方定义:默认情况下,模块内部的 action 和 mutation 仍然是注册在全局命名空间的——这样使得多个模块能够对
  同一个 action 或 mutation 作出响应。
  Getter 同样也默认注册在全局命名空间,但是目前这并非出于功能上的目的(仅仅是维持现状来避免非兼容性变更)。
  必须注意,不要在不同的、无命名空间的模块中定义两个相同的 getter 从而导致错误。

  如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。
  当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调 整命名
  namespaced: true,  // 开启命名空间 */
  state(){
    return {
      homeCounter: 100
    }
  },

  mutations: {
    increment(state) {
      state.homeCounter++;
    }
  },
  actions: {
    incrementAction(context) {
      context.commit('increment')
    }
  },
  getters: {
    doubleHomeCounter(state) {
      return state.homeCounter*2;
    }
  }
}

export default homeModule

4、在页面用使用
基本的写法:(普通写法)

<template>
  <div class="container">
    <div>这是测试modules的组件</div>
    module的值:<h3>{{$store.state.home.homeCounter}}</h3>
    module的值:<h3>{{$store.getters["home/doubleHomeCounter"]}}</h3>
    modules的按钮:<button @click="increment">+1</button>
    modules的按钮action:<button @click="incrementAction">+1</button>
  </div>
</template>
<script>
export default {
  methods: {
    increment() {
      this.$store.commit('home/increment')
    },
    incrementAction() {
      this.$store.dispatch('home/incrementAction')
    }
  },
}
</script>

辅助函数的写法
第一种写法:(辅助函数写法)

<template>
  <div class="container">
    <div>这是测试module辅助函数的组件</div>
    module的值:<h3>{{homeCounter}}</h3>
    module的值:<h3>{{$store.getters["home/doubleHomeCounter"]}}</h3>
    modules的按钮:<button @click="increment">+1</button>
    modules的按钮action:<button @click="incrementAction">+1</button>
  </div>
</template>

<script>
import {mapState, mapMutations, mapGetters,mapActions} from 'vuex'
export default {
  name: '',
  components: {

  },
  data() {
    return {

    }
  },
  computed: {
    // 写法一
    ...mapState({
      homeCounter: state => state.home.homeCounter
    }),
     ...mapGetters({
      doubleHomeCounter: "home/doubleHomeCounter"
    })
  },
  mounted() {
    
  },
  methods: {
    // 写法一
    ...mapMutations({
      increment: "home/increment"
    }),
    ...mapActions({
      incrementAction: "home/incrementAction"
    })
  },
}
</script>

第二种写法:(辅助函数写法)

<template>
  <div class="container">
    <div>这是测试module辅助函数的组件</div>
    module的值:<h3>{{homeCounter}}</h3>
    module的值:<h3>{{$store.getters["home/doubleHomeCounter"]}}</h3>
    modules的按钮:<button @click="increment">+1</button>
    modules的按钮action:<button @click="incrementAction">+1</button>
  </div>
</template>

<script>
import {mapState, mapMutations, mapGetters,mapActions} from 'vuex'
export default {
  name: '',
  computed: {
    // 写法二
    ...mapState('home',['homeCounter']),
    ...mapGetters('home', ['doubleHomeCounter'])
  },
  methods: {
    // 写法二
    ...mapMutations('home', ['increment']),
    ...mapActions('home', ['incrementAction']),
  },
}
</script>

第三种写法:(辅助函数写法)

<template>
  <div class="container">
    <div>这是测试module辅助函数的组件</div>
    module的值:<h3>{{homeCounter}}</h3>
    module的值:<h3>{{$store.getters["home/doubleHomeCounter"]}}</h3>
    modules的按钮:<button @click="increment">+1</button>
    modules的按钮action:<button @click="incrementAction">+1</button>
  </div>
</template>

<script>
// createNamespacedHelpers 创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数:
import { createNamespacedHelpers } from 'vuex'
// 解构 createNamespacedHelpers("home") 里面的home 是你文件的名字,我这里是创建了home.js
const {mapState, mapMutations, mapGetters,mapActions} = createNamespacedHelpers("home")
export default {
  name: '',
  computed: {
    // 写法三
    ...mapState(['homeCounter']),
    ...mapGetters(['doubleHomeCounter'])
  },
  mounted() {
    
  },
  methods: {
    // 写法三
    ...mapMutations(['increment']),
    ...mapActions(['incrementAction']),
  },
}
</script>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容

  • 首先我们知道组件之间共享数据的方式有以下几种:父向子传值:v-bind属性绑定子向父传值:v-on 事件绑定兄弟组...
    肖青荣阅读 471评论 0 4
  • Vuex中的核心特性 A.State B.Mutation Mutation用于修改变更$store中的数据使用方...
    如光凌清尘阅读 167评论 0 0
  • 1. Vuex 概述 1.1 组件之间共享数据的方式: 父向子传值:v-bind 属性绑定 子向父传值:v-on ...
    微笑曲线_8eee阅读 289评论 1 1
  • 1.Vuex概述 Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享 使用Vuex...
    王玉伟的伟阅读 333评论 0 0
  • 原文:https://laylawang17.github.io/2020/03/11/Vuex%E7%9A%84...
    FoxLayla阅读 721评论 0 0