当前位置: 首页 > article >正文

第四十四章 Vue之actions/mapActions/getters

目录

一、actions

1.1. 使用方法

1.2. 完整代码

1.2.1. index.js

1.2.2. main.js

1.2.3. App.vue

1.2.4. Son1.vue

1.2.5. Son2.vue

二、mapActions

2.1. 使用方法

​2.2. 完整代码

三、getters

3.1. 使用方法

3.2. 完整代码

3.2.1. main.js

3.2.2. index.js

3.2.3. App.vue

3.2.4. Son1.vue

3.2.5. Son2.vue


一、actions

1.1. 使用方法

之前几个章节我们学习了通过mutations同步修改Vuex仓库数据,mutations 必须是同步的 (便于监测数据变化,记录调试),本章节我们将学习通过学习actions的基本语法,来处理对Vuex仓库的异步操作。

1. 提供action 方法

注意:actions处理异步,它不能直接操作state,操作state还是需要commit mutation 

2. 页面中 dispatch 调用

1.2. 完整代码

1.2.1. index.js

// 存放的是vuex相关的核心代码
import Vue from 'vue'
import Vuex from 'vuex'

// 配置插件给Vue使用
Vue.use(Vuex)

// 创建仓库(空仓库)
const store = new Vuex.Store({
  // 严格模式(有利于初学者,检测不规范的代码 => 上线的时候可以去掉)
  strict: true,
  // 1. 通过 state提供数据(所有组件可以共享)
  state: {
    title: '大标题',
    count: 100
  },
  // 2. 通过 mutations 可以提供修改数据的方法
  mutations: {
    // 所有mutation函数,第一个参数,都是 state
    addCount (state, n) {
      // 修改数据
      state.count += n
    },
    subCount (state, n) {
      // 修改数据
      state.count -= n
    },
    changeTitle (state, obj) {
      state.title = obj.newTitle
    },
    changeCount (state, newCount) {
      state.count += newCount
    }
  },
  // 3. actions处理异步,它不能直接操作state,操作state还是需要commit mutation
  actions: {
    // context 上下文 (此处因为我们还未分模块,可以当成store仓库)
    // context.commit('mutation名字', 额外参数)
    changeCountAction (context, num) {
      // 这里是setTimeout模拟异步,以后大部分场景是发请求
      setTimeout(() => {
        context.commit('changeCount', num)
      }, 1000)
    }
  }
})

// 导出给main.js使用
export default store

1.2.2. main.js

import Vue from 'vue'
import App from './App.vue'
import store from '@/store/index'
console.log(store.state.count)

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  store
}).$mount('#app')

1.2.3. App.vue

<template>
  <div id="app">
    <h1>根组件 - {{ title }} - {{ count }}</h1>
    <input :value="count" @input="handleInput" type="text">
    <Son1></Son1>
    <hr>
    <Son2></Son2>
  </div>
</template>

<script>
import Son1 from './components/Son1.vue'
import Son2 from './components/Son2.vue'
import { mapState } from 'vuex'

export default {
  name: 'app',
  created () {
    console.log(this.$store.state.count)
  },
  data () {
    return {

    }
  },
  methods: {
    handleInput (e) {
      // 1.实时获取输入框的值
      const num = e.target.value
      // 2.提交mutation,调用mutation函数
      this.$store.commit('changeCount', num)
    }
  },
  computed: {
    ...mapState(['count', 'title'])
  },
  components: {
    Son1,
    Son2
  }
}
</script>

<style>

</style>

1.2.4. Son1.vue

<template>
  <div class="box">
    <h2>{{ $store.state.title }}</h2>
    从vuex中获取的值:<label>{{ $store.state.count }}</label>
    <br>
    <button @click="subCount(1)">值 + 1</button>
    <button @click="subCount(5)">值 + 5</button>
    <button @click="subCount(10)">值 + 10</button>
    <button @click="handleSub(1)">值 - 1</button>
    <button @click="handleSub(5)">值 - 5</button>
    <button @click="handleSub(10)">值 - 10</button>
    <button @click="handleChange(34)">值 + 34</button>
    <button @click="changeTitle">改标题</button>
  </div>
</template>

<script>
import { mapMutations } from 'vuex'
export default {
  name: 'Son1Com',
  methods: {
    handleAdd (n) {
      // 错误代码(vue默认不会监测,监测需要成本)
      // this.$store.state.count++
      // console.log(this.$store.state.count)

      // 应该通过 mutation 核心概念,进行修改仓库数据
      // 需要提交调用mutation
      this.$store.commit('addCount', n)
    },
    ...mapMutations(['subCount']),
    changeTitle () {
      this.$store.commit('changeTitle', { name: '王哲晓', newTitle: '2024加油,迎接新的开始,新的起点,新的人生' })
    },
    handleChange (n) {
      // 调用action
      // this.$store.dispatch('action名字', 额外参数)
      this.$store.dispatch('changeCountAction', n)
    }
  }
}
</script>

<style lang="css" scoped>
.box {
    border: 3px solid #ccc;
    width: 400px;
    padding: 10px;
    margin: 20px;
}
h2 {
    margin-top: 10px;
}
</style>

1.2.5. Son2.vue

<template>
    <div class="box">
      <h2>Son2 子组件</h2>
      从vuex中获取的值:<label>{{ count }}</label>
      <br>
      <button>值 - 1</button>
    </div>
  </template>

<script>
import { mapState } from 'vuex'
export default {
  name: 'Son2Com',
  computed: {
    ...mapState(['count'])
  }
}
</script>

<style lang="css" scoped>
.box {
    border: 3px solid #ccc;
    width: 400px;
    padding: 10px;
    margin: 20px;
}
h2 {
    margin-top: 10px;
}
</style>

二、mapActions

2.1. 使用方法

mapActions 是把位于actions中的方法提取了出来,映射到组件methods中,简化了actions函数。

 2.2. 完整代码

我们在上面的代码基础上对Son1.vue稍做调整:

<template>
  <div class="box">
    <h2>{{ $store.state.title }}</h2>
    从vuex中获取的值:<label>{{ $store.state.count }}</label>
    <br>
    <button @click="subCount(1)">值 + 1</button>
    <button @click="subCount(5)">值 + 5</button>
    <button @click="subCount(10)">值 + 10</button>
    <button @click="handleSub(1)">值 - 1</button>
    <button @click="handleSub(5)">值 - 5</button>
    <button @click="handleSub(10)">值 - 10</button>
    <button @click="handleChange(34)">值 + 34</button>
    <button @click="changeTitle">改标题</button>
    <button @click="changeCountAction(6666)">1秒钟后化神</button>
  </div>
</template>

<script>
import { mapMutations, mapActions } from 'vuex'
export default {
  name: 'Son1Com',
  methods: {
    handleAdd (n) {
      // 错误代码(vue默认不会监测,监测需要成本)
      // this.$store.state.count++
      // console.log(this.$store.state.count)

      // 应该通过 mutation 核心概念,进行修改仓库数据
      // 需要提交调用mutation
      this.$store.commit('addCount', n)
    },
    ...mapMutations(['subCount']),
    ...mapActions(['changeCountAction']),
    changeTitle () {
      this.$store.commit('changeTitle', { name: '王哲晓', newTitle: '2024加油,迎接新的开始,新的起点,新的人生' })
    },
    handleChange (n) {
      // 调用action
      // this.$store.dispatch('action名字', 额外参数)
      this.$store.dispatch('changeCountAction', n)
    }
  }
}
</script>

<style lang="css" scoped>
.box {
    border: 3px solid #ccc;
    width: 400px;
    padding: 10px;
    margin: 20px;
}
h2 {
    margin-top: 10px;
}
</style>

三、getters

3.1. 使用方法

除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters(类似于计算属性)

例如:state 中定义了list,为1-10的数组,组件中需要显示所有大于5的数据。

1. 定义 getters

2. 访问getters

① 通过 store 访问 getters

② 通过辅助函数 mapGetters 映射

3.2. 完整代码

3.2.1. main.js

import Vue from 'vue'
import App from './App.vue'
import store from '@/store/index'
console.log(store.state.count)

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  store
}).$mount('#app')

3.2.2. index.js

// 存放的是vuex相关的核心代码
import Vue from 'vue'
import Vuex from 'vuex'

// 配置插件给Vue使用
Vue.use(Vuex)

// 创建仓库(空仓库)
const store = new Vuex.Store({
  // 严格模式(有利于初学者,检测不规范的代码 => 上线的时候可以去掉)
  strict: true,
  // 1. 通过 state提供数据(所有组件可以共享)
  state: {
    title: '大标题',
    count: 100,
    list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  },
  // 2. 通过 mutations 可以提供修改数据的方法
  mutations: {
    // 所有mutation函数,第一个参数,都是 state
    addCount (state, n) {
      // 修改数据
      state.count += n
    },
    subCount (state, n) {
      // 修改数据
      state.count -= n
    },
    changeTitle (state, obj) {
      state.title = obj.newTitle
    },
    changeCount (state, newCount) {
      state.count += newCount
    }
  },
  // 3. actions处理异步,它不能直接操作state,操作state还是需要commit mutation
  actions: {
    // context 上下文 (此处因为我们还未分模块,可以当成store仓库)
    // context.commit('mutation名字', 额外参数)
    changeCountAction (context, num) {
      // 这里是setTimeout模拟异步,以后大部分场景是发请求
      setTimeout(() => {
        context.commit('changeCount', num)
      }, 1000)
    }
  },
  // 4. getters 类似于计算属性
  getters: {
    // 注意点:
    // 1. 形参第一个参数,就是state
    // 2. 必须有返回值,返回值就是getters的值
    filterList (state) {
      return state.list.filter(item => item > 5)
    }
  }
})

// 导出给main.js使用
export default store

3.2.3. App.vue

<template>
  <div id="app">
    <h1>根组件 - {{ title }} - {{ count }}</h1>
    <input :value="count" @input="handleInput" type="text">
    <Son1></Son1>
    <hr>
    <Son2></Son2>
  </div>
</template>

<script>
import Son1 from './components/Son1.vue'
import Son2 from './components/Son2.vue'
import { mapState } from 'vuex'

export default {
  name: 'app',
  created () {
    console.log(this.$store.state.count)
  },
  data () {
    return {

    }
  },
  methods: {
    handleInput (e) {
      // 1.实时获取输入框的值
      const num = e.target.value
      // 2.提交mutation,调用mutation函数
      this.$store.commit('changeCount', num)
    }
  },
  computed: {
    ...mapState(['count', 'title'])
  },
  components: {
    Son1,
    Son2
  }
}
</script>

<style>

</style>

3.2.4. Son1.vue

<template>
  <div class="box">
    <h2>{{ $store.state.title }}</h2>
    从vuex中获取的值:<label>{{ $store.state.count }}</label>
    <br>
    <button @click="subCount(1)">值 + 1</button>
    <button @click="subCount(5)">值 + 5</button>
    <button @click="subCount(10)">值 + 10</button>
    <button @click="handleSub(1)">值 - 1</button>
    <button @click="handleSub(5)">值 - 5</button>
    <button @click="handleSub(10)">值 - 10</button>
    <button @click="handleChange(34)">值 + 34</button>
    <button @click="changeTitle">改标题</button>
    <button @click="changeCountAction(6666)">1秒钟后化神</button>
    <hr>
    <div>{{ $store.state.list }}</div>
    <div>{{ $store.getters.filterList }}</div>
    <hr>
    <div>{{ filterList }}</div>
  </div>
</template>

<script>
import { mapMutations, mapActions, mapGetters } from 'vuex'
export default {
  name: 'Son1Com',
  computed: {
    ...mapGetters(['filterList'])
  },
  methods: {
    handleAdd (n) {
      // 错误代码(vue默认不会监测,监测需要成本)
      // this.$store.state.count++
      // console.log(this.$store.state.count)

      // 应该通过 mutation 核心概念,进行修改仓库数据
      // 需要提交调用mutation
      this.$store.commit('addCount', n)
    },
    ...mapMutations(['subCount']),
    ...mapActions(['changeCountAction']),
    changeTitle () {
      this.$store.commit('changeTitle', { name: '王哲晓', newTitle: '2024加油,迎接新的开始,新的起点,新的人生' })
    },
    handleChange (n) {
      // 调用action
      // this.$store.dispatch('action名字', 额外参数)
      this.$store.dispatch('changeCountAction', n)
    }
  }
}
</script>

<style lang="css" scoped>
.box {
    border: 3px solid #ccc;
    width: 400px;
    padding: 10px;
    margin: 20px;
}
h2 {
    margin-top: 10px;
}
</style>

3.2.5. Son2.vue

 

<template>
    <div class="box">
      <h2>Son2 子组件</h2>
      从vuex中获取的值:<label>{{ count }}</label>
      <br>
      <button>值 - 1</button>
    </div>
  </template>

<script>
import { mapState } from 'vuex'
export default {
  name: 'Son2Com',
  computed: {
    ...mapState(['count'])
  }
}
</script>

<style lang="css" scoped>
.box {
    border: 3px solid #ccc;
    width: 400px;
    padding: 10px;
    margin: 20px;
}
h2 {
    margin-top: 10px;
}
</style>


http://www.kler.cn/a/393610.html

相关文章:

  • 阿里云centos7.9服务器磁盘挂载,切换服务路径
  • win11 新建一个批处理,双击查看本机的IP地址
  • 力扣104 : 二叉树最大深度
  • Axure网络短剧APP端原型图,竖屏微剧视频模版40页
  • JS 实现SSE通讯和了解SSE通讯
  • ML 系列: 第 23 节 — 离散概率分布 (多项式分布)
  • 数据结构练习题和答案
  • 想要监控办公电脑,好用的监控软件怎么选择
  • cache中block(cache line)和frame概念
  • python各种方法总结
  • 【Linux】ISCSI实验
  • 使用git安装Django-micro,limit使用
  • Mysql 5.7.6以上版本怎样关闭GTID(由GTID改为基于file,position方式)
  • python习题练习
  • WebGIS四大地图框架:Leaflet、OpenLayers、Mapbox、Cesium
  • 【插件】多断言 插件pytest-assume
  • 2024年8个最佳在线websocket调试工具选择
  • 30.超市管理系统(基于springboot和Vue的Java项目)
  • Android 13.0 framework系统修改安兔兔等显示的屏幕尺寸大小功能实现
  • 集群架构中Lua脚本的限制以及出现的报错
  • N种方式解决
  • 计算机图形学论文 | 木工设计与制造计划的共同优化
  • 计算机毕业设计——ssm基于JAVA的求职招聘网站的设计与实现演示录像 2021
  • LeetCode【0009】回文数
  • 微信小程序=》基础=》常见问题=》性能总结
  • 期货配资系统行情源对接通讯协议范本