Vuex的使用看这一篇就够了

Vuex概述

Vuex 是一个专为 Vue.js 应用程序开发的状态管理库。它采用集中式存储管理应用的所有组件的状态,并以一种可预测的方式来保证状态以一种可预测的方式发生变化。

state状态

把公用的数据放到store里的state就行了,上面是vue2的代码,下面是vue3

import { createStore } from 'vuex'

export default createStore({
  state: {
    counter:0,
    title:'标题'
  },
  getters: {

  },
  mutations: {
  },
  actions: {
  },
  modules: {
  },

})

访问state里的数据

有两种方法,

1.通过store直接访问

2.通过辅助函数

通过store直接访问

注意,在模板,组件,js模块中的写法是不一样的

这里又可以分成两种方法,二者效果一样

直接用$store.state

<template>
  <nav>
    <p>counter:{{$store.state.counter}}</p>
    <p>{{$store.state.title}}</p>
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </nav>
  <router-view/>
</template>

<script>
export default {
  created() {
    console.log(this.$store)
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

写个计算属性

补充computed知识点

computed 属性中定义的 storeCount 方法被视为一个计算属性,Vue 会自动追踪其依赖。当 this.$store.state.count 的值变化时,storeCount 也会随之更新,从而实现响应式更新。这使得你能够在模板中直接使用 storeCount,而不需要手动管理状态的变化。

简而言之,这种方式利用了 Vue 的响应式特性,确保了数据的同步和更新。

<template>
  <nav>
    <p>counter:{{counter}}</p>
    <p>{{$store.state.title}}</p>
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </nav>
  <router-view/>
</template>

<script>
export default {
  computed:{
    counter(){
      return this.$store.state.counter
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

通过辅助函数mapState访问

可以看到上面的方法其实有点麻烦,因为如果要多次访问的话,代码量大,看起来也不整洁。

用法:

详细解释

  1. 导入 mapState

     

    javascriptCopy Code

    import { mapState } from 'vuex';

    通过导入 mapState,你可以在组件中使用这个函数。

  2. 使用 mapState

    javascriptCopy Code

    computed: { ...mapState(['count']) // 直接映射 state 中的 count }
    • mapState 接受一个字符串数组作为参数,这些字符串是 Vuex store 中 state 的属性名。
    • 这里的 ['count'] 表示你要将 Vuex store 中的 count 状态映射到当前组件的计算属性中。
  3. 展开运算符 ...

    • ... 是 ES6 的扩展运算符,它会将 mapState 返回的对象中的属性展开到 computed 中。
    • 这意味着 mapState(['count']) 会返回一个对象,例如 { count() { return this.$store.state.count; } },而展开运算符会将这个对象中的 count 方法直接添加到 computed 中。
  4. 结果

    • 最终,组件中就可以通过 {{ count }} 来直接使用 Vuex store 中的 count 状态了。由于计算属性的响应式特性,当 Vuex 中的 count 发生变化时,组件会自动重新渲染。

试一下

<template>
  <nav>
    <p>{{ counter }}</p>
    <p>{{ title }}</p>
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </nav>
  <router-view/>
</template>

<script>
import { mapState } from 'vuex';
export default {
  computed: {
    ...mapState(['counter','title'])
  },
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

修改store里的数据

Mutations介绍

通过mutations可以提供修改数据的方法

注意!mutation的第一个参数都是state。而且最多只能有两个参数,如果想实现多个参数,那第二个参数就要包装成对象

在store中定义 Mutation

import { createStore } from 'vuex'

export default createStore({
  state: {
    count:0,
    title:'标题'
  },
  getters: {

  },
  mutations: {
    add(state,n){
      state.count+=n
    }
  },
  actions: {
  },
  modules: {
  },

})

要调用 mutation,需要使用 store.commit 方法

<template>
  <nav>
    <p>{{ count }}</p>
    <p>{{ title }}</p>
    <button @click="add">增加</button>
  </nav>
<!--  <router-view/>-->
</template>

<script>
import { mapState } from 'vuex';
export default {
  computed: {
    ...mapState(['count','title'])
  },
  methods:{
    add(){
      this.$store.commit('add',3)
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;
}

nav a {
  font-weight: bold;
  color: #2c3e50;
}

nav a.router-link-exact-active {
  color: #42b983;
}
</style>

第二个参数要包装成对象的用法

add(state,obj){
      state.count+=obj.n
      console.log(obj.msg)
    }

import { createStore } from 'vuex'

export default createStore({
  state: {
    count:0,
    title:'标题'
  },
  getters: {

  },
  mutations: {
    add(state,obj){
      state.count+=obj.n
      console.log(obj.msg)
    }
  },
  actions: {
  },
  modules: {
  },

})

 add(){
        this.$store.commit('add',{
          n:3,msg:'哈哈'
        })
      }

  <template>
    <nav>
      <p>{{ count }}</p>
      <p>{{ title }}</p>
      <button @click="add">增加</button>
    </nav>
  <!--  <router-view/>-->
  </template>

  <script>
  import { mapState } from 'vuex';
  export default {
    computed: {
      ...mapState(['count','title'])
    },
    methods:{
      add(){
        this.$store.commit('add',{
          n:3,msg:'哈哈'
        })
      }
    }
  }
  </script>

  <style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
  </style>

练习

不能使用v-model双向绑定的方法。任何要修改仓库(store)里的数据,都要用mutation进行提交。

mapMutations介绍

mapMutations 是 Vuex 提供的一个辅助函数,用于简化组件中调用 mutations 的过程。它可以将 store 中的 mutation 映射为组件的方法,使得调用更简洁。

使用方法

  1. 导入 mapMutations

    import { mapMutations } from 'vuex';
  2. 在组件中使用

    在组件的 methods 中使用 mapMutations 来映射 mutations。例如:

export default {
  methods: {
    ...mapMutations(['increment', 'decrement']),
    
    // 你也可以指定方法名称
    ...mapMutations({
      add: 'increment', // 将 store 中的 increment 映射为组件的方法 add
    })
  }
}

  <template>
    <nav>
      <p>{{ count }}</p>
      <p>{{ title }}</p>
      <button @click="add({n:2,msg:'增加'})">增加</button>
    </nav>
  <!--  <router-view/>-->
  </template>

  <script>
  import { mapState,mapMutations } from 'vuex';
  export default {
    computed: {
      ...mapState(['count','title'])
    },
    methods:{
      ...mapMutations(['add'])
    }
  }
  </script>

  <style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
  </style>

mapActions

这边就主要介绍辅助函数mapAction了

  <template>
    <nav>
      <p>{{ count }}</p>
      <p>{{ title }}</p>
      <button @click="add(5)">增加</button>
      <button @click="change">延迟增加</button>
    </nav>
  <!--  <router-view/>-->
  </template>

  <script>
  import { mapState,mapMutations,mapActions } from 'vuex';
  export default {
    computed: {
      ...mapState(['count','title'])
    },
    methods:{
      ...mapMutations(['add']),
      ...mapActions(['change'])
    }
  }
  </script>

  <style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
  </style>

import { createStore } from 'vuex'

export default createStore({
  state: {
    count:0,
    title:'标题'
  },
  getters: {

  },
  mutations: {
    add(state,n){
      state.count+=n
    }
  },
  actions: {
    change(context,num){
      setTimeout(()=>{
        context.state.count+=10
      },1000)
    }
  },
  modules: {
  },

})

mapGetter

注意!

1.getters函数的第一个参数是state

2.必须要有返回值

  <template>
    <nav>
      <p>{{ count }}</p>
      <p>{{ title }}</p>
      <button @click="add(5)">增加</button>
      <button @click="change">延迟增加</button>
      <div>
        <p>mapGetter函数:</p>
        {{filterList}}
      </div>
    </nav>
  <!--  <router-view/>-->
  </template>

  <script>
  import { mapState,mapMutations,mapActions,mapGetters } from 'vuex';
  export default {
    computed: {
      ...mapState(['count','title']),
      ...mapGetters(['filterList'])
    },
    methods:{
      ...mapMutations(['add']),
      ...mapActions(['change'])
    }
  }
  </script>

  <style>
  #app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
  }

  nav {
    padding: 30px;
  }

  nav a {
    font-weight: bold;
    color: #2c3e50;
  }

  nav a.router-link-exact-active {
    color: #42b983;
  }
  </style>
import { createStore } from 'vuex'

export default createStore({
  state: {
    count:0,
    title:'标题',
    list:[1,2,3,4,5,6,7,8]
  },
  getters: {
    filterList(state){
      return state.list.filter(i=>i>4)
    }
  },
  mutations: {
    add(state,n){
      state.count+=n
    }
  },
  actions: {
    change(context,num){
      setTimeout(()=>{
        context.state.count+=10
      },1000)
    }
  },
  modules: {
  },

})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值