vue 常用开发父子组件的通信

1.父组件绑定参数,子组件props接收

// 父组件
<template>
    <div id="father">
        <data :msg="msg" :fn="myFunction"></data>
    </div>
</template>
 
<script>
import data from "./data .vue";
export default {
    
    
    name: father,
    components: {
    
    
        data 
    }
    data() {
    
    
        msg: "父组件定义的数据";
    },
    methods: {
    
    
        myFunction() {
    
    
            console.log("father");
        }
    },
};
</script>
// 子组件
<template>
    <div id="son">
        <p>{
    
    {
    
    msg}}</p>
        <button @click="fn">按钮</button>
    </div>
</template>
<script>
export default {
    
    
    name: "data",
    props: {
    
    
		msg: {
    
    
			type: String,
			defalut:''
		},
		fn :{
    
    
			type: Function,
		}
	}
};
</script>

2.父组件自定义绑定事件,子组件$emit接收

// 父组件
<template>
    <div id="father">
        <data  @fn="myFunction"></data>
    </div>
</template>
 
<script>
import data from "./data .vue";
export default {
    
    
    name: father,
    components: {
    
    
        data 
    }
    data() {
    
    
    },
    methods: {
    
    
        myFunction() {
    
    
           //编写需要的方法
           console.log('0000000000000')
        }
    },
};
</script>
// 子组件
<template>
    <div id="son">
        <p>{
    
    {
    
    msg}}</p>
        <button @click="fn">按钮</button>
    </div>
</template>
<script>
export default {
    
    
    name: "data",
	},
	data() {
    
    
    },
    methods: {
    
    
    //调用父组件
        sonHandle() {
    
    
         this.$emit('fn')
        }
    },
};
</script>

3.ref / $refs

ref :这个属性用在子组件上,可以将子组件的数据传给父组件

<template>
  <child ref="child"></child>
</template>
<script>
  import child from './child.vue'
  export default {
    
    
    components: {
    
     child },
    created() {
    
    
		this.$refs.child.open()//调用子组件的open方法
		//通过ref可以获取子组件的所有实例
	}
  }
</script>

4.this.$parent通信(子组件访问父组件)

//父组件
<template>
    <div id="father">
        <data ></data>
    </div>
</template>
 
<script>
import data from "./data .vue";
export default {
    
    
    name: father,
    components: {
    
    
        data 
    }
    data() {
    
    
    msg:'0000000000000000'
    },
    methods: {
    
    
        myFunction() {
    
    
           //编写需要的方法
           console.log('0000000000000')
        }
    },
};
</script>
// 子组件
<template>
    <div id="son">
        <p>{
    
    {
    
    msg}}</p>
        <button @click="fn">按钮</button>
    </div>
</template>
<script>
export default {
    
    
    name: "data",
	},
	data() {
    
    
    },
    methods: {
    
    
    //调用父组件
        fn() {
    
    
			 this.$nextTick(() => {
    
    //一般推荐加nextTick和保证组件有渲染不能v-if
             this.$parent.myFunction();//访问父组件的方法
         });

		}
    },
};
</script>

5.provide 和 inject通信

//grandpa.vue
<template>
  <div>
    <h3 style="margin-bottom: 20px">爷爷组件</h3>
    <el-button type="primary" @click="lookDetail">查看</el-button>
    <!-- 儿子组件 -->
    <son v-model:visible="openDialog"></son>
  </div>
</template>

<script>
import Son from "./son.vue";
export default {
    
    
  components: {
    
     Son },
  data() {
    
    
    return {
    
    
      message: "aa",
      openDialog: false,
    };
  },
  methods: {
    
    
    lookDetail() {
    
    
      this.openDialog = true;
    },
  },
};
</script>


//son.vue
<template>
  <div>
    <el-dialog  v-model="visible" title="父组件" width="50%" append-to-body @close="closeDialog">
      <el-button type="primary" @click="lookDetail">查看</el-button>
    </el-dialog>
    <!-- 孙子组件 -->
    <grandson v-model:visible="openDialog"></grandson>
  </div>
</template>

<script>
//孙子组件
import grandson from "./grandson.vue";
export default {
    
    
  components: {
    
    
    grandson,
  },
  props: {
    
    
    visible: {
    
    
      type: Boolean,
      default: false,
    },
  },
  emit: ["update:visible"],
  data() {
    
    
    return {
    
    
      openDialog: false,
    };
  },
  methods: {
    
    
    closeDialog() {
    
    
      this.$emit("update:visible", false);
    },
    lookDetail() {
    
    
      this.openDialog = true;
    },
  },
};
</script>


//grandson.vue
<template>
  <div>
    <el-dialog v-model="visible" title="孙子组件"  width="30%"  @close="closeDialog">
    </el-dialog>
  </div>
</template>

<script>
export default {
    
    
  props: {
    
    
    visible: {
    
    
      type: Boolean,
      default: false,
    },
  },
  emit: ["update:visible"],
  data() {
    
    
    return {
    
    };
  },
  methods: {
    
    
    closeDialog() {
    
    
        this.$emit("update:visible",false)
    },
  },
};
</script>

6、eventBus事件总线($emit / $on)

eventBus事件总线适用于父子组件、非父子组件等之间的通信
创建事件中心管理组件之间的通信

// event-bus.js

import Vue from 'vue'
export const EventBus = new Vue()

兄弟组件firstCom和secondCom

<template>
  <div>
    <first-com></first-com>
    <second-com></second-com>
  </div>
</template>

<script>
import firstCom from './firstCom.vue'
import secondCom from './secondCom.vue'
export default {
    
    
  components: {
    
     firstCom, secondCom }
}
</script>

<template>
  <div>
    <button @click="add">加法</button>    
  </div>
</template>

<script>
import {
    
    EventBus} from './event-bus.js' // 引入事件中心

export default {
    
    
  data(){
    
    
    return{
    
    
      num:0
    }
  },
  methods:{
    
    
    add(){
    
    
      EventBus.$emit('addition', {
    
    
        num:this.num++
      })
    }
  }
}
</script>

接收事件

<template>
  <div>求和: {
    
    {
    
    count}}</div>
</template>

<script>
import {
    
     EventBus } from './event-bus.js'
export default {
    
    
  data() {
    
    
    return {
    
    
      count: 0
    }
  },
  mounted() {
    
    
    EventBus.$on('addition', param => {
    
    
      this.count = this.count + param.num;
    })
  }
}
</script>

7、$attrs / $listeners

实组件之间的跨代通信。

$attrs:继承所有的父组件属性(除了props传递的属性、class 和 style),一般用在子组件的子元素上
$listeners:该属性是一个对象,里面包含了作用在这个组件上的所有监听器,可以配合 v-on=" $listeners " 将所有的事件监听器指向这个组件的某个特定的子元素。(相当于子组件继承父组件的事件)

A组件

<template>
    <div id="app">
        //此处监听了两个事件,可以在B组件或者C组件中直接触发 
        <child1 :p-child1="child1" :p-child2="child2" @test1="onTest1" @test2="onTest2"></child1>
    </div>
</template>
<script>
import Child1 from './Child1.vue';
export default {
    
    
    components: {
    
     Child1 },
    methods: {
    
    
        onTest1() {
    
    
            console.log('test1 running');
        },
        onTest2() {
    
    
            console.log('test2 running');
        }
    }
};
</script>

B组件

<template>
    <div class="child-1">
        <p>props: {
    
    {
    
    pChild1}}</p>
        <p>$attrs: {
    
    {
    
    $attrs}}</p>
        <child2 v-bind="$attrs" v-on="$listeners"></child2>
    </div>
</template>
<script>
import Child2 from './Child2.vue';
export default {
    
    
    props: ['pChild1'],
    components: {
    
     Child2 },
    inheritAttrs: false,
    mounted() {
    
    
        this.$emit('test1'); // 触发APP.vue中的test1方法
    }
};
</script>

C组件

<template>
    <div class="child-2">
        <p>props: {
    
    {
    
    pChild2}}</p>
        <p>$attrs: {
    
    {
    
    $attrs}}</p>
    </div>
</template>
<script>
export default {
    
    
    props: ['pChild2'],
    inheritAttrs: false,
    mounted() {
    
    
        this.$emit('test2');// 触发APP.vue中的test2方法
    }
};
</script>

猜你喜欢

转载自blog.csdn.net/weixin_46820017/article/details/127432804