在vue项目开发的过程中,经常会用到组件来管理不同的功能,有一些公共的组件会被提取出来,这时可能会产生一些疑问和需求?比如一个组件调用另外一个组件作为自己的组件,那么我们如何进行给子组件进行传值呢?
基于这种情况,本篇就介绍一下vue开发中常用的三种传值方式,父传子,子传父,非父子组件传值。
PS:这也是面试中比较常见的题目~
一、父传子,子传父
引用官网的一句话:父子组件的关系可以总结为props向下传递,事件向上传递。父组件通过props给子组件下发数据,子组件通过事件给父组件发送消息,如下图所示:
(1)从父组件向子组件传单个值,type为要传入值得类型,default是要传入值得初始值
父组件Parent.vue
<template>
<div>
<child :fatherMethod="fatherMethod"></child>
</div>
</template>
<script>
import Child from '../../components/Child.vue';
export default {
data() {
return {
name: 'Parent',
};
},
methods: {
fatherMethod() {
console.log('testing');
},
},
components: {
child: Child,
},
};
</script>
<style scoped>
</style>
子组件Child.vue
<template>
<div>
<button @click="childMethod">点击</button>
</div>
</template>
<script>
export default {
props: {
fatherMethod: {
type: Function, // 数据类型
default: null, // 初始值
},
},
data() {
return {
name: 'Child',
};
},
methods: {
childMethod() {
this.fatherMethod();
},
},
};
</script>
<style scoped>
</style>
(2)从父组件向子组件传多个值,这个时候要用一个数组接收
父组件Parent.vue
<template>
<div>
<child :fatherMethod="fatherMethod" :message="name"></child>
</div>
</template>
<script>
import Child from '../../components/Child.vue';
export default {
data() {
return {
name: 'Parent',
};
},
methods: {
fatherMethod() {
console.log('testing');
},
},
components: {
child: Child,
},
};
</script>
<style scoped>
</style>
子组件Child.vue
<template>
<div>
<button @click="childMethod">点击</button>
</div>
</template>
<script>
export default {
props: ['fatherMethod', 'message'],
data() {
return {
name: 'Child',
};
},
created() {
this.fatherMethod();
console.log(this.message);
},
methods: {
childMethod() {
this.fatherMethod();
},
},
};
</script>
<style scoped>
</style>
created函数中打印输出从父组件传入子组件的参数:
(3)从父组件向子组件传对象类型
父组件向子组件调接口动态传递对象值的时候会有一个问题,就是在子组件中会获取不到传入的数据,比如实例中的data对象,解决的办法就是添加一个监听器,这个很重要。
父组件Parent.vue
<template>
<div>
<child :fatherMethod="fatherMethod" :message="name" :data="data"></child>
</div>
</template>
<script>
import Child from '../../components/Child.vue';
export default {
data() {
return {
name: 'Parent',
data: {
name: '',
age: 0,
},
};
},
watch: {
data(newValue, oldValue) {
console.log(newValue, oldValue); // 监听器,监听对象
}
},
methods: {
fatherMethod() {
console.log('testing');
},
},
components: {
child: Child,
},
};
</script>
<style scoped>
</style>
子组件Child.vue
<template>
<div>
<button @click="childMethod">点击</button>
</div>
</template>
<script>
export default {
props: ['fatherMethod', 'message', 'data'],
data() {
return {
name: 'Child',
};
},
created() {
this.fatherMethod();
console.log(this.message);
console.log(this.data);
},
methods: {
childMethod() {
this.fatherMethod();
},
},
};
</script>
<style scoped>
</style>
二、子组件向父组件传值 ,通过$emit完成,以上述第一种情况为例
父组件Parent.vue
<template>
<div>
<child :fatherMethod="fatherMethod" v-on:backToParent="backToParent"></child>
</div>
</template>
<script>
import Child from '../../components/Child.vue';
export default {
data() {
return {
name: 'Parent',
};
},
methods: {
fatherMethod() {
console.log('testing');
},
backToParent(childValue) {
console.log(childValue); // 接收从子组件传回来的值
}
},
components: {
child: Child,
},
};
</script>
<style scoped>
</style>
子组件Child.vue
<template>
<div>
<button @click="childMethod">点击</button>
</div>
</template>
<script>
export default {
props: {
fatherMethod: {
type: Function, // 数据类型
default: null, // 初始值
},
},
data() {
return {
name: 'Child',
};
},
methods: {
childMethod() {
this.fatherMethod();
this.toParent(); // 给父组件传值
},
toParent() {
this.$emit("backToParent", this.fatherMethod);
}
},
};
</script>
<style scoped>
</style>
三、非父子组件进行传值