// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue';
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
import eventBus from '@/utils/eventBus';
import { store } from '@/store/index';
import App from './App';
import router from './router';
Vue.config.productionTip = false;
Vue.use(Antd);
/* eslint-disable no-new */
Vue.prototype.$my_event = new eventBus();
new Vue({
el: '#app',
store,
router,
components: { App },
template: '<App/>'
});
本文是笔者总结过往项目,在
vue
使用到的一些数据通信方案,希望在实际项目中有些帮助和思考。正文开始...
我们先看下在
vue
中我能想到的数据通信方案1、
props
父传子2、自定义事件
@event="query"
3、
.sync
修饰符3、
vuex
跨组件通信4、
Vue.observable
5、
provide/inject
6、
EventBus
7、
$refs
、$parent
基于以上几点,笔者用一个实际的
todolist
来举证所有的通信方式props 父组件传递子组件数据的接口通信
父组件以
Index.vue
为例,传入的子组件Content.vue
的props
就是:dataList="dataList"
在Content.vue
中我们可以看到就是通过props
上的dataList
获取父组件数据的。子组件数据通过父组件传递,页面数据就显示出来了
自定义事件 emit 通信
我们看到在父组件中加入了
@handleAdd
自定义事件在
Search.vue
中我们引入对应逻辑我们可以看到
自定义事件
子组件中就是这么给父组件通信的.sync 实现 props 的双向数据通信
在 vue 中提供了
.sync
修饰符,本质上就是便捷处理props
单向数据流,因为有时候我们想直接在子组件中修改props
,但是vue
中是会警告的,如果实现props
类似的双向数据绑定,那么可以借用.sync修饰符
,这点项目里设计弹框时经常有用。同样是上面
todolist
的例子我们在看下
Search.vue
已经通过:dataList.sync="dataList"
在props
上加了修饰符了在
Search.vue
中可以看到注意我们在
handleAdd
方法中修改了我们是用以下这种方式去与父组件通信的,this.$emit('update:dataList', dataList.concat(item))
。sync
本质也是利用自定义事件通信,上面代码就是下面的简版,我们可以利用.sync
修饰符实现props
的双向数据绑定,因此在实际项目中可以用.sync
修饰符简化业务代码,实际与下面代码等价vuex
vuex
在具体业务中基本上都有用,我们看下vuex
是如何实现数据通信的,关于vuex
如何使用参考官方文档,这里不讲如何使用 vuex,贴上关键代码然后在
main.js
中引入我们看下主页面路由页面,现在变成这样了,父组件没有任何
props
与自定义事件
,非常的干净。然后看下
Search.vue
与Content.vue
组件你会发现操作数据是用
$store.commit('mutationName', data)
这个vuex
提供的同步操作去修改数据的。 在Content.vue
中就是直接从store
中获取state
就行了vuex
的思想就是数据存储的一个仓库,数据共享,本质 store 也是一个单例模式,所有的状态数据以及事件挂载根实例上,然后所有组件都能访问和操作,但是貌似这么简单的功能引入一个状态管理工具
貌似有点杀鸡用牛刀了,接下来我们用官方提供的跨组件方案。Vue.observable
vue 提供一个这样的一个最小跨组件通信方案,我们具体来看下,新建一个目录
todoList-obsever/store/index.js
,我们会借鉴vuex
的一些思想,具体代码如下然后在
Content.vue
中在
Search.vue
中ok 这种方式算是代替
vuex
的一种解决方案,是不是比vuex
更简单呢,而且不用引入任何第三方库,因此在你的业务代码中可以用此来优化部分跨组件的数据通信。provide / inject
这是一个父组件可以向子孙组件透传数据的一个属性,也就是意味着在所有子孙组件,能拿到父组件
provide
提供的数据,具体可以看下下面例子我们在
Content.vue
组件中发现子组件就用
inject: ['newDataList']
来接收数据了。注意一点inject
一定是要与provide
组合使用,且必须是在父子组件,或者父孙,或者更深层的子组件中使用inject
。EventBus 总线事件
这种方式平时业务上也会有用得到,特别是在表单验证中就会有
在
mian.js
中挂载到prototype
上然后在具体路由上我们看下
在
Search.vue
中我们可以看到,我们是用this.$my_event.emit
去触发事件的$parent
或者$refs
访问父组件或者调用子组件方法这是项目中比较常用粗暴的手段,用一段伪代码感受下就行,不太建议项目里用 this.$parent 操作
在
Search.vue
组件中也能调用父组件的方法最后把这个
todo list demo
完整的完善了一下,点击路由可以切换不同todolist
了总结
1、用具体实例手撸一个
todolist
把所有vue
中涵盖的通信方式props
,自定义事件
、vuex
、vue.observable
、provide/inject
、eventBus
实践了一遍2、明白
vuex
的本质,实现Vue.observable
跨组件通信3、了解事件总线的实现方式,在
vue
中可以使用$emit
与$on
方式实现事件总线4、本文代码示例:code example