方法一:$emit / props

  • 父组件通过props的方式向子组件传递,子组件通过$emit触发父组件中v-on绑定的自定义事件
<!--父组件-->
<template>
<div>
<Child :message="message" @customEvent="customEvent"/>
</div>
</template>
<script>
export default {
components:{
Child
},
data(){
return {
message:'来自父组件的问候'
}
},
methods:{
customEvent(value){
//执行子组件触发的事件
console.log(value)
}
}
}
</script>
<!--------------------------------------------------------------------------------------------> <!--子组件-->
<template>
<div>
<p>{{message}}</p>
<button @click="handleClick">点击向父组件传值</button>
</div>
</template>
<script>
export default {
props:['message'],//得到父组件传递过来的数据
methods:{
handleClick(){
//触发父组件中的事件
this.$emit('customEvent','来自子组件的问候');
}
}
}
</script>

方法二、$parent / $children 与 ref

  • ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
  • $parent / $children:访问父 / 所有子实例
<!--父组件-->
<template>
<div>
<Child ref='children'/>
<button @click="handleClick">访问子组件</button>
</div>
</template>
<script>
import Child from './child'
export default {
components:{
Child
},
data(){
return {
message:'我是父组件的数据'
}
},
methods:{
handleClick(){
console.log(this.$refs.children.message)
console.log(this.$children[0].message)
//需要注意的是使用$children返回的是一个数组
}
}
}
</script> <!--------------------------------------------------------------------------------------------> <!--子组件-->
<template>
<div>
<p>{{message}}</p>
<button @click="handleClick">访问父组件</button>
</div>
</template>
<script>
export default {
data(){
return {
message:'我是子组件的数据'
}
},
methods:{
handleClick(){
console.log(this.$parent.message)
}
}
}
</script>

方法三、中央事件总线bus

  • 新建一个Vue事件bus对象,然后通过 bus.$emit 触发事件, bus.$on 监听触发的事件。
//eventBus.js
import Vue from 'vue';
export default new Vue();
  • 在需要用到的两个不同组件分别引入即可
  • 需要注意的是接受数据的组件要清除事件总线eventBus
<!--A组件-->
<template>
<div>
<p>A组件</p>
<button @click="handleClick">向B组件传值</button>
</div>
</template>
<script>
import eventBus from 'eventBus.js的路径'
export default {
data(){
return {
data:'我是A组件的数据'
}
},
methods:{
handleClick(){
eventBus.$emit('change',this.data);
}
}
}
</script> <!--------------------------------------------------------------------------------------------> <!--B组件-->
<template>
<div>
<p>B组件</p>
</div>
</template> <script>
import eventBus from 'eventBus.js的路径';
export default {
//触发事件一般用mounted 或 created 钩子来监听
mounted(){
//触发和监听的事件名称要一致
eventBus.$on('change',(value)=>{
console.log(value)
})
},
destroyed(){
eventBus.$off('change');
}
}
</script>

方法四、依赖注入 provide和inject

  • 适用场景:高阶插件/组件库
  • 类型:
    • provide:Object | () => Object
    • inject:Array<string> | { [key: string]: string | Symbol | Object }
  • 父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。
  • 不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。
<!--父组件-->
<template>
<div>
<h1>父组件</h1>
<Son/>
</div>
</template>
<script>
import Son from './son'
export default {
components:{
Son
},
data(){
return {
message:'我是父组件的数据'
}
},
provide(){
return {
message:this.message
}
}
}
</script> <!--------------------------------------------------------------------------------------------> <!--子组件-->
<template>
<div>
<h1>子组件</h1>
<GrandSon />
</div>
</template> <script>
import GrandSon from './grandSon';
export default {
components:{
GrandSon
}
}
</script> <!--------------------------------------------------------------------------------------------> <!--孙子组件-->
<template>
<div>
<h1>孙子组件</h1>
<p>{{message}}</p>
</div>
</template> <script>
export default {
inject:['message']
}
</script>

方法五、$attrs 和 $listeners

  • 适用场景:多层、递归组件
  • $attrs 是包含了所以父组件在子组件上设置的属性(除了prop传递的属性、class 和 style )
  • $listeners 是组件的内置属性,它的值是父组件(不含.native修饰器的) v-on事件监听器
    • 如果子组件已经绑定$listener中同名的监听器,则两个监听器函数会以冒泡的方式先后执行
<!--父组件-->
<template>
<div>
<h1>父组件</h1>
<Son :message1="message1" :message2="message2" name='attr' v-on="{onChange1,onChange2}"/>
</div>
</template>
<script>
import Son from './son'
export default {
components:{
Son
},
data(){
return {
message1:'我是父组件的数据1',
message2:'我是父组件的数据2'
}
},
methods:{
onChange1(val){
console.log("父组件:" + val)
},
onChange2(val){
console.log(val)
}
}
}
</script> <!--------------------------------------------------------------------------------------------> <!--子组件-->
<template>
<div>
<h1>子组件</h1>
<!--关键点-->
<GrandSon v-bind="$attrs" v-on="$listeners" @onChange1="onChange1"/>
</div>
</template> <script>
import GrandSon from './grandSon';
export default {
inheritAttrs:false,
/**
* 1、当设置inheritAttrs为true(默认)时,子组件的顶层标签元素中会渲染出父组件传递过来(前提:子组件的props中未注册父组件传递过来的属性)的属性。
* 2、当设置inheritAttrs为false时,子组件的顶层标签元素中不会渲染出父组件传递过来(前提:子组件的props中未注册父组件传递过来的属性)的属性。
* 3、不管inheritAttrs为true或者false,子组件中都能通过$attrs属性获取到父组件中传递过来的属性。
*/
components:{
GrandSon
},
methods:{
//与父组件监听的事件同名了
onChange1(val){
console.log('子组件:'+val)
}
}
}
</script> <!--------------------------------------------------------------------------------------------> <!--孙子组件-->
<template>
<div>
<h1>孙子组件</h1>
<p>{{message2}}</p>
<button @click="handleClick">点击触发父组件的方法</button>
</div>
</template> <script>
export default {
props:['message2'], //message2被声明
created(){
console.log(this.$attrs) //{message1: "我是父组件的数据1", name: "attr"}
console.log(this.$listeners) //{onChange1: ƒ, onChange2: ƒ}
},
methods:{
handleClick(){
this.$emit('onChange1','来自孙子的问候')
}
}
}
</script>

方法六、v-model

  • 父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过this.$emit('input',val)自动修改v-model绑定的值
  • prop属性和触发事件可以通过model修改
<!--父组件-->
<template>
<div>
<h1>父组件</h1>
<p>{{inputValue}}</p>
<Son v-model="inputValue"/>
</div>
</template>
<script>
import Son from './son'
export default {
components:{
Son
},
data(){
return {
inputValue:'父组件的默认消息'
}
}
}
</script> <!--------------------------------------------------------------------------------------------> <!--子组件-->
<template>
<div>
<h1>子组件</h1>
<p>父组件传过来的值:{{value}}</p>
<input @input="handleChange" />
</div>
</template> <script>
export default {
model:{
prop:'value', //默认(value)可以修改任意值
event:'input' //默认(input)事件名也可以修改
},
props:{
value:String
},
methods:{
handleChange(e){
this.$emit('input',e.target.value)
}
}
}
</script>

方法七、VueX

vue必须掌握之组件通信(7种方法)的更多相关文章

  1. vue中组件的四种方法总结

    希望对大家有用 全局组件的第一种写法 html: <div id = "app"> <show></show></div> js: ...

  2. Vue 创建组件的两种方法

    地址:https://blog.csdn.net/cofecode/article/details/74634301 创建组件的两种方法 1.全局注册 2.局部注册 var child=Vue.ext ...

  3. vue第八单元(组件通信 子父,父子组件通信 自定义事件 事件修饰符 v-model props验证 )

    第八单元(组件通信 子父,父子组件通信 自定义事件 事件修饰符 v-model props验证 ) #课程目标 掌握使用props让父组件给子组件传参(重点) 掌握props属性的使用以及prop验证 ...

  4. vue学习记录⑤(组件通信-父与子)

    今天我们看一下组件通信. 经过前面几篇文章,我们已经可以构建出完整的单个组件,并利用路由使其串联起来访问了. 但这明显还是不够的.一个页面不可能就是个单组件,一般是由多个组件合成的.正因为如此,组件之 ...

  5. VUE 动态加载组件的四种方式

    动态加载组件的四种方式: 1.使用import导入组件,可以获取到组件 var name = 'system'; var myComponent =() => import('../compon ...

  6. vue创建组件的几种方法

    <html> <head> <title>vue创建组件</title> <meta charset="utf-8"> ...

  7. Vue全局组件创建三种方法

    <my-com1></my-com1> <my-com2></my-com2> <template id="tmp1"> ...

  8. html中创建并调用vue组件的几种方法

    最近在写项目的时候,总是遇到在html中使用vue.js的情况,且页面逻辑较多,之前的项目经验都是使用脚手架等已有的项目架构,使用.vue文件完成组价注册,及组件之间的调用,还没有过在html中创建组 ...

  9. Vue组件通信父传方法给子组件调用

    // 父组件中将 :meth='changeCom1' 传入入子组件 , 子组件运行 meth(i) 方法 并给他传参数 ,在父组件可以获取这个参数,并做相应的操作   // 父组件 <temp ...

随机推荐

  1. 修改 ssh 远程连接 时间

           linux使用的是  红帽旗下 centos.         解释两个文件          /etc/ssh/sshd_config     配置ssh服务器端的          ...

  2. log4j2 springboot 特点与使用方法

    Apache Log4j2 is an upgrade to Log4j that provides significant improvements over its predecessor, Lo ...

  3. js将已有数组重新分组(将数组每10项分成一组)

    项目中碰到的一个小需求:分页请求数据,一次请求60条,需要将后台返回的数组每10条分成一组渲染一个表格(表格使用的是ant-design-vue的table) 实现逻辑: var chunk = 10 ...

  4. B树(B-树) 、B+树

    B树(B-树) 1.B-树(B树)的基本概念B-树中所有结点中孩子结点个数的最大值成为B-树的阶,通常用m表示,从查找效率考虑,一般要求m>=3.一棵m阶B-树或者是一棵空树,或者是满足以下条件 ...

  5. Java的引用类型的内存分析

    一. jdk的内存:jdk的bin目录常见命令 1. javac.exe:编译java源代码的,生成java字节码文件(*.class) 2. java.exe:启动一个jvm,来运行指定class字 ...

  6. day1 对java的认识

    对java的认识 1.java是一门跨平台的语言,由jvm进行预编译,转换成类似伪代码一样的东西,最后再转换成机器语言. 2.程序是由数据结构和算法构成,其他所有的工具类,方法都是为数据结构或者算法服 ...

  7. 15.Android-实现TCP客户端,支持读写

    在上章14.Android-使用sendMessage线程之间通信我们学习了如何在线程之间发送数据. 接下来我们便来学习如何通过socket读写TCP. 需要注意的是socket必须写在子线程中,不能 ...

  8. 范式通俗理解:1NF、2NF、3NF和BNCF

    https://blog.csdn.net/wyh7280/article/details/83350722 范式通俗理解:1NF.2NF.3NF和BNCF原创hongiii 最后发布于2018-10 ...

  9. ACM 英文学习系列

    因为ACM题目描述全是英文,所以有必要学习学习相关词汇...内心极为无奈 废话不多说 rooted binary tree 有根二叉树     integers n 英[ˈɪntɪdʒəz] 整数   ...

  10. 什么是AOP面向切面编程思想

    一.什么是AOP? 1.AOP不是一种语言,是一种编程范式 常见的编程范式: 面向过程.面向对象.函数式编程.事件驱动编程等 2.AOP可以解决特定问题,不能解决所有问题. 3.是面向对象的补充,不是 ...