Vue.js 3.0 学习笔记(十三)状态管理——Vuex

一、什么是Vuex

Vuex是一种状态管理模式,它采用集中式存储管理应用的所有组件的数据,并以相应的规则保证数据以一种可预测的方式发生变化。
这样比较官方的解释说起来还是太抽象了,简单来说,就是通过一种特定的规则来管理整个vue项目中需要共享的数据,在修改共享的数据时就会响应式地修改所有使用这些数据的组件,对于大型项目来说更方便管理。

二、安装Vuex

main.js文件

import { createApp } from 'vue'
import App from './App.vue'
//引入vuex
import { createStore } from 'vuex'

const store=createStore({
    state(){
        return{
            count:1
        }
    }
})
const app=createApp(App)
app.mount('#app')
//使用vuex插件
app.use(store)

三、在项目中使用vuex

1、搭建一个项目

  1. 在项目中新建store文件夹

  2. 在store下新建index.js
    在这里插入图片描述

  3. 输入以下代码

import {createStore} from "vuex";

export default createStore({
    state:{

    },
    mutations:{

    },
    actions:{

    },modules:{

    }
})

后续一一解释其中的对象

2、state对象

  1. 把共用的数据提取出来,放到状态管理的state对象中
import {createStore} from "vuex";

export default createStore({
    state:{
        name:"洗衣机",
        price:8600
    },
    mutations:{

    },
    actions:{

    },modules:{

    }
})

  1. 新建一个组件,在组件中通过store.state.xxx获取state对象的数据
<template>
  <div>
    <h1>商品名称:{{name}}</h1>
    <h1>商品价格:{{price}}</h1>
  </div>
</template>

<script>
import store from "@/store";

export default {
  name: "StateObject",
  computed:{
    name(){
      return store.state.name
    },
    price(){
      return store.state.price
    }
  }
}
</script>

<style scoped>

</style>

可以不用通过main.js配置,直接导入

3、getter对象

getter相当于state的计算属性,getter的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变,才会被重新计算。

  1. 修改index.js
import {createStore} from "vuex";

export default createStore({
    state:{
        name:"洗衣机",
        price:8600
    },
    getters:{
      getterPrice(state){
          return state.price+=300;
      }
    },
    mutations:{

    },
    actions:{

    },modules:{

    }
})

  1. 修改组件代码
<template>
  <div>
    <h1>商品名称:{{name}}</h1>
<!--    <h1>商品价格:{{price}}</h1>-->
    <h1>商品上涨后的价格:{{getPrice}}</h1>
  </div>
</template>

<script>
import store from "@/store";

export default {
  name: "StateObject",
  computed:{
    name(){
      return store.state.name
    },
    price(){
      return store.state.price
    },
    getPrice(){
      return store.getters.getterPrice
    }
  }
}
</script>

<style scoped>

</style>

4、mutation对象

修改Vuex的store数据,唯一的方法就是提交mutation,而mutation类似methods
每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler),通过commit联系

  1. 修改index.js
import {createStore} from "vuex";

export default createStore({
    state:{
        name:"洗衣机",
        price:8600
    },
    getters:{
      getterPrice(state){
          return state.price+=300;
      }
    },
    mutations:{
        addPrice(state,obj){
            return state.price+=obj.num;
        },
        subPrice(state,obj){
            return state.price-=obj.num;
        }
    },
    actions:{

    },modules:{

    }
})

  1. 修改组件代码
<template>
  <div>
    <h1>商品名称:{{name}}</h1>
<!--    <h1>商品价格:{{price}}</h1>-->
<!--    <h1>商品上涨后的价格:{{ getPrice }}</h1>-->
    <h1>商品的最新价格:{{ price }}</h1>
    <button @click="handlerAdd()">涨价</button>
    <button @click="handlerSub()">降价</button>
  </div>
</template>

<script>
import store from "@/store";

export default {
  name: "StateObject",
  computed:{
    name(){
      return store.state.name
    },
    price(){
      return store.state.price
    },
    getPrice(){
      return store.getters.getterPrice
    }
  },
  methods:{
    handlerAdd(){
      store.commit("addPrice",{
        num:100
      })
    },
    handlerSub(){
      store.commit("subPrice",{
        num:100
      })
    },
  }
}
</script>

<style scoped>

</style>

5、action对象

action类似于mutation
但是mutation修改状态时是同步,而所有的异步逻辑都应该封装在action对象中
action提交的是mutation,而不是直接变更数据状态,中间多了一个过程

  1. 修改index.js文件
addPriceasy(context){
            setTimeout(()=>{
                context.commit("addPrice",{
                num:100
             })
            },3000)
       },
      subPriceasy(context){
            setTimeout(()=>{
                context.commit("subPrice",{
                num:100
             })
            },3000)
       }
  1. 修改组件代码
<template>
  <div>
    <h1>商品名称:{{name}}</h1>
<!--    <h1>商品价格:{{price}}</h1>-->
<!--    <h1>商品上涨后的价格:{{ getPrice }}</h1>-->
    <h1>商品的最新价格:{{ price }}</h1>
    <button @click="handlerAdd()">涨价</button>
    <button @click="handlerSub()">降价</button>
    <button @click="handlerAddasy()">异步涨价(3秒后执行)</button>
    <button @click="handlerSubasy()">异步降价(3秒后执行)</button>
  </div>
</template>

<script>
import store from "@/store";

export default {
  name: "StateObject",
  computed:{
    name(){
      return store.state.name
    },
    price(){
      return store.state.price
    },
    getPrice(){
      return store.getters.getterPrice
    }
  },
  methods:{
    handlerAdd(){
      store.commit("addPrice",{
        num:100
      })
    },
    handlerSub(){
      store.commit("subPrice",{
        num:100
      })
    },
    handlerAddasy(){
      store.dispatch("addPriceasy")
    },
    handlerSubasy(){
      store.dispatch("subPriceasy")
    },
  }
}
</script>

<style scoped>

</style>

commit 和dispatch的区别在于commit是提交mutatious的同步操作,dispatch是分发actions的异步操作,例如:向后台发送数据

四、什么时候使用Vuex

要说这个问题,我们就得先看看vuex有什么好处

  1. Vuex的状态存储是响应式的,当store中的状态发生改变时,相应的组件也会相应地同步更新
  2. 不能直接改变store中的数据,改变store中数据的唯一途径就是显式地提交(commit)mutation

看完就能很明显感受到,只有大型项目才需要使用vuex进行管理,一般的小型项目使用vuex反而感觉有些麻烦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值