爷组件:Grand,父组件:Father,孙组件1:SonOne,孙组件2:SonTwo, 孙组件1 和 孙组件2 为兄弟组件
vue2
1.父传子(传值)(props)
//父组件 Father
<template>
<div>
<SonOne :num="num"></SonOne>
</div>
</template>
<script>
data() {
return {
num: 1
}
}
</script>
//子组件 SonOne
<template>
<div>{{ num }}</div>
</template>
<script>
props: {
num: {
type: number
}
}
//或者这样写
props:["son"]
</script>
2.子传父(传值)($emit)
//父组件 Father
<template>
<div>
<SonOne @addNum="addNum"></SonOne>
</div>
</template>
<script>
data() {
return {
num: 1
}
},
methods: {
addNum(num) {
this.num += num;
}
}
</script>
//子组件 SonOne
<template>
<div @click="addNum">点击+1</div>
</template>
<script>
methods: {
addNum() {
this.$emit('addNum',1);
}
}
</script>
3.父调子(调用方法)(ref)
//父组件 Father
<template>
<div>
<SonOne ref="sonOneRef"></SonOne>
<button @click="sonOneAddNum">调用子组件addNum方法</button>
</div>
</template>
<script>
methods: {
sonOneAddNum() {
this.$refs.sonOneRef.addNum;
}
}
</script>
//子组件 SonOne
<template>
<div>{{num}}</div>
</template>
<script>
data() {
return {
num: 1
}
},
methods: {
addNum(num) {
this.num += num;
}
}
</script>
4.子调父(调用方法)(this.$parent.event)
- 尽量避免使用此方法,因为会出现两个以上父组件同时引用改子组件的场景
- 可以用 $emit,vuex,eventBus事件总线(下面会写)方法代替
//父组件 Father
<template>
<div>
<SonOne></SonOne>
</div>
</template>
<script>
data() {
return {
num: 1
}
},
methods: {
addNum() {
this.num += 1;
}
}
</script>
//子组件 SonOne
<template>
<div @click="callParent"></div>
</template>
<script>
methods: {
callParent() {
this.$parent.event.addNum
}
}
</script>
5.兄弟之间传值或调用方法(传值 | 调用)(eventBus事件总线)
- 定义模块 src/bus.js,内容就是导入Vue模块,并导出一个Vue实例对象:
//bus.js
import Vue from 'vue'
export default new Vue()
- 此演示是 孙组件1 SonOne 向 孙组件2 SonTwo 发送一个事件
//孙组件1 SonOne
<template>
<div @click="sendMsg"></div>
</template>
<script>
import bus from '@/bus.js'
methods: {
sendMsg() {
bus.$emit('xxx', 'hello,world')
}
}
</script>
//孙组件2 SonTwo
<template>
<div @click="callParent"></div>
<script>
created(){
bus.$on('xxx', data=>{ console.log(data) })
}
</script>
6.爷传孙1(传值)($attrs)
//爷组件 Grand
<template>
<Father :toSonOne="toSonOne"></Father>
</template>
<script>
data(){
return {
toSonOne:"爷组件传给孙组件的值!~"
}
}
</script>
//孙组件 SonOne
<template>
<div>{{toSonOne}}</div>
</template>
<script>
props:{
toSonOne: { type: String }
}
</script>
7.爷传孙2(传值)(Provide,Inject)
//爷组件 Grand
<script>
export defalut {
data() {
arr:[1,2,3]
},
provide() {
return {
name:"test",
age:18,
length: this.arr.legth
}
}
}
</script>
//孙组件 SonOne
<template>
<div>{{name}}-{{age}}-{{length}}</div>
</template>
<script>
export defalut {
inject: ["name","age","length"]
}
</script>
8.孙传爷(传值)($listeners)
//孙组件 SonOne
<template>
<div @click="sendToGrand">{{toGrand}}</div>
</template>
<script>
data(){
return{
toGrand:"孙组件传给父组件的值!~"
}
},
methods:{
sendToFather(){
this.$emit("toGrand",this.toGrand)
}
}
</script>
//父组件 Father
<template>
<SonOne v-on="$listeners"></SonOne>
</template>
<script>
</script>
//爷组件 Grand
<template>
<Father @toGrand="getFromSonOne"></Father>
</template>
<script>
methods:{
getFromSonOne(val){
console.log(val)
}
}
</script>
9.爷调孙(调用方法)(eventBus事件总线)
- 推荐使用eventBus事件总线(第5项)
10.孙调爷(调用方法)(eventBus事件总线 | $listeners)
- 推荐使用eventBus事件总线(第5项) 或 $listeners(第8项)
vue3(常规语法)
1.父传子(传值)(props)
//父组件 Father
<template>
<SonOne :num="num"></SonOne>
</template>
<script>
import {ref} from 'vue'
setup () {
const num = ref(1)
return {num}
}
</script>
//子组件 SonOne
<template>
<div>{{ num }}</div>
</template>
<script>
props: ['num'],
</script>
2.子传父(传值)(emit)
//父组件 Father
<template>
<SonOne @sonHandler="sonHandler"></SonOne>
</template>
<script>
import {ref} from 'vue'
setup () {
function sonHandler () {
}
return { fn }
}
</script>
//子组件 SonOne
<template>
</template>
<script>
emits:['sonHandler']
setup (props, context) {
function fn () {
context.emit('sonHandler', '这是子组件传给父组件的') }
}
return { fn }
}
</script>
3.父调子(调用方法)(ref)
- 看vue3(语法糖的3)
4.子调父(调用方法)(emit)
- 看vue3(语法糖的4)
5.爷传孙(传值)(Provide,Inject)
- 看vue2的(7)
6.其他组件传值请用最后写的mitt库
vue3(语法糖setup)
1.父传子(传值)(props)
//父组件 Father
<template>
<SonOne :num="num"></SonOne>
</template>
<script setup>
import {ref} from 'vue'
const num = ref(1)
</script>
//子组件 SonOne
<template>
<div>{{ num }}</div>
</template>
<script setup>
const props = defineProps({
num: {
type: number
}
})
</script>
2.子传父(传值)(emit)
//父组件 Father
<template>
<SonOne @sendMsg="sendMsg"></SonOne>
</template>
<script setup>
function sendMsg(msg) {
console.log(msg);
}
</script>
//子组件 SonOne
<template>
<div @click="sendMsgClick"></div>
</template>
<script setup>
const emit = defineEmits(['sendMsg'])
function sendMsgClick() {
emit('sendMsg', 'hello');
}
</script>
3.父调子(调用方法)(ref)
- 子组件要defineExpose导出
//父组件 Father
<template>
<SonOne ref="sonOneRef"></SonOne>
</template>
<script setup>
import {ref} from 'vue'
const sonOneRef = ref()
function addNum(msg) {
sonOneRef.value.addNum
console.log('获取子组件中的num', sonOneRef.value.num );
}
</script>
//子组件 SonOne
<template>
<div>{{num}}</div>
</template>
<script setup>
import {ref} from 'vue'
const num = ref(1)
function addNum(count) {
num.value += count
}
defineExpose({num,addNum})
</script>
4.子调父(调用方法)(emit)
//父组件 Father
<template>
<SonOne @fatherAlert="fatherAlert"></SonOne>
</template>
<script setup>
function fatherAlert(msg) {
alert('我是爸爸的方法')
}
</script>
//子组件 SonOne
<template>
<div @click="clickChild"></div>
</template>
<script setup>
const emit = defineEmits(['fatherAlert'])
function clickChild() {
emit('fatherAlert');
}
</script>
5.爷传孙(传值)(Provide,Inject)
- 看vue2的(7)
6.其他组件传值请用最后写的mitt库
vue其他组件通信(mitt.js)(vue2,vue3都可以用)
- npm install mitt
- 在utils文件夹里创建eventbus.js文件
//eventbus.js
import mitt from "mitt"
const emitter = mitt()
export default emitter
- 发送事件
<template>
<button @click="btnClick"></button>
</template>
<script>
import emitter from "@/utils/eventbus.js"
export default {
methods:{
btnClick() {
emitter.emit("add",2)
}
}
}
</script>
- 接受事件
<script>
import emitter from "@/utils/eventbus.js"
export default {
created(){
emitter.on("add",() => {...})
}
}
</script>
- 接受全部事件
<script>
import emitter from "@/utils/eventbus.js"
export default {
created(){
emitter.on("*",(type,info) => {
//type: 传的事件名称
//info: 传的值
})
}
}
</script>
- 取消监听
emitter.all.clear()