vuex的基础使用

132 阅读2分钟

项目当中引入 vuex

  1. 下载包 npm i vuex@3

  2. 配置项目 main.js 一般项目创建都会配置好 一般会在src/store/index.js文件中配置

    import Vue from 'vue'
    import App from './App.vue'Vue.config.productionTip = false// 引入 vuex 的写法
    // 1. 引入库
    import Vuex from 'vuex'
    // 2. 安装
    Vue.use(Vuex)
    // 3. 创建仓库示例
    const store = new Vuex.Store()
    ​
    new Vue({
      // 4. 挂载new Vue 示例上
      store: store,
      render: h => h(App),
    }).$mount('#app')
    

概念一 state

创建

// 3. 创建仓库示例
const store = new Vuex.Store({
  // 配置对象
  // state 储存数据
  state: {
    count: 0,
    name: '小明',
    token: '1axcassdasd'
  }
})

基本使用

    <div>
      插值表达式: 
      {{$store.state.count}} 
      {{$store.state.name}} 
      {{$store.state.token}}
    </div>

优化方案

<template>
  <div>
    <div>
      计算属性封装 {{name}}
    </div>
  </div>
</template><script>
export default {
  // 如果觉得模板中每次都写完整的state路径非常麻烦
  // 可以封装到计算属性当中, 
  // 1. 它本身是作为数据渲染 
  // 2. 他可能后续会改变
  computed: {
    name() {
      return this.$store.state.name
    }
  }
}
</script><style></style>

vuex 自带辅助函数(mapState)

<template>
  <div>
    <div>
      计算属性封装 {{name}} {{count}} {{token}}
    </div>
  </div>
</template><script>
import { mapState } from 'vuex'
// console.log(mapState(['count', 'name', 'token']));
export default {
  // 如果觉得模板中每次都写完整的state路径非常麻烦
  // 可以封装到计算属性当中, 
  // 1. 它本身是作为数据渲染 
  // 2. 他可能后续会改变
  computed: {
    ...mapState(['count', 'name', 'token']),
    // 相当于生成了以下三个函数
    // ...{count: ƒ, name: ƒ, token: ƒ},
    // name() {
    //   return this.$store.state.name
    // },
    // count() {
    //   return this.$store.state.count
    // },
    // token() {
    //   return this.$store.state.token
    // }
  }
}
</script><style></style>

概念二 mutations

注意如何要修改state里的数据必须通过mutations进行修改,不通过mutations改state的数据不会生成数据快照,页面数据可以修改但是state里的数据不会改变

数据快照:浏览器vue调试工具的功能

image.png

创建

const store = new Vuex.Store({
  strict: true,
  // 配置对象
  // state 储存数据
  state: {
    count: 0,
    name: '小明',
    token: '123abc'
  },
  // 所有的变更都需要放在 mutations 里面
  mutations: {
    addCount(state) {
      // 这个函数被调用时默认会自动带上当前state对象
      state.count++
    }
  }
})

使用

<template>
  <div>
    <div>
      计算属性封装 {{name}} {{count}} {{token}}
    </div>
    <!-- <button @click="$store.state.count ++">直接增加</button> -->
    <button @click="$store.commit('addCount')">mutations增加</button>
  </div>
</template>

传参的用法 // mutations中的函数的第一个参数为state,第二个为传入的值,只有一个接收值,使用当你想要传多个值的时候,可以传入数组和对象,在把要的值一一提取出来

  mutations: {
    addCount(state, payload) {
      // 第二个参数可以用来传参, 调用commit时也在第二个参数放入即可
      // 这个函数被调用时默认会自动带上当前state对象
      state.count += payload
    }
  }

优化

注意, 由于mutations是要被执行的函数所以封装在 methods 里面

<template>
  <div>
    <!-- <button @click="$store.state.count ++">直接增加</button> -->
    <button @click="addCount(666)">mutations增加666</button>
    <button @click="addCount(888)">mutations增加888</button>
    <button @click="addCount(10)">mutations增加10</button>
  </div>
</template><script>
import { mapState } from 'vuex'
// console.log(mapState(['count', 'name', 'token']));
export default {
  methods: {
    addCount(data) {
      this.$store.commit('addCount', data)
    }
  }
}
</script>

辅助函数

<template>
  <div>
    <div>
      计算属性封装 {{name}} {{count}} {{token}}
    </div>
    <!-- <button @click="$store.state.count ++">直接增加</button> -->
    <button @click="addCount(666)">mutations增加666</button>
    <button @click="addCount(888)">mutations增加888</button>
    <button @click="addCount(10)">mutations增加10</button>
  </div>
</template><script>
import { mapState, mapMutations } from 'vuex'
export default {
  computed: {
    ...mapState(['count', 'name', 'token'])
  },
  methods: {
    ...mapMutations(['addCount'])
    // 他可以自动生成以下的函数
    // addCount(data) {
    //   this.$store.commit('addCount', data)
    // }
  }
}
</script><style></style>

概念三 actions

主要用于异步操作:如发起请求

和mutations一样,里的函数的第一个参数为state,第二个为传入的值,只有一个接收值,使用当你想要传多个值的时候,可以传入数组和对象,在把要的值一一提取出来

创建

const store = new Vuex.Store({
  strict: true,
  // 配置对象
  // state 储存数据
  state: {
   //...
  },
  // 所有的变更都需要放在 mutations 里面
  mutations: {
    //...
  },
  actions: {
    asyncAddCount(store, payload) {
      // actions 的函数由于默认不能直接修改state
      // 需要调用 mutations 所以第一个接到的参数是当前仓库的 store 本身
      // 可以直接当做组件内 的 this.$store 来使用
      setTimeout(() => {
        store.commit('addCount', payload)
      }, 2000);
    }
  }
})

使用

<template>
  <div>
    <button @click="$store.dispatch('asyncAddCount', 10)">异步修改state</button>
  </div>
</template>

封装

<template>
  <div>
    <button @click="asyncAddCount(10)">异步修改state</button>
  </div>
</template><script>
export default {
  methods: {
    asyncAddCount(data) {
      this.$store.dispatch('asyncAddCount', data)
    }
  }
}
</script><style></style>

辅助函数

<template>
  <div>
    <button @click="asyncAddCount(10)">异步修改state</button>
  </div>
</template><script>
import { mapState, mapMutations, mapActions } from 'vuex'export default {
​
  computed: {
    ...mapState(['count', 'name', 'token']),
  },
  methods: {
    ...mapMutations(['addCount']),
    ...mapActions(['asyncAddCount'])
  }
}
</script><style></style>

getters

主要使用场景:后期项目中的state数据比较复杂,使用一般使用getters把state里要的数据提取出来,方便使用

创建

const store = new Vuex.Store({
  strict: true,
  state: {
    count: 0,
    list: [1,2,3,4,5,6,7,8,9,10,666,777,888]
  },
  // 能够派生出一个数据是list经过过滤返回所有大于5的数据
  getters: {
    // 每个属性都是一个函数
    // 默认第一个接收到的就是当前的 state 对象供我们进行数据的计算
    // filterList(state) {
    //   return state.list.filter(item=>item>5)
    // }
    filterList: state => state.list.filter(item=>item>5)
  }
})

使用

<template>
  <div>
    <!-- 基本用法 {{$store.getters.filterList}} -->
    {{filterList}}
  </div>
</template><script>
import { mapGetters } from 'vuex'
export default {
  computed: {
    ...mapGetters(['filterList'])
    // 也可以手动封装函数
    // filterList() {
    //   return this.$store.getters.filterList
    // }
  }
}
</script><style></style>

常见用途(简化数据获取)

const store = new Vuex.Store({
  strict: true,
  state: {
    student: {
      name: '小明',
      school: {
        name: '北京大学',
        address: '北京'
      }
    }
  },
  // 能够派生出一个数据是list经过过滤返回所有大于5的数据
  getters: {
    address: state => state.student.school.address
  }
})
<template>
  <dv>
    学校地址: {{$store.getters.address}}
  </div>
</template>