引言
使用 Vue2 实现一个复杂表格,允许用户可以删减每行表格,在单元格输入内容事,显示外边框。
实现思路:父组件是一个 table 标签,在 thbody 标签内引入子组件表示一行,每行数据都写在该子组件内。for 循环该子组件即可实现多行表格。
存在问题:要将父组件数据传递到子组件。子组件点击加减按钮时,要将数据和事件通知父组件,父组件再调用对应方法,根据传递来的数据在指定位置加减行。
正文
- 导入子组件
import UnitRow from './components/UnitRow.vue'
export default{
components: {
UnitRow
},
}
- 父组件引用
...
<tbody>
<unit-row
v-for="(unit, index) in units"
:key="index"
:index="index"
@onAddUnit="addUnit"
@onDeleteUnit="deleteUnit"
:count="units.length"
:unit="unit"
>
</unit-row>
</tbody>
...
解释:使用“:” + 变量名向子组件传递想要传递的值(unit 为 data 中定义的变量)。使用@ + 绑定事件名传递方法,等号后是得到通知时要调用的方法
addUnits(index){
this.units.splice(index + 1,0,{...} // 添加一行
},
deleteUnit (index) {
if (this.units.length > 1) {
this.units.splice(index, 1) // 删除一行
}
},
- 子组件接收和发送通知
export default {
props: {
unit: {
Object
},
index:{
Number
},
subjects: {
Array
},
count: {
Number
}
},
}
解释:使用 props 接收从父组件传来的数据,须指明数据类型
handleAddUnit() {
this.$emit('onAddUnit', this.index) // 调用父组件的 addUnit 方法
},
handleDeleteUnit() {
this.$emit('onDeleteUnit', this.index) ; // 调用父组件的 deleteUnit 方法
},
解释:使用 $emit 发布事件,在后面添加想要传递的参数。父组件通过订阅对应事件进行想要。
收获
了解了一种新的父子组件交互数据的方式,从前仅仅知道使用如 Vuex 以及 Pinia 这类第三方工具进行数据传递。加强了我对组件这一重要概念的理解,将一个大的页面拆分成一个个组件,逐个实现,大大加强了代码之间的解耦性和可读性。