1.父传子:在子组件中可以接收父组件传入的值:基于属性传递?通过props接收;
??????????????????通过props接受的属性和data数据一样,是直接挂载到实例上的。
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>demo1</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<style>
.panel {
width: 300px;
}
</style>
</head>
<body>
<div id="app">
<div class="container">
<vote v-for="(item,index) in list" :key="index" :title="item" :num="'89'"> </vote>
</div>
</div>
<template id="Vote">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
{{title}}---{{num}}
</h3>
</div>
<content-vote :num='num'></content-vote>
<footer-vote></footer-vote>
</div>
</template>
<template id="ContentVote">
<div class="panel-body">
<div class="list-group">
<div class="list-group-item">支持人数:{{num}}</div>
<div class="list-group-item">反对人数:10</div>
<div class="list-group-item">支持率:90%</div>
</div>
</div>
</template>
<template id="FooterVote">
<div class="panel-footer text-center">
<button class="btn btn-success">支持</button>
<button class="btn btn-danger">反对</button>
</div>
</template>
<script>
const ContentVote={
template: '#ContentVote',
props:['num']
}
const FooterVote={
template: '#FooterVote'
}
Vue.component('Vote', {
template: '#Vote',
props:['title','num'],
components: {
ContentVote,
FooterVote
},
created() {
console.log(this.a,this.title);
},
})
let vm = new Vue({
el: '#app',
data:{
list:['胡歌','靳东','肖战']
}
})
</script>
</body>
</html>
2.子改父:通过基于自定义事件,在子组件中通过$emit接收。
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>demo2</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2>父组件中的num: {{num}}</h2>
<my-component :num="num" @parentEvent="add" ></my-component>
</div>
<template id="MyComponent">
<div>
<p>子组件中的num: {{num}}</p>
<p><button @click=" $emit('parentevent',n)">让num自加</button></p>
</div>
</template>
<script>
Vue.component('MyComponent',{ //注册全剧组件
data(){
return {
n:30
}
},
template:'#MyComponent', //组件的html
props:['num','add'], //接受父元素传过来的参数
methods: {
addFn(n){
console.log(123);
this.$emit('parentevent',n);
// 请注意,HTML属性不区分大小写,在DOM模板中使用时,不能使用v-on侦听camelCase事件,所以此处应该使用小写
}
},
})
let vm=new Vue({
el:"#app",
data:{
num:10
},
methods: { //存放方法 事件类
add(n=1){ //默认值 如果不传参数 默认为1
console.log(456)
this.num+=n;
}
},
})
</script>
</body>
</html>
3.兄弟之间通信:这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,通过$on监听事件, $emit触发事件。
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>demo3</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<vote></vote>
<vote></vote>
<vote></vote>
</div>
<template id="Vote">
<div>
<a-component :vue="vue"></a-component>
<b-component :vue="vue"></b-component>
</div>
</template>
<template id="A">
<div>
<p>A组件中的num: {{num}}</p>
</div>
</template>
<template id="B">
<div>
<p>B组件:<button @click="addFn(20)">更改A组件的数据</button></p>
</div>
</template>
<script>
const AComponent={
template:'#A',
data(){
return {
num:100
}
},
props:['vue'],
methods: {
add(n=1){
this.num+=n
}
},
created() {
this.vue.$on('brotherEvent',this.add)
},
}
const BComponent={
template:'#B',
props:['vue'],
methods: {
addFn(n){
this.vue.$emit('brotherEvent',n)
}
},
}
const Vote={
template:'#Vote',
data(){
return {
vue:new Vue
}
},
components:{
AComponent,
BComponent
}
}
let vm=new Vue({
el:"#app",
components:{
Vote
}
})
</script>
</body>
</html>
4.$parent,$children,$refs:? ?$parent是获取父组件实例,$children是以数组形式获取子组件实例,$refs是以对象形式获取子组件实例。
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>demo4</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<parent :title="10"></parent>
</div>
<template id="Parent">
<div>
<h4>Parent</h4>
<p>{{num}}</p>
<child-a></child-a>
</div>
</template>
<template id="ChildA">
<div>
<h4>ChildA</h4>
<p>{{n}}</p>
<p>{{$parent.num}}</p>
<button @click="$parent.add(20)">修改值</button>
</div>
</template>
<script>
const ChildA = {
template: '#ChildA',
computed: {
n(){
return this.$parent.num;
}
},
created() {
console.log(this.$parent);
},
}
const Parent = {
template: '#Parent',
data() {
return {
num: 10
}
},
props: ['title'],
methods: {
add(n = 1) {
this.num += n;
}
},
components: {
ChildA
},
created() {
// console.log(this.$parent);
},
}
let vm = new Vue({
el: '#app',
components: {
Parent
}
})
</script>
</body>
</html>
5.$attrs,$listeners:? $attrs是接收父作用域内传入的没有被props接收的自定义属性,$listeners获取父作用域内传入的事件。
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>demo5</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h3>父组件</h3>
<vote :num="num" :msg="msg" :n="n" class="box" @eventA="add" @eventB="reduce" @click="add"></vote>
</div>
<template id="Vote">
<div>
<h4>Vote</h4>
<p>num:{{$attrs.num}}---msg:{{$attrs.msg}}---n:{{n}}</p>
<button @click="$listeners.eventa(100)">自加</button>
<button @click="$listeners.eventb(10)">自减</button>
<component-a :n="n" v-bind="$attrs"></component-a>
<component-b v-on="$listeners"></component-b>
</div>
</template>
<template id="ComponentA">
<div>
<h4>子组件A</h4>
<p>num:{{$attrs.num}}---msg:{{$attrs.msg}}---n:{{$attrs.n}}</p>
</div>
</template>
<template id="ComponentB">
<div>
<h4>子组件B</h4>
<button @click="$listeners.eventa(100)">自加</button>
<button @click="$listeners.eventb(10)">自减</button>
</div>
</template>
<script>
const ComponentA={
template:'#ComponentA',
created() {
console.log('***',this.$attrs);
},
}
const ComponentB={
template:'#ComponentB',
}
const Vote={
template:'#Vote',
components:{
ComponentA,
ComponentB
},
props:['n'],
// 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件
created() {
console.log(this.$attrs);
console.log(this.$listeners);
}
}
let vm=new Vue({
el:"#app",
components:{
Vote
},
data:{
num:10,
msg:"hello",
n:100
},
methods: {
add(n){
this.num+=n;
},
reduce(n){
this.num-=n;
}
},
})
</script>
</body>
</html>
6.Provide,inject:? provide在祖先组件中注入属性和方法,inject在后代组件中获取注入的属性和方法,注意这些属性是不可响应的,如果需要可响应,则需要注入一个可响应的对象。
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>demo6</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h3>父组件</h3>
<p>num:{{num}}---m:{{obj.m}}</p>
<vote></vote>
</div>
<template id="Vote">
<div>
<h4>Vote</h4>
<component-a></component-a>
<component-b></component-b>
</div>
</template>
<template id="ComponentA">
<div>
<h4>子组件A</h4>
<p>a:{{a}}---b:{{b}}---num:{{num}}---m:{{obj.m}}</p>
<p>
<button @click="add(100)">自加</button>
</p>
</div>
</template>
<template id="ComponentB">
<div>
<h4>子组件B</h4>
<p>num:{{num}}---m:{{obj.m}}---x:{{x}}</p>
<p>
<button @click="reduce(100)">自减</button>
</p>
</div>
</template>
<script>
const ComponentA={
template:'#ComponentA',
inject:['a','b','num','obj','add','reduce']
}
const ComponentB={
template:'#ComponentB',
inject:['num','obj','add','reduce','x']
}
const Vote={
template:'#Vote',
components:{
ComponentA,
ComponentB
},
provide:{
x:10000
}
}
let vm=new Vue({
el:"#app",
components:{
Vote
},
data:{
num:10,
msg:"hello",
n:100,
obj:{
m:100
}
},
provide(){
console.log(this);
return {
a:100,
b:200,
num:this.num,
obj:this.obj,
add:this.add,
reduce:this.reduce
}
},
methods: {
add(n){
this.num+=n;
},
reduce(n){
this.num-=n;
}
},
})
</script>
</body>
</html>
这篇文章主要介绍了vue组件通信的六种方法,分别有例子,谢谢大家观看!!!
|