Vuex从0到1入门
组件之间的数据共享方式
父向子传值
原理: 使用v-bind属性绑定。
在子组件中定义节点props,在props中使用数组的方式指定要从父组件中床过来的值的名称。
在父组件的子组件标签上,通过静态传值或者v-bind动态绑定的方式指定与子组件props中同名的属性并传值。
注意:
- 在porps中的属性名称需要使用驼峰式命名,在template中使用短横线命名。
- 向子组件传入
class和style不会替换子组件模板中原先的class和style,而是会合并。
子向父传值
原理:使用v-on事件绑定。
在父组件的子组件标签上使用v-on绑定自定义的事件。使用$event接收传过来的值。
在子组件中使用$emit('自定义事件名称' , 值)的方式触发自定义事件进行传值。
注意:
v-on绑定的事件不能是驼峰命名,因为它会自动转换为全小写。
兄弟组件传值
原理:使用EventBus事件中心进行管理。
单独创建一个全局的Vue实例,在要通信的组件中调用它的$on监听事件,调用$emit触发事件,$off销毁事件。
缺点:在大型项目中容易造成维护困难。
Vuex
Vuex用于实现数据(状态共享),适用于大范围的数据共享,它具有以下优点:
- 集中管理数据,易于维护。
- 高效的数据共享。
- 响应式数据,实时保持数据和页面的同步。
其他状态管理工具还有:Flux、Redux等。
Vuex基本使用
1、安装
npm install vuex --save
2、导入并使用
import Vuex from 'vuex'
Vue.use(Vuex)
3、创建store对象
Vuex.store({
state: { count: 0 } // state对象中存放要共享的数据
})
在vue实例中可以通过this.$store访问到store对象。
4、将store对象挂载到Vue实例上
new Vue({
store,
render: h => h(App)
}).$mount('#app')
State
在Vuex中,state属性节点用于存放数据,它的值是一个对象,对象中的每一个属性就是相应的数据。
例如有如下state节点:
state: {
count: 0,
foo: 1,
bar: [1,2,3]
}
访问方式一:this.$store.state
在vue组件中的计算属性节点中访问count:
computed: {
count(){
return this.$store.state.count
},
bar(){
return this.$store.state.bar
}
}
访问方式二:mapState辅助函数
首先在vue组件中导入该函数,mapState函数可以接收一个对象,并返回一个对象,因此可以直接将这个对象赋值给computed属性。
import { mapState } from 'vuex'
-------------------------------------------
computed: mapState({
count: 'count' // 这里的'count'就是state节点中的count
valueOfFoo: state => state.foo // 可以使用箭头函数
countPlus(state){ return state.count++ }
})
如果组件本身就有自己局部的计算属性,可以使用对象展开运算符解构mapState返回的对象,当mapState的参数对象中的属性名和属性值相同时,可以直接传入一个数组来代替该对象。
computed: {
...mapState(['count' , 'foo' , 'bar']),
// 组件自己的计算属性
...
}
Mutations
store对象中的mutations节点专门用于操作修改state中的对象。更改vuex中的store中的state的唯一方式就是提交mutations。
首先在store对象中定义mutations:
mutations: {
addCount(state , param){ // 第一个参数都为当前store对象的state , 第二个参数为单一的值或者对象
state.count += param.step // 修改state中的count值
}
}
在组件中提交mutations有两种方式,并且在提交时可以传入参数(负载),当参数多时应当以一个对象的形式传入。
方式一:this.$store.commit(type)
// 第一个参数是mutations中对应的函数名,也叫类型,第二个是要传入的参数
this.$store.commit('addCount' , { step: 1 })
// 或
this.$store.commit('addCount' , 1)
方式二:mapMutations
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
}
注意:mutations中函数操作只能是同步的,异步操作需要使用actions
Actions
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
actions: {
increment ( context ) {
setTimeout(() => {
context.commit('increment')
}, 1000)
}
// 或
increment ({ commit }){
setTimeout(() => {
commit('increment')
}, 1000)
}
}
在组件中分发actions的方式有两种
方式一:this.$store.dispatch()
this.$store.dispatch('increment')
方式二:使用mapActions
使用mapActions将actions中的方法映射为组件methods中的方法
import { mapActions } from 'vuex'
methods: {
mapActions(['increment'])
}
Getters
Getters不修改state,在它里面定义的方法可以包装或加工state中的数据之后返回。
doneTodos: (state) => { // 第一个参数是state
return state.todos.filter(todo => todo.done)
}
在组件中的使用方式和state一样。
this.$store.getters.doneTodos
import { mapGetters } from 'vuex'
computed: {
...mapGetters(['doneTodos'])
}
最后还有一个模块(Module)的概念,下次再将啦!
175

被折叠的 条评论
为什么被折叠?



