1.组件间共享数据的方式
父向子传值:v-bind属性绑定
子向父传值:v-on事件绑定
兄弟组件间数据共享:EventBus
- $on接收数据的组件
- $emit发送数据的组件
2.什么是vuex
vuex是实现组件全局状态(数据)管理的一种机制,可以方便实现组件之间数据的共享。
在不使用Vuex的情况下,组件间的数据传递呈链条结构:父组件==>子组件==>孙组件,孙组件想要拿到父组件的数据,必须通过子组件。可以看出,如果子组件的层度更深,数据将更难传递。
在使用Vuex后,组件可以直接调用共享的数据stroe,不需要层层递进。
3. Vuex的作用
3.1 使用Vuex统一管理状态的好处:
1.能够在Vuex中集中管理共享的数据,易于开发和维护
- 能够高效的实现组件之间的数据共享,提高开发效率
- 存储在Vuex中的数据都是响应式的,能够实时保存数据与页面同步
3.2 什么样的数据适合存储到Vuex中
一般情况下,只有组件之间共享的数据,才有必要存储到Vuex中,对于组件私有的数据,依旧存储到自身的data中。
4. Vuex的基本使用
1.安装Vuex依赖包
npm install vuex --save
- 导入vuex包
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
- 创建store对象
const store = new Vuex.Store({
state: { count: 0 }
})
- 将store对象挂载到vue实例中
new Vue({
el: '#app',
store,
router,
render: h => h(app)
})
5. Vuex的核心概念
- State
- Mutation
- Action
- Getter
5.1 State
State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中进行存储。
const store = new Vuex.Store({
state: { count : 0 }
})
组件访问State中数据的第一种方式
this.$store.state.count(全局数据名)
组件访问State中的数据的第二种方式
// 1. 从vuex中按需导入mapState函数
import { mapState } from ’vuex‘
// 2. 将全局数据,映射为当前组件的计算属性
computed: {
...mapState(['count'])
}
5.2 Mutation
5.2.1 Mutaiton用于变更store中的数据
- Store中的数据只能通过mutation变更,不可以直接操作Store中的数据
- 通过这种方式虽然操作起来有些繁琐,但是可以集中监控所有数据的变化
- mutation中不能使用异步操作
5.2.2 使用mutation的第一种方式
// 1. 首先在store中的mutations中定义一个函数
mutations: {
add(state) {
state.count++
}
}
// 2. 在组件通过commit调用add函数
this.$store.commit('add')
5.2.3 mutation传递参数
// 1. 首先在Store中定义一个mutation函数
mutations: {
add2(state, step) {
state.count += step
}
}
// 2. 在组件中调用函数并传入参数
methods: {
handler() {
this.$store.commit('add2', 5)
}
}
5.2.4 触发mutation的第二种方式
// 1.从vuex中按需导入mapMutations函数
import { mapMutations } from 'vuex'
// 2. 通过mapMutations函数,将需要的mutations函数映射为当前组件的methods方法。
methods: {
...mapMUtations(['add', 'add2'])
}
// 传参
methods: {
...mapMUtations(['add', 'add2'])
handler() {
this.add2(5)
}
}
5.3 Action
- Action用于处理异步任务。
- 如果通过异步操作变更数据,必须通过Action,而不是使用Action,但是在Action中还是要通过Mutation的方式间接变更数据。
5.3.1 使用Action的第一种方式
// 1.定义Action
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
add(state) {
state.count++
}
},
actions: {
addAsync(context) {
setTimeout( () => {
context.commit('add')
}, 1000)
}
}
})
// 2. 触发Action
methods: {
handler() {
this.$store.dispatch('addAsync')
}
}
// 触发actions异步任务时携带参数
actions: {
addAsync(context, step) {
setTimeout( () => {
context.commit('add', step)
}, 1000)
}
}
5.3.2 触发actions的第二种方式
// 1. 从vuex中按需导入mapMutations函数
import { mapActions } from ‘vuex’
// 2. 将指定的actions函数,映射为当前组件的methods函数
methods: {
...mapActions(['add', 'add2'])
}
5.4 Getter
Getter用于对Store中的数据进行加工处理形成新的数据,不会改变state的的数据,起到包装数据的作用。
- Getter类似于vue的计算属性
- Store中的数据发生变化,getter的数据也会跟着变化
// 1. 定义getters
const store = new Vuex.Store({
state:{
count: 0
},
getters: {
showNum: state => {
return '当前最新的数量是【'+state.count + '】'
}
}
})
// 2.使用getter的第一种方式
this.$store.getters.showNum
// 3. 使用getters的第二种方式
import { mapGetters } from 'vue'
computed: {
...mapGetters(['showNum'])
}
6. module模块化和命名空间
6.1 module模块化
由于使用单一状态数,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就有可能编的非常臃肿。
为了解决以上问题,Vuex允许我们将store分割成module。每个模块拥有自己的state、mutation、action、getter、甚至时嵌套模块,将之上而下进行同样方式的分割,如下:
const moduleA = {
state: {},
mutations: {},
actions: {},
getters: {}
}
const moduleB = {
state: {},
mutations: {},
actions: {},
getters: {}
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
$store.state.a // -> moduleA的状态
$store.state.b //-> moduleB的状态
6.2 命名空间
默认情况下,模块内部的action、mutation和getter是注册在全局命名空间的,这样使得多个模块能够对统一mutation或在才提哦那作出响应。如果希望模块有更高的封装度和复用性,可以通过添加namespaced:true的方式使其成为带命名空间的模块。当模块被注册后,它所有getter、action以及mutation都会自动根据模块注册的路径调整命名。
const moduleA = {
namespaced: true, // 开启命名空间
state: {},
mutations: {},
actions: {},
getters: {}
}
网友评论