【9 Vue全家桶 – Vuex状态管理】

文章详细介绍了Vuex的状态管理机制,包括如何创建和使用store,state的读取与修改,以及通过mutation进行同步更新。同时,讲解了getter的使用来处理state数据,action用于处理异步操作,并展示了module如何抽离模块进行更高效的状态管理。重点强调了不要在mutation中执行异步操作的原则。
摘要由CSDN通过智能技术生成

1 什么是状态管理

其实是数据管理但是为了更好的指出是由于状态的变化导致数据的变化(响应式数据),我们称之为状态管理.
在这里插入图片描述

2 Vuex的状态管理

在这里插入图片描述

组件只能直接读取state,而不能直接修改state,必须通过mutation才能修改.(pinia可以直接读取和修改state)

在这里插入图片描述

3 Vuex的安装

npm install vuex

4 创建Store

在这里插入图片描述

文件结构

在这里插入图片描述

1 创建store,使用state(核心一)

import { createStore } from 'vuex'

const store = createStore({
  state: () => ({
    // 模拟数据
    // counter: 100,
    rootCounter: 100,

  }),
 
 //用于修改state的mutations
  mutations: {
    increment(state) {
      state.counter++
    }
   
  }
  
})

export default store

2 使用和修改state,解构state获取数据

<template>
  <div class="app">
  //模板中使用
    <h2>Home当前计数: {{ $store.state.counter }}</h2>
    //options API 使用
    <h2>Computed当前计数: {{ storeCounter }}</h2>
    //setUP API 使用
    <h2>Setup当前计数: {{ counter }}</h2>
    // 修改state
    <button @click="increment">+1</button>
  </div>
</template>

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

<script setup>
  import { toRefs } from 'vue'
  import { useStore } from 'vuex'

  const store = useStore()
  //解构state获取数据,counter,可以是多个数据,起别名等(推荐)
  const { counter } = toRefs(store.state)
  
  function increment() {
    // store.state.counter++
    store.commit("increment")
  }
</script>

<style scoped>
</style>



5 getters的基本使用 对state数据进行加工(核心二)

inde.js代码

const store = createStore({
  state: () => ({
    // 模拟数据
    // counter: 100,
    rootCounter: 100,
    name: "coderwhy",
    level: 100,
    avatarURL: "http://xxxxxx",
    friends: [
      { id: 111, name: "why", age: 20 },
      { id: 112, name: "kobe", age: 30 },
      { id: 113, name: "james", age: 25 }
    ],

  }),
  getters: {
    // 1.基本使用
    doubleCounter(state) {
      return state.counter * 2
    },
    totalAge(state) {
      return state.friends.reduce((preValue, item) => {
        return preValue + item.age
      }, 0)
    },
    // 2.在该getters属性中, 获取其他的getters
    message(state, getters) {
      return `name:${state.name} level:${state.level} friendTotalAge:${getters.totalAge}`
    },
    // 3.getters是可以返回一个函数的, 调用这个函数可以传入参数(了解)
    getFriendById(state) {
      return function(id) {
        const friend = state.friends.find(item => item.id === id)
        return friend
      }
    }
  },

vue代码

 <template>
 <div class="app">
   <!-- <button @click="incrementLevel">修改level</button> -->
   <h2>doubleCounter: {{ $store.getters.doubleCounter }}</h2>
   <h2>friendsTotalAge: {{ $store.getters.totalAge }}</h2>
   <h2>message: {{ $store.getters.message }}</h2>

   <!-- 根据id获取某一个朋友的信息 -->
   <h2>id-111的朋友信息: {{ $store.getters.getFriendById(111) }}</h2>
   <h2>id-112的朋友信息: {{ $store.getters.getFriendById(112) }}</h2>
 </div>
</template>

6 Mutation基本使用,state的修改(核心三)

重要的原则: 不要在mutation方法中执行异步操作

mutations: {
    increment(state) {
      state.counter++
    },
    changeName(state, payload) {
      state.name = payload
    },
    incrementLevel(state) {
      state.level++
    },
    changeInfo(state, newInfo) {
      state.level = newInfo.level
      state.name = newInfo.name

      // 重要的原则: 不要在mutation方法中执行异步操作

    },

methods: {
      changeName() {
        // this.$store.state.name = "李银河"
        //带外部参数的修改
        this.$store.commit("changeName", "王小波")
      },
      incrementLevel() {
        this.$store.commit("incrementLevel")
      },
      changeInfo() {
      //外部参数是一个对象
        this.$store.commit("changeInfo", {
          name: "王二",
          level: 200
        })
      }
    }
  }
</script>

7 actions的基本使用 ,异步派发(核心四)

使用dispatch函数进行分发
在这里插入图片描述

actions: {
    incrementAction(context) {
      // console.log(context.commit) // 用于提交mutation
      // console.log(context.getters) // getters
      // console.log(context.state) // state
      context.commit("increment")
    },
    changeNameAction(context, payload) {
      context.commit("changeName", payload)
    },

  },
<template>
<div class="home">
  <h2>当前计数: {{ $store.state.counter }}</h2>
  <button @click="counterBtnClick">发起action修改counter</button>
  <h2>name: {{ $store.state.name }}</h2>
  <button @click="nameBtnClick">发起action修改name</button>
</div>
</template>

<script>

export default {
  methods: {
    counterBtnClick() {
      this.$store.dispatch("incrementAction")
    },
    nameBtnClick() {
      this.$store.dispatch("changeNameAction", "aaa")
    }
  }
}
</script>

<script setup>

</script>

<style scoped>
</style>


actions的异步操作

在这里插入图片描述

8 module的基本使用,抽出模块(核心五)

在这里插入图片描述
定义一个单独的home.js文件

export default {
  state: () => ({
    // 服务器数据
    banners: [],
    recommends: []
  }),
  mutations: {
    changeBanners(state, banners) {
      state.banners = banners
    },
    changeRecommends(state, recommends) {
      state.recommends = recommends
    }
  },
  actions: {
    fetchHomeMultidataAction(context) {
      return new Promise(async (resolve, reject) => {
        // 3.await/async
        const res = await fetch("http://123.207.32.32:8000/home/multidata")
        const data = await res.json()
        
        // 修改state数据
        context.commit("changeBanners", data.data.banner.list)
        context.commit("changeRecommends", data.data.recommend.list)

        resolve("aaaaa")
      })
    }
  }
}

导入index.js

//导入模块对象
import homeModule from './modules/home'
//导入模块
modules: {
    home: homeModule,
  }

使用xxx.vue文件

<template>
  <div class="home">
    <h2>Home Page</h2>
    <ul>
      <!-- 使用数据时需要模块名 state.modulename.xxx -->
      <template v-for="item in $store.state.home.banners" :key="item.acm">
        <li>{{ item.title }}</li>
      </template>
    </ul>
  </div>
</template>

<script>
</script>

<script setup>

  import { useStore } from 'vuex'

  // 调用方法时,不需要模块名
  const store = useStore()
  store.dispatch("fetchHomeMultidataAction").then(res => {
    console.log("home中的then被回调:", res)
  })

</script>


<style scoped>
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力修福报

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值