vue

vue的几种传值方式与demo代码

vue的几种传值方式

Posted by John Doe on 2021-01-08
Words 1.4k and Reading Time 8 Minutes
Viewed Times

⽗⼦组件传值

几种传值方式

  • props / $emit
    ⼦组件中通过定义props接收⽗组件中通过v-bind绑定的数据
    ⽗组件中通过监听⼦组件中$emit的⾃定义事件接收数据
  • $parent / children
    ⼦组件中通过this.$parent这个对象获取⽗组件中的数据
    ⽗组件中通过this.$children这个数组获取⼦组件中的数据
  • $ref
    ⽗组件中定义⼦组件中的ref属性后,通过this.$refs.定义的属性名获取⼦组件数据

props / $emit

⼦组件中通过定义props接收⽗组件中通过v-bind绑定的数据
Parent.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<div>
<h1>Parent</h1>
<my-child v-bind:msg="'form Parent msg'"></my-child>
</div>
</template>

<script>
import MyChild from "./Child";
export default {
components: {
MyChild
}
};
</script>

<style scoped>

</style>

Child.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div>
<h3>Child</h3>
<h5>{{msg}}</h5>
</div>
</template>

<script>
export default {
props: {
msg: {
type: String,
default: ""
}
}
};
</script>

<style scoped>

</style>

传值结果:
父组件传值prop接收

子组件通过$emit传值给父组件
Parent.vue

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
<template>
<div>
<h1>Parent</h1>
<h3>{{msg}}</h3>
<my-child v-bind:msg="'form Parent msg'" @showMsg="showMsg"></my-child>
</div>
</template>

<script>
import MyChild from "./Child";
export default {
data() {
return {
msg: ''
}
},
components: {
MyChild
},
methods: {
showMsg(val) {
this.msg = val
}
}
};
</script>

<style scoped>

</style>

Child.vue

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
<template>
<div>
<h3>Child</h3>
<h5>{{msg}}</h5>
<button @click="passMsg">向父组件传值</button>
</div>
</template>

<script>
export default {
props: {
msg: {
type: String,
default: ""
}
},
methods: {
passMsg() {
this.$emit('showMsg', 'i am from child')
}
}
};
</script>

<style scoped>

</style>

传值结果:
子组件$emit传值
子组件$emit传值

$parent / children $ref

⼦组件中通过this.$parent这个对象获取⽗组件中的数据
⽗组件中通过this.$children这个数组获取⼦组件中的数据

1
2
3
4
mounted() {
console.log(this.$children)
console.log('ref',this.$res.child)
}

⾮⽗⼦间传值

事件总线

1
2
3
4
5
6
7
8
9
10
11
12
// 原理上就是建⽴⼀个公共的js⽂件,专⻔⽤来传递消息
// bus.js
import Vue from 'vue'
export default new Vue;
// 在需要传递消息的地⽅引⼊
import bus from './bus.js'
// 传递消息
bus.$emit('msg', val)
// 接受消息
bus.$emit('msg', val => {
console.log(val)
})

App.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<div id="app">
<button @click="passMsg">非父子传值App->Child</button>

<router-view/>
</div>
</template>
<script>
import bus from './util/bus'
export default {
methods: {
passMsg() {
bus.$emit('msg','this is from App')
}
},
}
</script>

Child.vue

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
37
38
39
40
41
<template>
<div class="child">
<h2>This is a child page</h2>
<h3>{{msg}}</h3>
<h4>{{childMsg}}</h4>
<button @click="passtoParent">子向父传值</button>
</div>
</template>
<script>
import bus from '../util/bus'
export default {
//父向子传值
props:{
msg:{
type:String,
default:''
}
},
data() {
return {
childMsg: 'childMsg'
}
},
methods:{
passtoParent(){
this.$emit('showMsg','this is from child')
}
},
mounted () {
// bus.$on监听
bus.$on('msg',(val)=>{
this.childMsg=val
});
},
}
</script>
<style lang="css" scoped>
.child{
background-color:red;
}
</style>

$attrs / $listeners

App.vue

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
<template>
<div id="app">
<button @click="passMsg">非父子传值App->Child</button>
<Parent :msg='a' :msg2='b' :msg3='c'></Parent>//改动
<router-view/>
</div>
</template>


<script>
import bus from './util/bus'
import Parent from './views/Parent'
export default {
//改动
data() {
return {
a: 'msga',
b: 'msgb',
c: 'msgc',

}
},
components:{
Parent
},
methods: {
passMsg() {
bus.$emit('msg','this is from App')

}
},

}
</script>

Child.vue

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
37
38
39
40
41
42
43
44
45
46
<template>
<div class="child">
<h2>This is a child page</h2>
<h3>{{msg}}</h3>
<h4>{{childMsg}}</h4>
<button @click="passtoParent">子向父传值</button>
</div>
</template>

<script>
import bus from '../util/bus'
export default {
//父向子传值
props:{
msg:{
type:String,
default:''
}
},
data() {
return {
childMsg: 'childMsg'
}
},
methods:{
passtoParent(){
this.$emit('showMsg','this is from child')
}
},
mounted () {
//改动
console.log('attrs',this.$attrs),
// bus.$on监听
bus.$on('msg',(val)=>{
this.childMsg=val
});
},
}
</script>

<style lang="css" scoped>
.child{
background-color:red;
}

</style>

Pqarent.vue

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
<template>
<div class="parent">
<div>this is a parent page</div>
<h1>{{msg}}</h1>
<!-- 改动-->
<Child v-bind:msg="'from parent'" @showMsg="showMsg1" ref="child" v-bind="$attrs"></Child>
<!-- @showMsg="showMsg1"监听事件 -->
</div>
</template>

<script>
import Child from './Child'


export default {
data(){
return{
msg:''
}

},
components: {
Child
},
methods:{
showMsg1(val){
this.msg=val
}
},
mounted () {
console.log(this.$children[0].childMsg);
console.log('ref',this.$refs.child)
},
}
</script>


This is copyright.

...

...

00:00
00:00