前言
本文假设读者已经了解vue的基础语法,能够使用vue编写出简单的页面
Vue 组件间的通信
为了更全面认知我们来回顾一下以下内容。在Vue组件的世界里,数据传递分三种情况:
-
父组件给子组件传递数据, 使用
props
选项声明接收,可以是对象(带校验),也可以是数组. -
子组件给父组件传递数据, 使用
$emit()
方法触发事件携带参数,父组件使用$on
监听获取. 还有一种办法是 使用语法糖v-model
,在父组件写法上感觉就像普通的一个双向数据绑定方案,不同的是写在组件上而不是写在input
控件上.子组件上依旧使用$emit('input', 要传递的数据对象)
-
非父子组件通信, 怎么办? 很慌?
$dispatch()
派发?,$broadcast
广播? 中央事物总线bus
? 别急,还有个更好用的Vuex
关于非父子组件的通信,也就是跨级组件和兄弟组件通信时,vue1.x中采用$dispatch
和$broadcast
这两种办法,在vue2.x中已经被废弃。取而代之的就是采用中央事物总线bus
的办法,步骤如下
- 创建一个空的vue实例
bus
,var bus = new vue()
,里面没有任何内容 - 定义一个全局的组件
component-a
,假设这个组件就是我们要的跨级组件。当该组件中有数据更新,需要通知源组件时,使用bus.$emit('自定义事件名', ‘要传递的参数对象’)
触发 - 在2中提到的源组件我们假设就是
app
中,在mounted
时使用bus.$on('emit发起的事件名', function(param){ })
来监听并获取到数据param
Vuex 能解决什么
理论上我们使用纯vue就能解决所有的组件通信问题。但这也只是“理论上”,在大型的单页面SPA项目中,因为数据状态相对复杂,我们希望有更方便,更容易理解的办法操作和管理非父子组件的通信数据,更容易维护整个项目的组件状态,而Vuex就是用来处理这个问题的。
![](https://img.haomeiwen.com/i8646214/1e99cdfbd72b2960.png)
在项目中使用Vuex
安装: npm install --save vuex
导入: import Vuex from 'vuex'
使用vuex: Vue.use(Vuex)
创建仓库store, 配置vue信息:
const store = new Vuex.Store({
// vuex 的配置信息
})
使用配置:
new Vue({
el: '#app',
router: router,
// 使用vuex
store: store,
component: {app},
tmeplate: '<app/>'
})
仓库 store
包含了应用的数据(状态)和操作过程。Vuex里的数据都是响应式的,任何组件使用同一store
时,只要store
的数据发生了变化,对应的组件也会立即更新。
Vuex 怎么用
vuex这么强,那它怎么用?数据状态管理如何实现?
| 搭好vuex框架
接下来为了提高学习效率,我们采用总分形式直接入手实例,假设有store.js如下
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import request from './module/request'
import nav from './module/nav'
import breadcrumb from './module/breadcrumb'
let store = new Vuex.Store({
modules: {
request,
nav,
breadcrumb
}
});
export default store;
在代码中可以看到创建了一个仓库store
,而配置信息是一个modules
,它的值是从其他文件导入的,什么意思?其实这只是vuex更加规范的管理每一种类型或功能数据状态的规范而已。如案例中有三种,request
用于管理异步请求的数据状态,nav
用于管理导航信息的数据状态,breadcrumb
用于管理面包屑的数据状态。这就是vuex中module
选项的用法。
| 配置一个真正的vuex文件
分好数据类型之后,我们开始配置一个真正的vuex配置信息,假设在./module/breadcrumb.js
中有如下配置
export default {
// state选项用来存放 仓库中各组件托管的数据状态
state: {
message: 'store源数据',
list: [3, 8, 13, 24, 5]
},
// mutations选项定义组件中更新数据的方法
// 组件只能通过这种办法修改state中的数据
mutations: {
// 参数state就是上一个选项state,第二个是组件中传递过来要更新的数据
changeMes (state, val) {
state.message = val
},
resetMes (state, val) {
state.message = val
}
},
// 仓库中统一进行数据处理的地方,功能类似组件中的computed
getters: {
listLength: (state, getters) => {
return getters.filteredList.length
}
},
// actions实现异步修改数据,不能用mutation实现(数据不能及时更新)
actions: {
actionMesAsyn (context) {
return new Promise(resolve => {
setTimeout(() => {
context.commit('changeMes', msg)
resolve()
}, 2000)
})
}
}
}
如案例中所诉,一个仓库可以有一下几个选项
- state选项: 用来存放 仓库中各组件托管的数据状态
-
mutations选项: 定义组件中更新数据的方法,在组件中,只能通过这种办法修改
state
中的数据,而不能直接调用state
修改,仓库的数据流动书单向传递的 -
getters:选项: 仓库中统一进行数据处理的地方,功能类似组件中的
computed
-
actions选项: 如果修改数据的操作是异步的,不能使用
mutations
,必须使用actions
,否者会出现更新不及时的问题
| 在页面中访问vuex数据
到目前位置我们已经配置好一个vuex了, 在任何组件,通过调用$store
来访问状态信息。如果没有使用module
,在组件通常在计算属性中使用
computed: {
storeData: this.$store.state.list
}
如果使用了module
,则需要加模块名如本例中的breadcrumb
this.$store.state.breadcrumb.list
对于getters
中处理过的数据状态,使用
this.$store.getters.filterList
对于mutations
中的方法,在组件中使用commit
来触发事件
this.$store.commit('increment', 5)
网友评论