Vue父子组件间通信

转自 https://www.cnblogs.com/vickylinj/p/10877765.html

一、子组件向父组件传值 emit

1、自定义事件
在子组件中定义事件触发,通过 e m i t ( ) 把 值 传 递 给 父 组 件 , 父 组 件 使 用 v − o n : x x x ( 或 者 使 用 语 法 糖 @ x x x ) 进 行 监 听 并 接 受 参 数 ; 但 是 需 要 注 意 emit()把值传递给父组件,父组件使用v-on:xxx(或者使用语法糖@xxx)进行监听并接受参数;但是需要注意 emit()使von:xxx(使@xxx)emit()第一个参数是自定义事件的名称。
原理:父组件将方法的引用,传递到子组件内部,子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去
子组件:

在这里插入图片描述
父组件:

在这里插入图片描述

2、使用v-model
在父组件上使用v-model指令,子组件使用this.$emit(‘input’,this.子组件属性)

......
<my-component  v-model="total "></my-component>
......
this.$emit ('input', this.counter);

二、父组件向子组件传值

1、 使用props

子组件通过 props方法获取父组件传递过来的值。props中可以定义能接收的数据类型,如果不符合会报错

父组件

//引入的add-widget组件
//动态传值使用的是表达式,使用 v-bind 的缩写语法通常更简单:XXX;静态传值不用绑定,传递的是字符串
<add-widget :msg-val="msg"> //这里必须要用 - 代替驼峰
// HTML 特性是不区分大小写的。所以,当使用的不是字符串模板,camelCased (驼峰式) 命名的 prop 需要转换为相对应的 kebab-case (短横线隔开式) 命名,当你使用的是字符串模板的时候,则没有这些限制 
</add-widget>
data(){
    return {
        msg: [1,2,3]
    };
}

子组件

//子组件通过props来接收数据:
//方式1:
props: ['msgVal']
//方式2 :
props: {
    msgVal: Array //这样可以指定传入的类型,如果类型不对,会警告
}
//方式3:
props: {
    msgVal: {
        type: Array, //指定传入的类型
        //type 也可以是一个自定义构造器函数,使用 instanceof 检测。
        default: [0,0,0] //这样可以指定默认的值
    },
// isPublic: {
//    type: Boolean,
//    default: undefined  //注意!对于布尔类型,默认值不要写成false,否则isPublic永远为false。
// }
}
//注意 props 会在组件实例创建之前进行校验,所以在 default 或 validator 函数里,诸如 data、computed 或 methods 等实例属性还无法使用

注意:父子组件传值,数据是异步请求,有可能数据渲染时报错

原因:异步请求时,数据还没有获取到但是此时已经渲染节点了
解决方案:可以在父组件需要传递数据的节点加上 v-if = isReady(isReady默认为false),异步请求获取数据后(isReady赋值为true),v-if = isReady

2、使用$ref

ref 是被用来给元素或子组件注册引用信息的。引用信息将会注册在父组件的 $refs 对象上。

如果ref用在子组件上,指向的是组件实例,可以理解为对子组件的引用,通过 r e f 可 能 获 取 到 在 子 组 件 里 定 义 的 属 性 和 方 法 。 如 果 r e f 在 普 通 的 D O M 元 素 上 使 用 , 引 用 指 向 的 就 是 D O M 元 素 , 通 过 ref可能获取到在子组件里定义的属性和方法。 如果ref在普通的 DOM 元素上使用,引用指向的就是 DOM 元素,通过 refrefDOM使DOMref可能获取到该DOM 的属性集合,轻松访问到DOM元素,作用与JQ选择器类似。

父组件

<template>
 <div>
 <h1>父组件!</h1>
 //注册子组件,起名 msg
 <child ref="msg"></child>
 </div>
</template>
 
<script>
 import Child from '../components/child.vue'
 export default {
 components: {Child},
 mounted: function () {
 //获取子组件对象 msg
  console.log( this.$refs.msg);
  //调用子组件对象方法传值
  this.$refs.msg.getMessage('子组件!')
 }
 }
</script>

子组件

<template>
 <h3>{{message}}</h3>
</template>
<script>
 export default {
 data(){
  return{
  message:''
  }
 },
 methods:{
 //子组件定义方法,供父组件调用传值
  getMessage(m){
  this.message=m;
  }
 }
 }
</script>

比较:
props通过父组件属性绑定,子组件定义相应属性,进行接收;
ref通过父组件注册子组件,调用子组件定义的方法进行传值

prop 着重于数据的传递,它并不能调用子组件里的属性和方法。像创建文章组件时,自定义标题和内容这样的使用场景,最适合使用prop。
$ref 着重于引用,主要用来调用子组件里的属性和方法,其实并不擅长数据传递。而且ref用在dom元素的时候,能使到选择器的作用,这个功能比作为索引更常有用到

三、子组件向子组件传递数据
通过eventBus或vuex(小项目少页面用eventBus,大项目多页面使用 vuex)传值

1、通过eventBus(即通过on监听、emit触发的方式)
1.1定义一个新的vue实例专门用于传递数据,并导出
在这里插入图片描述
1.2定义传递的方法名和传输内容,点击事件或钩子函数触发eventBus.emit事件
在这里插入图片描述
1.3接收传递过来的数据
注意:enentBus是一个另一个新的Vue实例,区分两个this所代表得vue实例
在这里插入图片描述

2、vuex进行传值
详情见:https://baijiahao.baidu.com/s?id=1618794879569468435&wfr=spider&for=pc

四、画面迁移的组件之间传递数据
1、通过路由带参数进行传值,例:两个组件 A和B,A组件通过query把orderId传递给B组件

A组件传值写法:

this.$router.push({ path: '/conponentsB', query: { orderId: 123 } }) // 跳转到B

B组件取值写法:

this.$route.query.orderId

注意:
①Vue-详解设置路由导航的两种方法:声明式的导航 和编程式的导航router.push(…)
②其中画面迁移有push和replace两种方式,详情如:

https://www.cnblogs.com/vickylinj/p/10880869.html

③传参的方式又分为查询参数query(+path)和命名路由params(+name)两种方式:
命名路由搭配params,刷新页面参数会丢失
查询参数搭配query,刷新页面数据不会丢失
接受参数使用this.$router后面就是搭配路由的名称就能获取到参数的值

详情如:https://blog.csdn.net/crazywoniu/article/details/80942642

2、通过设置 Session Storage缓存的形式进行传递

两个组件A和B,在A组件中设置缓存orderData

const orderData = { 'orderId': 123, 'price': 88 } 
sessionStorage.setItem('缓存名称', JSON.stringify(orderData))

B组件就可以获取在A中设置的缓存了

const dataB = JSON.parse(sessionStorage.getItem('缓存名称'))

五、通过provide/inject传值

详情见:https://www.cnblogs.com/vickylinj/p/13368745.html

六、通过 a t t r s 、 attrs、 attrslisteners传值

详情见:https://www.cnblogs.com/vickylinj/p/13376391.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值