今天终于搞懂了Vue父子组件通信的做法。
需求是做几个自定义的条件选择框如下图:
那我就把单独的选择框抽出来做成一个组件方便复用。子组件 conditionBox
子组件定义如下:
conditionBox.vue
<template>
<div class="condition-box">
<!-- 标题 -->
<div>{{title}}</div>
<!-- 按钮们 -->
<button
class="condition-item"
:class="index == selectedIndex ? 'condition-item-selected' : ''"
@click="select(index)"
v-if="conditions"
v-for="(condition, index) in conditions"
>{{condition}}</button>
</div>
</template>
<script>
export default {
name: "condition",
props: {
//从父组件传来的条件标题
title: "",
//从父组件传来的条件数组
conditions: Array
},
data() {
return {
//被选中的条件编号
selectedIndex: 0
};
},
methods: {
/**
* 选择条件
* @param (int) 条件编号
*/
select: function(index) {
this.selectedIndex = index;
//在这里使用 this.$emit("事件", 参数...) 来进行子组件向父组件的通信
this.$emit("selectCondition", index);
}
}
};
</script>
<style lang="scss" scoped>
···
.condition-item {
width: 60px;
height: 30px;
margin: 0 6px;
background: transparent;
outline: none;
border: none;
font-size: 14px;
color: #333;
//按钮被选中时的样式
&-selected {
color: white;
background: green;
}
}
</style>
复制代码
父组件
父组件主要代码如下:
<template>
...
<!-- 在这里用 v-on:事件="函数" 来使父组件响应子组件里面的自定义函数,其中“事件”是子组件中定义的事件,函数是父组件用来响应子组建通信的函数,这里不用写参数-->
<!-- 使用 props 传递参数时,使用 参数名="参数" 时参数是普通 string 类型,使用 :参数名="参数" 时参数是动态 object 类型 -->
<conditionBox title="题目类型:" :conditions="questionTypes" v-on:selectCondition="selectType"/>
...
</template>
<script>
import conditionBox from "./ConditionBox";
export default {
...
components: {
conditionBox
},
data() {
return {
//题目类型
questionTypes: ["选择", "判断", "填空", "计算", "解答", "证明"],
},
methods: {
//这个函数用来相应子组件通信请求,参数名可以和子组件中定义的不同
/**
* 选择题目类型
* @param (int) 被点击的按钮索引
*/
selectType: function(id) {
console.log(id);
}
}
};
</script>
复制代码
接下来是重点
父组件向子组件传递数据
父组件向子组件传递数据的方式是通过props,只需两步即可搞定:
- 在子组件的props中定义想要接收的参数
props: {
//从父组件传来的标题
title: "",
//从父组件传来的条件数组
conditions: Array
},
复制代码
- 在父组件使用子组件时传递子组件需要的参数即可
<!-- 在这里用 v-on:事件="函数" 来使父组件响应子组件里面的自定义函数,其中“事件”是子组件中定义的事件,函数是父组件用来响应子组建通信的函数,这里不用写参数-->
<!-- 使用 props 传递参数时,使用 参数名="参数" 时参数是普通 string 类型,使用 :参数名="参数" 时参数是动态 object 类型 -->
<conditionBox title="题目类型:" :conditions="questionTypes"/>
复制代码
子组件向父组件传递数据
子组件向父组件传递数据需要使用自定义事件,只需三步即可搞定:
- 在子组件中需要向父组件传递数据的地方使用this.$emit("事件", 参数...) 来向父组件传递数据
/**
* 选择条件
* @param (int) 条件编号
*/
select: function(index) {
this.selectedIndex = index;
//在这里使用 this.$emit("事件", 参数...) 来进行子组件向父组件的通信
this.$emit("selectCondition", index);
}
复制代码
- 在父组件中定义接收子组件传来数据的方法
//这个函数用来相应子组件通信请求,参数名可以和子组件中定义的不同
/**
* 选择题目类型
* @param (int) 被点击的按钮索引
*/
selectType: function(id) {
console.log(id);
}
复制代码
- 在父组件使用子组件时,使用v-on:"事件"="方法"来规定子组件调用父组件中的哪个方法来向父组件传递数据
<!-- 在这里用 v-on:事件="函数" 来使父组件响应子组件里面的自定义函数,其中“事件”是子组件中定义的事件,函数是父组件用来响应子组建通信的函数,这里不用写参数-->
<conditionBox title="题目类型:" :conditions="questionTypes" v-on:selectCondition="selectType"/>
复制代码
这样就完成了Vue父子组件通信。