vue子父组件之间通信
September 18, 2021
7915
一、vue2.0
父 ==> 子 通信 (props、$refs、this.$children)
方式一:props:传值 单向绑定的,即只能父组件向子组件传递,不能反向。而传递的方式也分为两种:
方式二:**$ref** (可以调用子组件的方法跟改变属性值)
- 如果ref用在子组件上,指向的是组件实例,可以理解为对子组件的索引,通过$ref可能获取到在子组件里定义的属性和方法。
- 如果ref在普通的 DOM 元素上使用,引用指向的就是 DOM 元素,通过$ref可能获取到该DOM 的属性集合,轻松访问到DOM元素,作用与JQ选择器类似。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<!-- 父组件 -->
<template>
<div>
<h1>我是父组件!</h1>
<child ref="msg"></child>
</div>
</template>
<script>
import Child from '../components/child.vue'
export default {
components: {Child},
mounted: function () {
console.log( this.$refs.msg);
this.$refs.msg.getMessage('我是子组件一!')
}
}
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<!-- 子组件 -->
<template>
<h3>{{message}}</h3>
</template>
<script>
export default {
data(){
return{
message:''
}
},
methods:{
getMessage(m){
this.message=m;
}
}
}
</script>方式三:this.$children(应急用)
- 如果ref用在子组件上,指向的是组件实例,可以理解为对子组件的索引,通过$ref可能获取到在子组件里定义的属性和方法。
- 如果ref在普通的 DOM 元素上使用,引用指向的就是 DOM 元素,通过$ref可能获取到该DOM 的属性集合,轻松访问到DOM元素,作用与JQ选择器类似。
子 ==> 父通信 (**$emit**、this.$parent.event、函数绑定 )
方式一:$emit 在子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了(最常用)
不带参
1
vm.$emit( event, arg )
带参(子向父传值:this.$emit(“name”,“值”); 父接收:@name:name (自定义方法接收);)
1
2
3
4
5
6
7
8
9
10
11
12子组件:
<template>
<h3>我是子组件!</h3>
</template>
<script>
export default {
mounted: function () {
this.$emit('getMessage', '我是父组件!')
}
}
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25父组件:
<template>
<div>
<h1>{{title}}</h1>
<child @getMessage="showMsg"></child>
</div>
</template>
<script>
import Child from '../components/child.vue'
export default {
components: {Child},
data(){
return{
title:''
}
},
methods:{
showMsg(title){
this.title=title;
}
}
}
</script>
方式二:父组件把方法传入子组件中,在子组件里直接调用这个方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20父组件:
<template>
<div>
<child :fatherMethod="fatherMethod"></child>
</div>
</template>
<script>
import child from '~/components/dam/child';
export default {
components: {
child
},
methods: {
fatherMethod() {
console.log('测试');
}
}
};
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24子组件:
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
props: {
fatherMethod: {
type: Function,
default: null
}
},
methods: {
childMethod() {
if (this.fatherMethod) {
this.fatherMethod();
}
}
}
};
</script>方式三:this.$parent.event 直接在子组件中来调用父组件的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20父组件:
<template>
<div>
<child></child>
</div>
</template>
<script>
import child from '~/components/dam/child';
export default {
components: {
child
},
methods: {
fatherMethod() {
console.log('测试');
}
}
};
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16子组件:
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
methods: {
childMethod() {
this.$parent.fatherMethod();
}
}
};
</script>
二、vue3.0
父 ==> 子 通信 (props、$refs、this.$children)
父 ==> 孙 通信 (provide / inject)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22父组件中:
template:
<b><b>
import b from './b.vue'
import { reactive, provide } from 'vue'
components: {
b
},
setup () {
const mmm = reactive({
list: [
111,
222,
333
]
})
provide('mmm', mmm.list)
},1
2
3
4
5
6
7
8
9
10
11子组件中:
<template>
<c></c>
</template>
<script>
import c from './c.vue'
export default {
components: {
c
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22孙子组件中:
<template>
<ul>
<li v-for="(item, index) in list" :key="index">{{item}}</li>
</ul>
</template>
<script>
import { inject } from 'vue'
export default {
setup () {
const list = inject('mmm')
const parentClick = (e) => {
alert(1)
}
return {
list,
parentClick
}
}
}
</script>子 ==> 父通信 (emit、$parent.event 、函数绑定 )
方式一:emit 在子组件里用emit向父组件触发一个事件,父组件监听这个事件就行了(最常用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36父组件:
<template>
<!-- 父组件 -->
<div class="parent">
<Child :num="count" @handle="changeValue" />
<button @click="add">父组件的按钮</button>
</div>
</template>
<script lang="ts">
import Child from './components/child.vue'
import { defineComponent, reactive, toRefs } from 'vue'
export default defineComponent({
name: '',
props: {},
components: { Child },
setup () {
const state = reactive({
count: 1
})
const add = (): void => {
state.count += 1
}
const changeValue = (num: number) => {
state.count += num
}
return {
...toRefs(state),
add,
changeValue
}
}
})
</script>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26子组件:
<template>
<div class="child">
<h1> 父组件传入的值:{{ num }}</h1>
<button @click="changeParentNum('1111')">子组件的按钮</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'child',
props: {
num: Number
},
setup (props, ctx) {
const changeParentNum = () => {
// 通过ctx调用emit事件 需要注意的是Vue2.x中使用 $emit切勿混淆
ctx.emit('handle', 2)
}
return {
changeParentNum
}
}
})
</script>方式二:父组件把方法传入子组件中,在子组件里直接调用这个方法(同vue2.0)
方式三:**$parent.event** setup里面不支持直接使用this,使用getCurrentInstance 实例, 直接在子组件中来调用父组件的方法或者字段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20父组件:
<template>
<div>
<child></child>
</div>
</template>
<script>
import child from '~/components/dam/child';
export default {
components: {
child
},
methods: {
fatherMethod() {
console.log('测试');
}
}
};
</script>1
2
3
4
5
6
7
8
9子组件:
import { getCurrentInstance } from 'vue'
setup (props, ctx) {
const { proxy } = getCurrentInstance()
proxy.$parent.fatherMethod('我调用父亲') //调用父组件的方法
或者
proxy.$parent.state //调用父组件的属性
}
通过依赖注入实现父子组件数据共享(比如mitt)
- 本文作者:wowangmouren
- 本文链接:https://wangwewntao.top/2021/09/18/wmr_11/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!