前言
vue的组件传值分为三种方式:父传子、子传父、非父子组件传值
引用官网的一句话:父子组件的关系可以总结为 prop 向下传递,事件向上传递
父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息,如下图所示:
下面我们就开始用代码(一言不合就上代码)详细的介绍vue组件传值的三种方式
1、父传子
子组件的代码:
<template>
<div id="container">
{{msg}}
</div>
</template>
<script>
export default {
data() {
return {};
},
props:{
msg: String
}
};
</script>
<style scoped>
#container{
color: red;
margin-top: 50px;
}
</style>
父组件的代码:
<template>
<div id="container">
<input type="text" v-model="text" @change="dataChange">
<Child :msg="text"></Child>
</div>
</template>
<script>
import Child from "@/components/Child";
export default {
data() {
return {
text: "父组件的值"
};
},
methods: {
dataChange(data){
this.msg = data
}
},
components: {
Child
}
};
</script>
<style scoped>
</style>
父传子的实现方式就是通过props属性,子组件通过props属性接收从父组件传过来的值,而父组件传值的时候使用 v-bind 将子组件中预留的变量名绑定为data里面的数据即可
2、子传父
子组件代码:
<template>
<div id="container">
<input type="text" v-model="msg">
<button @click="setData">传递到父组件</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: "传递给父组件的值"
};
},
methods: {
setData() {
this.$emit("getData", this.msg);
}
}
};
</script>
<style scoped>
#container {
color: red;
margin-top: 50px;
}
</style>
父组件代码:
<template>
<div id="container">
<Child @getData="getData"></Child>
<p>{{msg}}</p>
</div>
</template>
<script>
import Child from "@/components/Child";
export default {
data() {
return {
msg: "父组件默认值"
};
},
methods: {
getData(data) {
this.msg = data;
}
},
components: {
Child
}
};
</script>
<style scoped>
</style>
子传父的实现方式就是用了 this. e m i t 来遍历 g e t D a t a 事件,首先用按钮来触发 s e t D a t a 事件,在 s e t D a t a 中用 t h i s . emit 来遍历 getData 事件,首先用按钮来触发 setData 事件,在 setData 中 用 this. emit来遍历getData事件,首先用按钮来触发setData事件,在setData中用this.emit 来遍历 getData 事件,最后返回 this.msg
总结:
子组件中需要以某种方式例如点击事件的方法来触发一个自定义事件
将需要传的值作为$emit的第二个参数,该值将作为实参传给响应自定义事件的方法
在父组件中注册子组件并在子组件标签上绑定对自定义事件的监听
3、非父子
vue 中没有直接子对子传参的方法,建议将需要传递数据的子组件,都合并为一个组件
如果一定需要子对子传参,可以先从传到父组件,再传到子组件(相当于一个公共bus文件)
为了便于开发,vue 推出了一个状态管理工具 vuex,可以很方便实现组件之间的参数传递
4. 在vue2 中,我要在 A 组件里 引入B组件,并且 A组件可以调用 B组件里的 getlist方法
A组件,监听B组件的自定义事件(虽然这里不是直接调用getlist,但展示了如何监听事件),并通过父组件的方法间接调用B组件的getlist方法。
<!-- AComponent.vue -->
<template>
<div>
<BComponent @getlist-event="handleGetlistEvent" ref="bComponent" />
<button @click="callBComponentDirectly">Call BComponent Getlist Directly</button>
</div>
</template>
<script>
import BComponent from './BComponent.vue';
export default {
name: 'AComponent',
components: {
BComponent
},
methods: {
handleGetlistEvent() {
// 这里通常处理B组件触发的事件,但因为我们想直接调用getlist,所以这个方法可以留空或仅做日志记录
console.log('getlist-event received in AComponent');
},
callBComponentDirectly() {
// 直接调用B组件的getlist方法(推荐方式)
this.$refs.bComponent.getlist();
}
}
}
</script>
B组件:定义一个方法getlist,并触发一个自定义事件(虽然这里不是必须的,但为了说明完整性)
<!-- BComponent.vue -->
<template>
<div>
<!-- B组件的内容 -->
</div>
</template>
<script>
export default {
name: 'BComponent',
methods: {
getlist() {
// 执行获取列表的逻辑
console.log('getlist method in BComponent called');
// 可选:触发一个自定义事件(这里并不是为了调用getlist而触发,而是为了说明事件的使用)
this.$emit('getlist-event');
}
}
}
</script>