- 20020-03-03
最近在用vue写canvas小游戏,为了方便维护,还是按照面向对象的思路写的,把不同对象分成了各种组件,最后统一在父组件绘图, 在设置监听器的时候遇到了传参的问题,记录一下
一、需求
为了方便说明先介绍一下即将要出场的组件:
父组件index、子组件person、子组件listener,其他的组件略过。
目前的需求是在两个子组件中进行通信,由于通信不太多而且有一部分数据父组件也需要,所以最后决定用emit实现(如果有更高效并且合适的子组件通信方法也请评论告诉我)。
所以我的问题就是person传给listener的参数是不确定的,为了提高复用性,我决定不把参数写死,以下是我的解决方法:
二、解决方法
- 子元素person给父元素传参非常简单:
this.$emit('callLisenter', x, y, width, height)
- 父元素接受固定的参数也非常简单:
callLisenter(x, y, width, height){
console.log(x, y, width, height);
}
- 如果想要获取不确定的参数,就可以使用到arguments(形参)
arguments非常好用,他类似数组,可以适用下标获取对应位置的参数,比如可以使用 arguments[0] 获取到 x,arguments[1] 可以获取到 y
callLisenter(){
console.log(arguments);
console.log(arguments[0], arguments[1], arguments[2], arguments[3]);
}
- 但是我们如果直接这样传给子组件listener,在子组件内部使用arguments[0],arguments[1] 获取参数这样不仅不直观,而且也不便于维护。
突然~ 我灵光一闪,使用解构赋值,可以获取不固定数量的参数
arguments类似于数组,但不是真正的数组,许多数组方法无法使用,所以首先我们需要将他转换成真正的数组来处理:
callLisenter(){
let arr = Array.prototype.slice.apply(arguments)
console.log(arr);
}
- 在子组件listener中,我们利用es6的解构赋值,就可以很方便直观的获取到对应的数据
getPerson([x, y, width, height]){
console.log(x, y, width, height);
}
- 一切都非常完美,但是为了更高的复用性,我们可以把调用另一个子组件的方法名也设置成动态的,最终实现方法如下:
// 子组件 person
this.$emit('callLisenter', 'getPerson', x, y, width, height)
// 父组件 index
callDropDown (name) {
let arr = Array.prototype.slice.apply(arguments)
arr = arr.splice(1, arr.length - 1)
this.$refs.listener[name](arr)
}
// 子组件 listener
getPerson([x, y, width, height]){
console.log(x, y, width, height);
}