手把手教你使用Vuex,有眼睛就能会的教程

94 阅读3分钟

虽然在创建项目的时候我们可以用vue-cli来自动生成Vuex,但是我们不能忘记一些基础知识点,毕竟万丈高楼平地起嘛,

在你想了解一个东西的时候,首先去看官网。官网对于他的介绍这么说的

image.png

通俗易懂的解释一遍就是说我们在多个组件共享一条数据的时候,单向数据流的结构性很容易被破坏,Vuex他就好比一个仓库,我们把一些共享的数据放在这个仓库里面,直接从仓库中去取值,不用在各组件之间传来传去。

我们首先从安装开始介绍

第一步:安装

    1.1 npm install vuex --save
    
    1.2 创建一个单独的 Store 文件价 在创建一个 index.js文件
    
    1.3 在index.js中创建vuex的实列对象
    
    1.4 导出该对象
    
    1.5main.js中引入该对象并且挂在到Vue.prototype的原型上
    
    1.6 将引入的 Store 放在 vue 的实例上 
    

还不会没关系,咱们还要图片教学 把馒头掰碎喂到你嘴巴去

image.png

image.png

image.png

image.png

State的使用: (State:驱动应用的数据源,可以理解为他是一个存储数据的一个空间集合,需要存放的数据都放在这里)

你可以直接使用$store.state.仓库中定义的数据名称拿到该属性值

Store 文件下的 index.js

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

Vue.use(Vuex);

const store = new Vuex.Store({
   state:{
    // 定义一个 name
    name:'孙悟空',
    // 定义一个 number
    number:13580
   }
    
})

export default store;

拿到值store中state的值

 <template>
  <div>
    <p>我的名字是:{{$store.state.name}}</p>
    <p>金箍棒重量:{{$store.state.number}}</p>
  </div>
</template>

运行结果:

image.png

mutations的使用: (mutations用来修改数据,但是他修改的是同步数据,异步数据的话不能直接在此操作)

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

Vue.use(Vuex);

const store = new Vuex.Store({
   state:{
    // 定义一个 name
    name:'孙悟空',
    // 定义一个 number
    number:13580
   },
   mutations:{
    // 定义一个修改数据的方法
    changeNumber(state,payload){
        state.number += payload
    }
    // 不传递载荷的情况下,第一个参数为必传参数(state)
    changeNum(state){
        state.number -= 1000
    }
   }
})

export default store;

修改App.vue

<template>
  <div>
    <p>我的名字是:{{$store.state.name}}</p>
    <p>金箍棒重量:{{$store.state.number}}斤</p>
    <button @click="Changebig(10000)">大大大</button>
    <button @click="ChangeSmall">小小小</button>
  </div>
</template>

<script>
export default {
  name: 'DemoApp',

  data() {
    return {
      
    };
  },

  created(){
  },
  
  mounted() {
  },

  methods: {
   ChangeSmall(){
      this.$store.commit('changeNum')
    },
    // 修改state中的值我们需要用store中的commit方法将修改的内容提交给mutation不能直接修改 commit 后面接连个参数('函数名',载荷)
    Changebig(number){
      this.$store.commit('changeNumber',number)
    }
  },
};
</script>

<style lang="scss" scoped>

</style>

这里说一条重要原则:Mutations里面的函数必须是同步操作,不能包含异步操作!

actions:所有的异步操作都在这里执行完成之后在由 commit 提交到 mutation

const store = new Vuex.Store({
   state:{
    // 定义一个 name
    name:'孙悟空',
    // 定义一个 number
    number:13580
   },
   mutations:{
    // 定义一个修改数据的方法,接收两个参数 (state,载荷)
    changeNumber(state,payload){
        state.number += payload
    },
    // 不传递载荷的情况下
    changeNum(state){
        state.number -= 1000
    }
   },
   actions:{
    // 定义一个修改数据的异步操作需要传递两个参数(commit,payload)
    setNumber(context,payload){
        // 异步的操作首先由 dispatch 进行操作 然后通过 mutation 修改 State 中的数据
        // 关于参数的定义 可以参考 mutations
        setTimeout(()=>{
            context.commit('changeNumber',payload)
        },2000)
    }
   }
})

App.vue 修改数据

<template>
  <div>
    <p>我的名字是:{{$store.state.name}}</p>
    <p>金箍棒重量:{{$store.state.number}}斤</p>
    <button @click="TimeOver">修改值</button>
    <button @click="Changebig(10000)">大大大</button>
    <button @click="ChangeSmall">小小小</button>
  </div>
</template>

<script>
export default {
  name: 'DemoApp',

  data() {
    return {
    };
  },

  created(){
  },
  mounted() {
  },

  methods: {
    ChangeSmall(){
      this.$store.commit('changeNum')
    },
    // number就是传递过去的载荷 通过commit来进行修改
    Changebig(number){
      this.$store.commit('changeNumber',number)
    },
    // 点击按钮触发 异步修改事件 'setNumber' 首先需要调用 store.dispatch 方法
    TimeOver(){
      this.$store.dispatch('setNumber', 10000)
    }
  },
};
</script>

<style lang="scss" scoped>

</style>

Getters:类似与计算属性(computed)它带有缓存,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

import Vue from 'vue'
import Vuex from 'vuex'
// import Cart from './modules/Cart.js'
// import details from './modules/details'
Vue.use(Vuex);

const store = new Vuex.Store({
   state:{
     // 定义一个 name
     name:'孙悟空',
     // 定义一个 number
     number:13580,
+    todoList:[{id:1,done:true},{id:2,done:true},{id:3,done:false},{id:4,done:false}]
   },
   mutations:{
    // 定义一个修改数据的方法,接收两个参数 (state,载荷)
    changeNumber(state,payload){
        state.number += payload
    },
    // 不传递载荷的情况下
    changeNum(state){
        state.number -= 1000
    }
   },
   actions:{
    // 定义一个修改数据的异步操作需要传递两个参数(commit,payload)
    setNumber(context,payload){
        setTimeout(()=>{
            // 异步的操作首先由 dispatch 进行操作 然后通过 mutation 修改 State 中的数据
            // 关于参数的定义 可以参考 mutations
            context.commit('changeNumber',payload)
        },2000)
    }
   },
+  getters:{
     doneTodos:state=>{
        // 直接筛选出 State.todoList里面 done属性为true的值
        return state.todoList.filter(todo=>todo.done === true)
    }
   },
})

export default store;

获取属性值的方法

    this.$store.getters.方法名称

Getters的作用就好比在特定的页面你需要用到 state 中的数据,但是 state 在多个页面中有用到,若你直接修改 state 则多个页面中的 值都会改变,这个时候你将 getters 函数的形式返回出来,用在需要改变的页面上。这样你 state 中的数据就不会呗污染啦。而且保留了原有的 state 数据。

运行结果

image.png

modules:它的主要作用就是对项目中的vuex进行模块化分配,当你的项目足够大的时候,需要用到该属性,中小型项目对该属性运用的需求不是特别高

image.png

index.js 文件

import Vue from 'vue'
import Vuex from 'vuex'
//  导入你需要用的模块 Cart.js
import Cart from './modules/Cart.js'
import details from './modules/details'
Vue.use(Vuex);

const store = new Vuex.Store({
    //  利用 modules 把导入的模块放进去      
   modules:{
    Cart,
    details
   }
})

export default store;

Cart.js 文件

const Cart = {
    // 加上命名空间 (用来区分你的 modules 文件名称)
    namespaced: true,
    state:()=>({
        // 定义一个 CartList 数据
        CartList:[{id:1,name:'Jay'},{id:2,name:'Esony'},{id:3,name:'JJlin'}]
    }),
    mutations:{
        // 定义一个 change 方法
        change(state,payload){
            state.CartList.forEach(item => {
                item.id += payload
            });
        }
    }
}

export default Cart

再调用的时候跟之前没模块化分配的时候差不多,主要是增加了一个命名空间的操作,获取 State 数据

App.vue

<template>
  <div>
    {{this.$store.state.Cart.CartList}}
  </div>
</template>

<script>
export default {
  name: 'DemoApp',

  data() {
    return {
    };
  },

  created(){
  },
  mounted() {
  },

  methods: {

  },
};
</script>

<style lang="scss" scoped>

</style>

运行结果:

image.png

调用 Mutations 方法

<template>
  <div>
    <button @click="change(10000)">大大大</button>
    {{this.$store.state.Cart.CartList}}
  </div>
</template>

<script>
export default {
  name: 'DemoApp',

  data() {
    return {
    };
  },

  created(){
  },
  mounted() {

  },

  methods: {
    change(number){
      this.$store.commit('Cart/change',number)
    },
  },
};
</script>

<style lang="scss" scoped>

</style>

运行结果

image.png

其实用法都一样,只需要注意在每个文件中加上 namespaced 调用的时候添加上对应的文件名称就行。

总结:

state : 用来储存数据

mutations:修改 state 中的数据,通过 $store.commit 去调用

Actions: 用来修改异步操作(切记切记),紧张直接去修改 state 中的数据,通过 $store.dispatch 去调用

getters: 类似与计算属性的作用,用来对 state 中的数据进行处理 通过 $store.getters

modules:对每一个vuex进行模块化分配,需要在主文件中先导入,然后引入进去

其实他们对应有各自的辅助函数,可以直接调用分别是 { mapState,mapActions,mapMutations,mapGetters }在vuex中引入,因为本人不太喜欢用辅助函数,所以就不标明啦,需要看的小伙伴可以从百度查找一下,要是各位觉得该文章还满意有帮助到你,可以点赞收藏一下,也可以在底下留言出一期 辅助函数的教学文章。🤭(●'◡'●)