Vuex基础
- Vuex概述
- Vuex基本使用
- 使用Vuex完成todo案例
小范围内的数据共享
组件之间共享数据的方式
- 父向子传值:v-bind 属性绑定
- 子向父传值:v-on 事件绑定
- 兄弟组件之间共享数据: EventBus
数据接收方通过 on 自定义接收事件 接收数据的那个组件 数据发送方通过 emit 发送数据 发送数据的那个组件
以上只适合,如果需要大范围的进行数据共享使用vuex
Vuex概述
Vuex的基本使用
安装 vuex 依赖包:
npm install vuex --save
在store.js文件中
// 导入 vuex 包 import Vuex from 'vuex' // 注册vuex Vue.use(Vuex) // 创建 store 对象,将 store 对象挂载到 vue 实例中 const store = new Vuex.Store({ // state 中存放的就是全局共享的数据 state: { count: 0 } })
项目实际操作步骤:
创建带有vuex的vue项目,在任意窗口打开终端,输入命令:vue ui
当项目仪表盘打开之后,我们点击页面左上角的项目管理下拉列表,再点击Vue项目管理器
点击创建项目,如下图所示 第一步,设置项目名称和包管理器 (图片省略…)
第二步,设置手动配置项目,在main.js中
new Vue({ el: '#app', render: h => h(app), render渲染app根组件 router, // 将创建的共享数据对象,挂载到 Vue 实例中 // 所有的组件,就可以直接从 store 中获取全局的数据了 store })
第三步,设置功能项
第四步,创建项目
使用Vuex完成计数器案例
打开刚刚创建的vuex项目,找到src目录中的App.vue组件,将代码重新编写如下:
<template> <div> <my-addition></my-addition> <p>----第四步:以标签的形式,进行使用注册的组件----</p> <my-subtraction></my-subtraction> </div> </template> <script> // 第二步:导入创建的组件 import Addition from './components/Addition.vue' import Subtraction from './components/Subtraction.vue' export default { data() { return {} }, // 第三步:将创建的组件注册为App的子组件 components: { 'my-subtraction': Subtraction, 'my-addition': Addition } } </script> <style> </style>
第一步:在components文件夹中创建Addition.vue组件,代码如下:
<template> <div> <h3>当前最新的count值为:</h3> <button>+1</button> </div> </template> <script> export default { data() { return {} } } </script> <style> </style>
第一步:在components文件夹中创建Subtraction.vue组件,代码如下:
<template> <div> <h3>当前最新的count值为:</h3> <button>-1</button> </div> </template> <script> export default { data() { return {} } } </script> <style> </style>
最后在项目根目录(与src平级)中创建 .prettierrc 文件,编写代码如下:
{ "semi":false, *不使用分号* "singleQuote":true *将双引号更改为单引号* }
Vuex 中的主要核心概念如下:
dispatch函数 => 触发 actions 中定义的函数
commit函数 => 触发 mutation 中定义的函数
总结:操作state、mutation、action、getter;推荐使用第二种方式
- state 和 getter 映射为当前组件的计算属性
- mutation 和 action 映射为当前组件的methods方法
注意事项:
只有mutations中定义的函数,才有权利修改state中的数据
在actions中定义的函数,只有处理异步操作的功能,不能直接修改state中的数据
必须通过 context.commit() 触发mutations定义的函数才行,
让mutations定义的函数,协助actions中定义的函数来修改state里面的数据调用 this.$store.dispatch() 触发 actions 中的某个函数
在项目根目录的store.js中
注意:
mutations actions getters 它们都是以s结尾的
因为我们可以有很多个 mutation/action/getter 函数。
const store = new Vuex.Store({ state: { count: 0 }, mutations: { }, actions: { }, getters: { } })
State
State 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 State 中进行存储。
// 在项目根目录的store.js中:创建store数据源,提供唯一公共数据 const store = new Vuex.Store({ state: { count: 0 } })
组件访问 State 中数据的第一种方式:
this.$store.state.全局数据名称
在Addition.vue组件中:
在template中this可以省略
<template> <div> <h3>当前最新的count值为:{{$store.state.count}}</h3> <button>+1</button> </div> </template>
组件访问 State 中数据的第二种方式: (推荐使用)
通过刚才导入的 mapState 函数,将当前组件需要的全局数据,映射为当前组件的 computed 计算属性:
// 1. 从 vuex 中按需导入 mapState 函数 import { mapState } from 'vuex' // 2. 将全局数据,映射为当前组件的计算属性 computed: { ...mapState(['count']) }
.在Subtraction.vue组件中:
<template> <div> <h3>当前最新的count值为:{{count}}</h3> *第三步:使用计算属性* <button>-1</button> </div> </template> <script> // 第一步:从 vuex 中按需导入 mapState 函数 import { mapState } from 'vuex' export default { data() { return {} }, // 第二步:将全局数据,映射为当前组件的计算属性 computed: { ...mapState(['count']) } } </script>
Mutation和Action
Mutation 用于变更 Store中 的数据。
- 只能通过 mutation 变更 Store 数据,不可以直接操作 Store中的数据。
- 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化
在store.js中:定义 Mutation
const store = new Vuex.Store({ state: { count: 0 }, mutations: { // 参数state就是store中的state对象 add(state) { // 变更状态 state.count++ } } })
在Addition.vue组件中:
// 触发mutation methods: { handle1() { // 触发 mutations 的第一种方式 this.$store.commit('add') } }
可以在触发 mutations 时传递参数:
在store.js中:定义Mutation
const store = new Vuex.Store({ state: { count: 0 }, mutations: { addN(state, step) { //第一个形参永远都是state也就是$state对象 //第二个形参是调用addN时传递的参数 state.count += step } } })
在Addition.vue组件中:commit 的作用:就是调用某个mutation 函数
// 触发mutation methods: { handle2() { // 在调用 commit 函数, // 触发 mutations 时携带参数 this.$store.commit('addN', 3) } }
this.$store.commit() 是触发 mutations 的第一种方式,触发 mutations 的第二种方式:
// 1. 从 vuex 中按需导入 mapMutations 函数 import { mapMutations } from 'vuex'
通过刚才导入的 mapMutations 函数,将需要的 mutations 函数,映射为当前组件的 methods 方法:
// 2. 将指定的 mutations 函数,映射为当前组件的 methods 函数 methods: { ...mapMutations(['add', 'addN']) }
使用mutations的第二种方式: (推荐使用) 如下:
在store.js中:定义Mutation
- 第一步:在Mutations对象中,新增sub函数
- 第一个形参永远都是state也就是$state对象
- 第二个形参是调用addN时传递的参数
注意:
在mutations中不能编写异步的代码,会导致vue调试器的显示出错。
在vuex中我们可以使用Action来执行异步操作。如果通过异步操作变更数据,必须通过 Action,
而不能使用 Mutation,但是在 Action 中还是要通过触发 Mutation 的方式间接变更数据 。
const store = new Vuex.Store({ state: { count: 0 }, mutations: { sub(state, step) { state.count -= step } } })
在Subtraction.vue组件中
- 第二步:导入mapMutations
- 第三步:获得mapMutations映射的sub函数
- 第四步:为按钮绑定事件
注意:
- 在mutations中不能编写异步的代码,会导致vue调试器的显示出错。
- 在vuex中我们可以使用Action来执行异步操作。如果通过异步操作变更数据,必须通过 Action,而不能使用 Mutation,但是在 Action 中还是要通过触发 Mutation 的方式间接变更数据 。
<button @click="sub(1)">-1</button> import { mapState,mapMutations } from 'vuex' export default { data() { return {} }, computed:{ ...mapState(['count']) }, methods:{ ...mapMutations(['sub']) } }
在Addition.vue组件中:
- 第一步:为按钮绑定事件
- 第二步:在methods方法中,定义 btnHandle3
- 第四步:调用 this.$store.dispatch()
<button @click="btnHandle3">-1 ASync</button> // 触发 Action methods: { btnHandle3() { // 触发 actions 的第一种方式:异步地让count自增加1 this.$store.dispatch('addAsync') } }
在store.js中:定义 Action
注意:只有mutations中定义的函数,才有权利修改state中的数据
// 第三步:定义 Action const store = new Vuex.Store({ state: { count: 0 }, mutations: { add(state) { state.count++ } }, actions: { addAsync(context) { setTimeout(() => { context.commit('add') }, 1000) } } })
触发 actions 异步任务时携带参数:.在Addition.vue组件中
<button @click="btnHandle4">+N ASync</button> // 触发 Action methods: { btnHandle4() { // 在调用 dispatch 函数,触发 actions 时携带参数 this.$store.dispatch('addNAsync', 5) } }
在store.js中:定义 Action
// 定义 Action const store = new Vuex.Store({ state: { count: 0 }, mutations: { addN(state, step) { state.count += step } }, actions: { addNAsync(context, step) { setTimeout(() => { context.commit('addN', step) }, 1000) } } })
this.$store.dispatch() 是触发 actions 的第一种方式,触发 actions 的第二种方式:
// 1. 从 vuex 中按需导入 mapActions 函数 import { mapActions } from 'vuex'
通过刚才导入的 mapActions 函数,将需要的 actions 函数,映射为当前组件的 methods 方法:
// 2. 将指定的 actions 函数,映射为当前组件的 methods 函数 methods: { ...mapActions(['addASync', 'addNASync']) }
项目具体实现步骤: 实现异步减N
在Subtraction.vue组件中:
<button @click="subAsync(1)">-1 ASync</button> <script> // 第一步:从 vuex 中按需导入 mapActions 函数 import { mapActions } from 'vuex' export default { // 第二步:映射为当前组件的methods方法 methods: { ...mapActions(['subAsync']) } } </script>
在store.js中:定义 Action
// 定义 Action const store = new Vuex.Store({ state: { count: 0 }, // 第四步 mutations: { sub(state,step) { state.count -= step } }, // 第三步 actions: { subAsync(context,step) { setTimeout(() => { context.commit('sub',step) }, 1000) } } })
Getter
Getter用于对Store中的数据进行加工处理形成新的数据,它只会包装Store中保存的数据,
并不会修改Store中保存的数据,当Store中的数据发生变化时,Getter生成的内容也会随之变化。
- Getter 可以对 Store 中已有的数据加工处理之后形成新的数据,类似 Vue 的计算属性。
- Store 中数据发生变化,Getter 的数据也会跟着变化。
在store.js中
// 定义 Getter const store = new Vuex.Store({ state: { count: 0 }, getters: { // showNum 的第一个参数,就是state 对象 showNum: state => { return '当前最新的数量是【 '+ state.count +'】 ' } } })
使用 getters 的第一种方式:
this.$store.getters.名称
使用 getters 的第二种方式:.在Subtraction.vue组件中
import { mapGetters } from 'vuex' // 然后直接在页面{{showNum}}进行使用即可 computed: { ...mapGetters(['showNum']) }