Vuex最全讲解,成为前端大佬必备知识,爆肝一万多字,我行你也行❤

x33g5p2x  于2021-09-24 转载在 Vue.js  
字(10.3k)|赞(0)|评价(0)|浏览(890)

Vuex概况

store核心概念

1.- State:  包含了store中存储的各个状态。

2.- Getters:  类似于 Vue 中的计算属性,根据其他 getter 或 state 计算返回值。

3.- Mutation: 一组方法,是改变store中状态的执行者,只能是同步操作。

4.- Action:  一组方法,其中可以包含异步操作。

5.- Moudule:  Module是store分割的模块,每个模块拥有自己的state、getters、mutations、actions。   

vuex辅助函数

在Vuex中获取数据的辅助函数有两个mapState、mapGetters,

操作Mutation和acitonhas函数mapMutations、mapActions

前两个用在computed(计算属性中)

后两个用在methods(方法中)

如何使用

多个组件共享同一个状态(数据)

1.安装vuex

新建store文件夹===>index.js

main.js中,导入store对象,并且放在new Vue中 就可以通过this.$store的方式获取到这个store对象
2.使用vuex中的count(state中定义的共享状态)

this.$store.state.count

3.不能直接修改store中的状态,直接修改devtools监听不到数据的修改

4.mutations 负责同步修改状态

Vuex的store修改状态唯一的方式:提交mutations-->(this.$store.commit('add'))

Getters Store中的计算属性

  1. // 计算数字的平方
  2. quadratic(state) {
  3. // 第一个参数,状态state
  4. return state.count * state.count
  5. }

2.筛选数据

  1. filterInfo(state) {
  2. return state.info.filter(res =>{
  3. return res.age>18
  4. })
  5. }
  • 获取数据
  1. info:this.$store.getters.filterInfo

3.如果想要获取符合条件的个数

  • {{$store.getters.filterInfo.length}}
    4.如果不想年龄晒选写死,想自己输入年龄,只需要在getters里写一个方法
  1. // 筛选数据
  2. filterInfo(state, age) {
  3. //要返回一个方法才可以传值
  4. //age返回的不是一个确定的值,而是一个函数
  5. // 1.
  6. // return function(age){
  7. // return state.info.filter(res =>{
  8. // return res.age>age
  9. // })
  10. // }
  11. // 2.
  12. return (age) => {//return后才可以传递参数
  13. return state.info.filter(res => res.age > age)
  14. }

5.getters中的两个参数

  1. // 第一个state,拿数据,第二个参数geters:也就是说可以从getters中调用上面平方根的方法
  2. testGettes(state,getters){
  3. return getters.quadratic
  4. }

vuex辅助函数 

辅助函数

mapState, 用于将state中的数据映射到组件的计算属性中

  1. <!-- 第一种 -->
  2. <!--
  3. 组件中的计算属性名称,和vuex状态名称不一致的时候,可以使用对象写法
  4. -->
  5. computed:mapState({
  6. cnum:"count",
  7. })
  8. <!-- 第二种 -->
  9. <!--
  10. 字符串数组写法,
  11. 组件中计算属性名,和vuex中状态名一致的时候
  12. -->
  13. computed:mapState([
  14. "count",
  15. ])
  16. <!-- 第三种 -->
  17. <!--
  18. 当组件有自己的计算属性的时候,我们可以使用结构写法,将辅助函数合并到计算属性中
  19. -->
  20. computed:{
  21. ...mapState({
  22. cnum:"count",
  23. })
  24. }

mapGetters 用于将getter中的计算属性映射到组件的计算属性中用法同mapState

  1. computed:{
  2. // 对象展开符,解构mapGetters
  3. ...mapGetters({
  4. // 将store中的getters的filterInfo,映射到组件上的info计算属性上
  5. info:"filterInfo"
  6. }),
  7. ...mapGetters([ //字符串数组
  8. "getInfoLength"
  9. ])
  10. }
  11. mapMutations : 用于将mutations映射到methods
  12. ...mapMutations([
  13. "add"
  14. ]),
  15. // 对象写法
  16. ...mapMutations({
  17. // 同步,通过commit触发mutations
  18. myadd:"add",
  19. // 方法名:mutation函数名
  20. addtwo:"addParms"
  21. }),
  22. mapActions :于将actions映射到methods
  23. ...mapActions({
  24. // 方法名:mutation函数名
  25. myasync:"asyncAdd"
  26. })

Vuex中的核心 --- modules

当项目比较大的时候,如果只有一个模块来维护数据,那么这个模块会非常的大,对于维护性来说,不是特别高,所以vuex中,提供模块功能,我们可以通过modules将vuex处理为多个模块

  1. const myCount={
  2. state:{
  3. user:{
  4. name:'admin',
  5. pass:'12345'
  6. },
  7. count:10
  8. },
  9. getters:{
  10. },
  11. mutations:{
  12. // 模块的同步中是没有第三参数,(根状态)
  13. cAdd(state,paylaod){
  14. console.log(this)
  15. state.count++
  16. }
  17. },
  18. actions:{
  19. }
  20. }
  21. export default new Vuex.Store({
  22. state:{
  23. num:2
  24. },
  25. modules: { // 模块选项
  26. // 引用myuser模块
  27. u:myUser,
  28. c:myCount,
  29. cat
  30. }
  31. })

使用模块的属性

  1. $store.state.模块名称.属性名
  2. $store.getters.模块名称.属性名
  3. $store.commit('方法名称')//同步提交
  4. $store.dispatch('方法名称') //异步提交

实战解析 

上面概念说完了,该实战练习了,动起来!

State,Mutations

store下的index.js

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. // 安装插件
  4. Vue.use(Vuex)
  5. export default new Vuex.Store({
  6. state: {//存储状态
  7. // 自定义共享状态
  8. count:0,
  9. stu:[
  10. {id:1001,name:123},
  11. {id:1003,name:'符鼠'},
  12. {id:1004,name:'追梦'},
  13. ],
  14. user:{
  15. name:'随便',
  16. sex:'随机'
  17. }
  18. },
  19. // vuex中的store状态更新的唯一方式是提交Mutation
  20. mutations: {//写方法,通过mutations修改、页面的插件才能监听到
  21. add(state){//方法的第一个参数就是state,也就是state的对象
  22. // this是store对象
  23. state.count++
  24. },
  25. //state(store中的state),(Payload:提交方法携带的参数)
  26. addTen(state,ten){//点击加10
  27. state.count += ten
  28. },
  29. addTwo(state,obj){//点击加2,加obj才能接收对象
  30. state.count += obj.two
  31. },
  32. // 向stu数组中添加一条数据
  33. addStu(state,payload){
  34. state.stu.push(payload)//向数组中添加数据
  35. },
  36. updUser(state,age){//给stu对象添加新属性
  37. // state.user.age='18'不能写等号
  38. // state.user = {...state.user,'age':12}
  39. Vue.set(state.user,'age',123)
  40. }
  41. },
  42. actions: {},
  43. modules: {}
  44. })

Aone组件

  1. <template>
  2. <div class="hello">
  3. <h1>aone组件</h1>
  4. <h2>{{$store.state.count}}</h2>
  5. <li>{{$store.state.stu}}</li>
  6. <button @click="addTen">+10</button>
  7. <button @click="addStu">添加成员</button>
  8. </div>
  9. </template>
  10. <script>
  11. export default {
  12. name: 'aone',
  13. props: {
  14. msg: String,
  15. count:Number
  16. },
  17. data() {
  18. return {
  19. stu:{id:1005,name:'测试'}
  20. }
  21. },
  22. methods: {
  23. addTen(){
  24. // 触发mutations函数,指定额外参数,字符串方式提交
  25. this.$store.commit('addTen',10)
  26. },
  27. addStu(){
  28. this.$store.commit('addStu',this.stu)
  29. }
  30. },
  31. }
  32. </script>

hello组件

  1. <template>
  2. <div class="hello">
  3. <h1>helloworld组件</h1>
  4. <h2>{{$store.state.count}}</h2>
  5. <h2>{{$store.state.user}}</h2>
  6. <button @click="addTwo">点击加2</button>
  7. <button @click="updUser">修改</button>
  8. </div>
  9. </template>
  10. <script>
  11. export default {
  12. name: 'HelloWorld',
  13. props: {
  14. msg: String,
  15. count:Number
  16. },
  17. methods: {
  18. addTwo(){
  19. // 触发mutations函数,指定额外参数,对象形式提交
  20. this.$store.commit({
  21. type:'addTwo',
  22. two:2
  23. })
  24. },
  25. updUser(){
  26. // 触发mutations函数,指定额外参数
  27. this.$store.commit({
  28. type:'updUser' })
  29. }
  30. },
  31. }
  32. </script>

Actions,Getters 

store下的index.js

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. // 安装插件
  4. Vue.use(Vuex)
  5. // 实例化vuex并导出
  6. export default new Vuex.Store({
  7. state: {
  8. count: 0,
  9. info: [
  10. {
  11. di: 1, name: '开发者1', age: 21
  12. },
  13. {
  14. di: 2, name: '开发者2', age: 22
  15. },
  16. {
  17. di: 3, name: '开发者3', age: 23
  18. },
  19. ]
  20. },
  21. // 只能通过mutations更改数据
  22. mutations: {//如果mutation是一个异步函数,那么devtools不能跟踪数据变化
  23. // mutations负责同步修改状态
  24. increment(state, payload) {
  25. // setTimeout(()=>{
  26. state.count += payload
  27. // },2000)
  28. }
  29. },
  30. // 专写异步actions
  31. actions: {//context上下文对象
  32. asyncIcrement(context, payload) {
  33. setTimeout(() => {
  34. context.commit('increment', payload)
  35. }, 2000)
  36. }
  37. },
  38. getters: {//store的计算属性
  39. // 计算数字的平方
  40. quadratic(state) {
  41. // 第一个参数,状态state
  42. return state.count * state.count
  43. },
  44. // 筛选数据
  45. filterInfo(state, age) {
  46. //要返回一个方法才可以传值
  47. //age返回的不是一个确定的值,而是一个函数
  48. // return function(age){
  49. // return state.info.filter(res =>{
  50. // return res.age>age
  51. // })
  52. // }
  53. return (age) => {//return后才可以传递参数
  54. return state.info.filter(res => res.age > age)
  55. }
  56. },
  57. testGettes(state,getters){
  58. // 调用上面平方根的方法
  59. return getters.quadratic
  60. }
  61. },
  62. modules: {
  63. }
  64. })

myvux组件

  1. <template>
  2. <div id="main">
  3. <h2>这是myvue组件</h2>
  4. <h3>{{$store.state.count}}</h3>
  5. <button @click="add">+1</button>
  6. <button @click="asyAdd">异步+1</button>
  7. <h2>获取年龄小于22的开发</h2>
  8. </div>
  9. </template>
  10. <script>
  11. export default {
  12. methods: {
  13. add(){
  14. this.$store.commit('increment',5)
  15. },
  16. asyAdd(){
  17. // 触发actions异步并传参
  18. this.$store.dispatch('asyncIcrement',10)
  19. }
  20. },
  21. }
  22. </script>

myhome组件

  1. <template>
  2. <div id="home">
  3. <h2>这是home组件</h2>
  4. <h3>{{$store.state.count}}</h3>
  5. <h3>平方:{{$store.getters.quadratic}}</h3>
  6. <!-- 通过getters来筛选数据 -->
  7. <div>
  8. <h3>获取大于22的</h3>
  9. <li v-for="itme in info">
  10. {{itme}}
  11. </li>
  12. <!-- {{$store.getters.filterInfo.length}} -->
  13. //调用上面函数
  14. <h5>{{$store.getters.testGettes}}</h5>
  15. </div>
  16. </div>
  17. </template>
  18. <script>
  19. export default {
  20. data() {
  21. return {
  22. info:this.$store.getters.filterInfo(22)
  23. }
  24. },
  25. }
  26. </script>

 辅助函数及Modules

store下的index.js

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. Vue.use(Vuex)
  4. export default new Vuex.Store({
  5. state: {
  6. count:0,
  7. user:{
  8. name:'admin',
  9. pass:'123'
  10. },
  11. info: [
  12. {
  13. di: 1, name: '开发者1', age: 21
  14. },
  15. {
  16. di: 2, name: '开发者2', age: 22
  17. },
  18. ]
  19. },
  20. getters:{
  21. filterInfo(state){
  22. // 过滤大于20的数据
  23. return state.info.filter(info=>info.age>22)
  24. },
  25. getInfoLeng(state,getter){
  26. return getter.filterInfo.length
  27. }
  28. },
  29. mutations: {
  30. add(state){
  31. this.count ++
  32. },
  33. addParms(state,num){
  34. this.count += num
  35. }
  36. },
  37. actions: {
  38. //异步
  39. asyncAdd(context){
  40. setTimeout(()=>{
  41. context.commit('add')
  42. },2000)
  43. }
  44. },
  45. modules: {
  46. }
  47. })

Mystate组件(mapstate对应state)

  1. <template>
  2. <div id="mystate">
  3. <!-- 使用vuex中的count -->
  4. <p>数字:{{ $store.state.count }}</p>
  5. <!-- <p>数字data:{{num}}</p> -->
  6. <!-- <p>计算属性中的数字:{{cnum}}</p> -->
  7. <!-- vuex中的数据 -->
  8. <!-- <p>mapstate:{{count}}</p>
  9. <p>mapstate:{{user}}</p> -->
  10. <p>cuser:{{ cuser }}</p>
  11. <p>cuser:{{ csuser }}</p>
  12. <p>cnum:{{ cnum }}</p>
  13. <p>组件自己的计算属性:{{ cPrice }}</p>
  14. </div>
  15. </template>
  16. <script>
  17. import {mapState} from 'vuex'
  18. // console.log(mapState);
  19. export default {
  20. data() {
  21. return {
  22. // 在data中定义不是响应式
  23. num:this.$store.state.count,
  24. price:10
  25. }
  26. },
  27. // 计算属性
  28. // computed:{
  29. // cnum(){
  30. // return this.$store.state.count
  31. // }
  32. // }
  33. // 通过mapState辅助函数,帮我们自动生成计算属性
  34. // computed:mapState([//字符串数组写法
  35. // // 属性名和vuex状态名相同可以使用数组的形式写
  36. // 'count',//将vuex中状态count映射到计算属性中
  37. // 'user'
  38. // ])
  39. // 以对象形式使用
  40. // computed:mapState({
  41. // cuser(state){
  42. // // 通过计算属性的第一个函数,是vuex中的状态state,所以可以通过state直接获取数据
  43. // return state.user//this.$store.user
  44. // },
  45. // // 简写方式
  46. // csuser:state => state.user,
  47. // // 等价于tate => state.count
  48. // cnum:'count'
  49. // })
  50. computed:{
  51. //组件自己的计算属性
  52. cPrice(){
  53. return '$'+this.price
  54. },
  55. //通过mapState映射过来的计算属性
  56. ...mapState({
  57. cuser(state){
  58. // 通过计算属性的第一个函数,是vuex中的状态state,所以可以通过state直接获取数据
  59. return state.user//this.$store.user
  60. },
  61. // 简写方式
  62. csuser:state => state.user,
  63. // 等价于tate => state.count
  64. cnum:'count'
  65. })
  66. }
  67. }
  68. </script>

Mygetter组件(mapgetters对应getters)

  1. <template>
  2. <div id="mygetter">
  3. <h3>mapgetter用法</h3>
  4. <p>直接使用getters:{{$store.getters.filterInfo}}</p>
  5. <p>mapgetters:{{info}}</p>
  6. <p>获取长度(info):{{getInfoLeng}}</p>
  7. </div>
  8. </template>
  9. <script>
  10. // 获取辅助函数
  11. import { mapGetters, mapState } from "vuex";
  12. // console.log(mapState);
  13. export default {
  14. computed: {
  15. // 对象展开符解构mapgetters
  16. ...mapGetters({//对象写法
  17. // 将store中的getters的filterInfo映射到组件上的info计算属性上
  18. info:'filterInfo'
  19. }),
  20. ...mapGetters([//字符串数组写法
  21. 'getInfoLeng'
  22. ])
  23. },
  24. };
  25. </script>

mymutations组件(mapmutations对应mutations)

  1. <template>
  2. <div id="mymutations">
  3. <h3>使用mapmutions和mapactions</h3>
  4. <button @click="add">触发add</button>
  5. <button @click="myadd">触发myadd</button>
  6. <!-- 传参 -->
  7. <button @click="addtwo(3)">+3</button>
  8. <button @click="myasync">触发异步</button>
  9. </div>
  10. </template>
  11. <script>
  12. // 获取辅助函数
  13. import {mapState,mapGetters,mapMutations,mapActions} from 'vuex';
  14. export default {
  15. // 计算属性
  16. computed:{
  17. },
  18. // 放方法
  19. methods: {
  20. // 为了触发mutation函数 定义的方法没必要这么写
  21. // clickAdd(){
  22. // this.$store.commit('add')
  23. // }
  24. //触发异步
  25. myasync(){
  26. this.$store.dispantch('asyncAdd')
  27. },
  28. // 字符串数组的用法
  29. ...mapMutations([
  30. 'add'
  31. ]),
  32. // 对象写法
  33. ...mapMutations({
  34. // 同步方法通过commit触发mutauions
  35. myadd:'add',
  36. // 方法名:mutation函数名
  37. addtwo:'addParms'
  38. }),
  39. //异步
  40. ...mapActions({
  41. myasync:'asyncAdd'
  42. })
  43. },
  44. }
  45. </script>

Modules模块的使用

  1. <script>
  2. //vuex文件
  3. import Vue from 'vue'
  4. import Vuex from 'vuex'
  5. import myUser from './myuser'
  6. import cat from './cat'
  7. Vue.use(Vuex)
  8. // const myUser={
  9. // }
  10. export default new Vuex.Store({
  11. modules: {//模块选项
  12. // 引入
  13. u:myUser,
  14. cat
  15. }
  16. })
  17. </script>
  18. -----------------------------------------------------------下面是展示页面
  19. <template>
  20. <div class="modules">
  21. <!-- 多了一层u -->
  22. <h4>user信息:{{$store.state.u.user}}</h4>
  23. <h4>cat信息:{{$store.state.cat.mycat}}</h4>
  24. </div>
  25. </template>

相关文章