博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vue父、子、孙组件间数据传递、事件传递
阅读量:6857 次
发布时间:2019-06-26

本文共 8389 字,大约阅读时间需要 27 分钟。

怎么实现父子组件的数据传递、事件传递,有哪几种方式

一、父获取子组件数据事件可以通过下面几种方式:

1、通过给子组件绑定ref属性,获取子组件实例2、通过this.$children获取子组件实例3、通过vuex完成父子组件数据事件通信复制代码

二、子获取父组件数据事件可以通过下面几种方式:

1、通过props传递父组件数据、事件, 或者通过$emit和$on实现事件传递2、通过ref属性,调用子组件方法,传递数据;通过props传递父组件数据、事件, 或者通过$emit和$on实现事件传递3、通过this.$parent.$data或者this.$parevent._data获取父组件数据;通过this.$parent执行父组件方法4、通过vuex完成父子组件数据事件通信复制代码
我是父组件内容,我有一个子组件名字叫{
{childName1}},这是通过ref获取的内容;
我是父组件内容,我有一个子组件名字叫{
{childName2}},这是通过children获取的内容;
复制代码
复制代码

怎么实现兄弟组件之间的数据传递、事件传递,有哪几种方式

1、利用Vuex存储数据, 配合父组件watch进行事件监听2、利用bus中央开关总线,挂载全局事件3、利用$parent进去数据传递, $parent.$children调用兄弟组件事件复制代码
复制代码
复制代码

怎么实现祖孙组件之间的数据传递、事件传递,有哪几种方式

1、利用$attrs实现祖孙组件间的数据传递,$listeners实现祖孙组件间的事件监听 $attrs包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。$listeners包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。2、利用provide/inject 实现祖孙组件间的数据传递和事件监听provide 和 inject 主要为高阶插件/组件库提供用例,允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。3、利用vuex传递存储数据,利用$parent、$children封装一套可向下广播事件,向上派发事件的方法;复制代码

第一种实现方式

显示弹层(第一种方式)
复制代码
// 弹层组件(子组件的子组件)var alert = {    template: ` 

{
{title}}

{
{con}}
`, data() { return { } }, props: ['title', 'con'], methods: { submit() { this.$emit('on-submit') } }};// mask组件(子组件)var myMask = { template: `
`, components: { alert }, inheritAttrs: false, data() { return { } }, props: ['show'], methods: { }, watch: { }};export default { name: 'my-page', components: { myMask, }, data() { return {} }, isShow: false, title: '我是标题', con: '我是内容', }; }, methods: { submit() { window.alert('关闭弹层'); this.isShow = false; }, }}复制代码

祖组件在传递数据给子组件的时候,如果子组件没有通过props接收祖组件传递的参数,那么这个数据会表现在子组件的根标签的属性上;通过设置 inheritAttrs 到 false,这些默认行为将会被去掉; 然后我们可以在子组件绑定v-bind="attrs",将这些特性传递给孙组件,孙组件通过props接收数据; 同理我们也可以通过listeners实现祖孙之间的事件监听器传递

第二种实现方式

切换显示内容(第二种方式)
复制代码
var myTable = {    template: `
{
{item.value}}
`, data() { return { tableType: 0, list: [{
value: '新闻', type: 0}, {
value: '汽车', type: 1}, {
value: '娱乐', type: 2}] } }, inject: ['store'], methods: { switchType(value) { this.store.commit('type', value) } }};var myList = { template: `
{
{item}}
`, data() { return { listType: 0, listInfo: { 0: ['新闻1', '新闻2', '新闻3'], 1: ['汽车1', '汽车2', '汽车3'], 2: ['娱乐1', '娱乐2', '娱乐3'] } } }, inject: ['store'], props: [], methods: { }, mounted() { }};var myCon = { template: `
`, data() { return { } }, components: { myTable, myList, mySearch }, props: [], methods: { }, mounted() { }};export default { name: 'my-page', components: { myCon, }, provide() { return { store: this.store } }, data() { return { store: { state: { type: 0 }, commit (type, value) { this.state[type] = value } }, }; }, methods: { changeCon() { this.store.state.type ++; if(this.store.state.type > 2) this.store.state.type = 0; }, }, mounted() { }}复制代码

第三种实现方式(来自饿了么UI之前源码)

请输入内容
复制代码
var myCon = {    template: `
`, data() { return { } }, components: { myTable, myList, mySearch }, props: [], methods: { }, mounted() { }};var mySearch = { name: 'mySearch', template: `

{

{content}}

`, data() { return { content: '没有搜索内容' } }, props: [], methods: { /*对多级父组件进行事件派发*/ dispatch(componentName, eventName, params) { /*获取父组件,如果以及是根组件,则是$root*/ var parent = this.$parent || this.$root; /*获取父节点的组件名*/ var name = parent.$options.name; while (parent && (!name || name !== componentName)) { /*当父组件不是所需组件时继续向上寻找*/ parent = parent.$parent; if (parent) { name = parent.$options.name; } } /*找到所需组件后调用$emit触发当前事件*/ if (parent) { parent.$emit.apply(parent, [eventName].concat(params)); } }, }, mounted() { this.$on('on-input', (value) => { this.content = value; if(value == '') { this.content = '没有搜索内容'; this.dispatch('my-page', 'no-data', false); } }) }};function broadcast(componentName, eventName, params) { /*遍历当前节点下的所有子组件*/ this.$children.forEach(child => { /*获取子组件名称*/ var name = child.$options.name; if (name === componentName) { /*如果是我们需要广播到的子组件的时候调用$emit触发所需事件,在子组件中用$on监听*/ child.$emit.apply(child, [eventName].concat(params)); } else { /*非所需子组件则递归遍历深层次子组件*/ broadcast.apply(child, [componentName, eventName].concat([params])); } });}export default { name: 'my-page', components: { myMask, myCon, }, provide() { return { store: this.store } }, data() { return { store: { state: { type: 0 }, commit (type, value) { this.state[type] = value } }, isShow: false, title: '我是标题', con: '我是内容', hasSearch: false }; }, methods: { submit() { window.alert('关闭弹层'); this.isShow = false; }, changeCon() { this.store.state.type ++; if(this.store.state.type > 2) this.store.state.type = 0; }, changInput(e) { if(e.target.value) { this.hasSearch = true; } this.broadcast('mySearch', 'on-input', e.target.value) }, /*对多级父组件进行事件派发*/ dispatch(componentName, eventName, params) { /*获取父组件,如果以及是根组件,则是$root*/ var parent = this.$parent || this.$root; /*获取父节点的组件名*/ var name = parent.$options.name; while (parent && (!name || name !== componentName)) { /*当父组件不是所需组件时继续向上寻找*/ parent = parent.$parent; if (parent) { name = parent.$options.name; } } /*找到所需组件后调用$emit触发当前事件*/ if (parent) { parent.$emit.apply(parent, [eventName].concat(params)); } }, broadcast(componentName, eventName, params) { broadcast.call(this, componentName, eventName, params); } }, mounted() { this.$on('no-data', (value) => { this.hasSearch = value; }) }}复制代码

broadcast通过递归遍历子组件找到所需组件广播事件,而dispatch则逐级向上查找对应父组件派发事件。 broadcast(componentName:(组件名),eventName:(事件名称)以及params:(数据))。根据componentName深度遍历子组件找到对应组件emit事件eventName。 dispatch(componentName:(组件名),eventName:(事件名称)以及params:(数据))。根据componentName向上级一直寻找对应父组件,找到以后emit事件eventName。

通过这种方式进行数据、事件传递,必须给组件命名name;

转载于:https://juejin.im/post/5b570924e51d45195f0b3bb3

你可能感兴趣的文章
表单元素01
查看>>
React Native项目Xcode打包发布iOS问题
查看>>
JPress v1.0-rc2 发布,新增微信小程序 SDK
查看>>
Confluence 6 为搜索引擎隐藏外部链接
查看>>
Python Mysql 数据库操作
查看>>
iOS Autolayout 介绍 2 Interface Builder 技巧
查看>>
打卡加虐狗
查看>>
Springboot + swagger2 通过实体对象封装形式上传视频或者图片问题解决
查看>>
Confluence 5 中如何快速创建一个 JIRA Ticket
查看>>
TP5搭建虚拟主机详细步骤
查看>>
为什么我们做分布式使用Redis?
查看>>
【4opencv】求解向量和轮廓的交点
查看>>
一次邮件发送协议SMTP问题排查
查看>>
BugkuCTF 文件上传测试
查看>>
7- OpenCV+TensorFlow 入门人工智能图像处理-彩色反转&边缘检测
查看>>
不同地域的内容偏好性分析
查看>>
JPA @Column 字段命名 默认驼峰转换
查看>>
作者谈《阿里巴巴Java开发手册(规约)》背后的故事
查看>>
缓冲区溢出攻击相关知识
查看>>
Purism 发布 PureBoot:高度安全、完整的 Linux 引导流程
查看>>