超详细 vue组件通信的10种方式

目录

  • 1、父组件props传值给子组件
    • 1-1、props扩展属性
    • 1-2、props扩展示例
  • 2、子组件$emit传值给父组件
    • 2-1、$emit传递多个参数
    • 2-2、$emit触发时的同时,父组件也传递参数
  • 3、祖先组件provide传递孙子组件inject接收
  • 4、父组件$refs获取子组件数据
  • 5、子组件$parent获取父组件数据
  • 6、组件 a t t r s 和 attrs和 attrslisteners透传
    • 6-1、$attrs
    • 6-2、$listeners
  • 7、事件总线event-bus
  • 8、vue-router传值
  • 9、vuex传值
  • 10、slot作用域传值

1、父组件props传值给子组件

子组件中定义props字段,类型为Array(如需限制字段值类型,也可以定义为Object的形式)。如下例子,父组件挂载子组件helloWorld,在组件标签上给title赋值,子组件helloWorld定义了props属性,里面有一个值是title,这样子组件就可以使用父组件传递过来的值了。

  • 父组件:home.vue



  • 子组件:hello-world.vue



1-1、props扩展属性

文档传送门

属性名 描述
type javaScript数据类型 限制props的类型
default 默认值 props的默认值
required Boolean 是否必须 true为必须
validator 回调函数 默认参数为props的值 props的值做处理 返回值必须是Boolean

1-2、props扩展示例




2、子组件$emit传值给父组件

子组件传值给父组件,需要在子组件中触发一个事件,在事件中,调用$emit(‘父组件的方法名’, ‘传递的值’),然后在父组件中,通过在子组件标签上自定义事件函数,接收传递过来的值。

  • 父组件:home.vue



  • 子组件:hello-world.vue



2-1、$emit传递多个参数

$emit的第一个参数后面添加,父组件按顺序接收。或者直接传递一个Object

// 子组件
this.$emit("childEvent", this.age, 'xxx', 'xxxx')
// or
this.$emit("childEvent", { a: 1, b: 2 })

// 父组件
parentEvent(value1, value2) {
  console.log(value1)
  console.log(value2)
}

2-2、$emit触发时的同时,父组件也传递参数

  • 父组件:home.vue



  • 子组件:hello-world.vue



3、祖先组件provide传递孙子组件inject接收

允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。注意:provide 和 inject 绑定并不是可响应的,然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的

  • 祖先组件:ancestor.vue
<template>
 <div id="ancestor">
  <Parent :keys="keys" />
 </div>
</template>

<script>
import Parent from '../../components/parent'

export default {
 name: 'ancestor',
 components: {
  Parent
 },
 provide() {
  return {
   obj: this.obj
  }
 },
 data() {
  return {
   title: 'ancestor',
   keys: 1998,
   obj: {
    set: 'hello provide'
   }
  }
 }
}
</script>
  • 父组件:parent.vue
<template>
 <div id="parent">
  <div class="head_box">
   <Son :value="index" />
  </div>
 </div>
</template>

<script>
import Son from '../son'

export default {
 name: 'parent',
 components: {
  Title
 },
 data() {
  return {
   index: 'WoW'
  }
 }
}
</script>
  • 子组件:son.vue
<template>
 <div id="son">
  <div class="title_box">
   <p>我是 {{ obj.set }}</p>
  </div>
 </div>
</template>

<script>
export default {
 name: 'son',
 inject: {
  obj: {
   from: 'Communication',
   default: {}
  }
 },
 data() {
  return {
   index: 1
  }
 }
}
</script>

4、父组件$refs获取子组件数据

在子组件标签上写上ref属性,父组件通过this. r e f s . n a m e . 方法名或者 t h i s . refs.name.方法名或者this. refs.name.方法名或者this.refs.name.属性名的方式可以访问子组件的数据和方法

  • 父组件:parent.vue
<template>
  <div>
    <Son :title="msg" ref="hello" />
    <button @click="parentEvent">我是父亲</button>
  </div>
</template>

<script>
import Son from "../components/son.vue";

export default {
  name: "parent",
  data() {
    return {
      msg: "搜索音乐",
    };
  },

  methods: {
    parentEvent() {
      this.$refs.hello.add();
      console.log(this.$refs.hello.age);
    },
  },
  components: {
    HelloWorld
  },
};
</script>
  • 子组件:son.vue
<template>
  <div class="hello">
    <h1>{{ title }}</h1>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: ["title"],
  data() {
    return {
      age:18
    }
  },
  methods: {
    add(){
      console.log("我是子组件")
    }
  }
}
</script>

5、子组件$parent获取父组件数据

在子组件中,可以使用 p a r e n t 访问其上级父组件的数据和方法。如果是多重嵌套,也可以使用多层 parent访问其上级父组件的数据和方法。如果是多重嵌套,也可以使用多层 parent访问其上级父组件的数据和方法。如果是多重嵌套,也可以使用多层parent层层往上。

  • 父组件:parent.vue
<template>
  <div>
    <Son :title="msg" ref="hello" />
  </div>
</template>

<script>
import Son from "../components/son.vue";

export default {
  name: "parent",
  components: {
    Son
  },
  data() {
    return {
      msg: "搜索音乐",
    };
  },

  methods: {
    parentEvent() {
      console.log("我是父组件的方法");
    },
  }
}
</script>
  • 子组件:son.vue
<template>
  <div class="hello">
    <h1 @click="add">{{ title }}</h1>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: ["title"],
  data() {
    return {
      age:18
    };
  },
  methods: {
    add(){
      console.log(this.$parent.msg)
      this.$parent.parentEvent();
    }
  },
};
</script>

注:如果要找父组件的父组件,this. p a r e n t . parent. parent.parent.xxx,如此类推

6、组件 a t t r s 和 attrs和 attrslisteners透传

a t t r s 包含了父作用域中不作为 p r o p 被识别获取的 a t t r i b u t e 绑定 ( c l a s s 和 s t y l e 除外 ) ,而 attrs包含了父作用域中不作为prop被识别获取的 attribute 绑定(class 和 style 除外),而 attrs包含了父作用域中不作为prop被识别获取的attribute绑定(classstyle除外),而listeners则包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器

6-1、$attrs

  • 祖先组件:ancestor.vue
<template>
 <div id="ancestor">
  <Parent :keys="keys" num="3000" />
 </div>
</template>

<script>
import Parent from '../../components/parent'

export default {
 name: 'ancestor',
 components: {
  Parent
 },
 data() {
  return {
   keys: 1998
  }
 }
}
</script>
  • 父组件:parent.vue
<template>
 <div id="parent">
  <div class="head_box">
   <Son v-bind="$attrs" />
  </div>
 </div>
</template>

<script>
import Son from '../son'

export default {
 name: 'parent',
 components: {
  Son
 },
 data() {
  return {}
 }
}
</script>
  • 子组件:son.vue
<template>
 <div id="son">
  <div class="title_box">
   <p>爷爷的值:{{ $attrs.keys }}</p>
   <p>爷爷的值:{{ $attrs.num }}</p>
  </div>
 </div>
</template>

<script>
export default {
 name: 'son',
 data() {
  return {}
 }
}
</script>

6-2、$listeners

  • 祖先组件:ancestor.vue
<template>
 <div id="ancestor">
  <Parent :keys="keys" @handleChildAdd="handleAdd" />
 </div>
</template>

<script>
import Parent from '../../components/parent'

export default {
 name: 'ancestor',
 components: {
  Parent
 },
 data() {
  return {
   keys: 1998
  }
 },
 methods: {
  // 父组件的事件
  handleAdd() {
   this.keys++
  }
 }
}
</script>
  • 父组件:parent.vue
<template>
 <div id="parent">
  <div class="head_box">
   <Son v-bind="$attrs" v-on="$listeners" />
  </div>
 </div>
</template>

<script>
import Son from '../son'

export default {
 name: 'parent',
 components: {
  Son
 },
 data() {
  return {}
 }
}
</script>
  • 子组件:son.vue
<template>
 <div id="son">
  <div class="title_box">
   <p>爷爷的值:{{ $attrs.keys }}</p>
   <span @click="chlidEvent">点击触发爷爷的事件</span>
  </div>
 </div>
</template>

<script>
export default {
 name: 'son',
 data() {
  return {}
 },
 methods: {
  chlidEvent() {
   // 通过$emit调用爷爷的方法
   this.$emit('handleChildAdd')
  }
 }
}
</script>

7、事件总线event-bus

  • 先新建一个bus.js文件,在bus.js里new一个Vue实例,充当传输数据的中间层
import Vue from 'vue';
export default new Vue;
  • 在组件A中引入bus.js,通过bus.$emit(‘事件名’,‘参数’)传递参数
<template>
  <div class="hello">
    <h1 @click="add">{{ title }}</h1>
  </div>
</template>

<script>
import bus from "../publicFn/bus.js";

export default {
  name: "HelloWorld",
  props: ["title"],
  data() {
    return {
      age:18
    };
  },
  methods: {
    add(){
      bus.$emit("childEvent", this.age);
    }
  },
};
</script>
  • 在B组件mounted周期中使用$on(‘事件名’, function(){})接收
<template>
  <div id='swiper'>
    <button>我是按钮</button>
  </div>
</template>

<script>

import bus from "../publicFn/bus.js";

export default {
  name:'Swiper',
  data (){
    return {

    }
  },
  mounted(){
    bus.$on("childEvent", (e) => {
      console.log(e)
    })
  }
}
</script>

8、vue-router传值

移步:vue-router总结

9、vuex传值

移步:vuex总结

10、slot作用域传值

作用域插槽在slot上绑定属性来将子组件的信息传给父组件使用,这些属性会被挂在父组件slot-scope接受的对象上。绑定时用的key,就是父组件获取数据的键。

  • 父组件
<template>
  <div>
    <aaaChildren>
      <template #default="scope">
        <h1>{{ scope.info.age }}</h1>
      </template>
      <template #text="scope">
        <h2>{{ scope.data }}</h2>
      </template>
    </aaaChildren>
  </div>
</template>

<script>
import aaaChildren from './children/index.vue'

export default {
  name:'aaa',
  components:{
    aaaChildren
  }
}
</script>
  • 子组件
<template>
  <div class="aaa_children">
    <slot :info="user"></slot>
    <slot name="text" :data="name"></slot>
  </div>
</template>

<script>
  export default {
    name:'aaaChildren',
    props:[],
    components:{},
    data(){
      return {
        user: {
          age: 18,
          name: '小明'
        },
        name: '卡卡罗特'
      }
    }
  }
</script>

如果看了觉得有帮助的,我是@鹏多多,欢迎 点赞 关注 评论

往期文章

  • 细数JS中实用且强大的操作符&运算符
  • 微信小程序API交互的自定义封装
  • 微信小程序request请求的封装

个人主页

  • CSDN
  • GitHub
  • 简书
  • 博客园
  • 掘金

你可能感兴趣的:(Vue,vue.js)