Richard's Blog

在vue组件中实现属性透传

字数统计: 753阅读时长: 2 min
2019/08/06 Share

在 React 中属性透传是一件很随意的事,只要在某个子组件上写上{...this.props}就能简单的实现属性透传,这对封装第三方组件非常友好。

在 Angular 中没有尝试过,但是想了一下似乎可以通过ViewChild和继承被扩展类来实现属性透传。

最近在 Vue 项目中遇到了一个类似的需求,但是百度了一会似乎没什么文章说这个问题,虽然有关 vue 的 HOC 相关文章不少,但是我遇到的需求和 HOC 还有点不太一样。

需求是使用 iView 组件库,其中当使用Upload组件时必须在请求的 body 中传递固定的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<Upload :data="body"/>
</template>

<script>
export default {
data() {
return {
body: {
'system': 'mySystem'
}
}
}
}
</script>

像上面这样的代码不想每次都写:data="body"这样的代码,封装的想法还是有的。比如可以把data封闭到 mixin 里,但是Upload组件每次还要记得写:data="body",也要记得写 mixins 才不会出错,最好是能把Upload包装成自己的组件,然后组件内部定义好Upload需要的默认的属性。

这样还不够,因为只是单纯的对Upload进行封装,Upload组件上原有的属性和事件最好也能直接使用。

这里就需要进行属性透传。假设我  要把Upload封装到MyUpload组件中,MyUpload组件的属性和事件至少应该与Upload组件上的属性和事件一一对应,如果名字一样就更好了,这样说明文档都省了,直接看 iView 的就行了。

关于这个想法我咨询了很有经验的同事,同事跟我说需要用 vue 的方法写 JXS,我以为是一种类似 React 里的 JXS 那样写,只是可能步骤上有些出入,业余时间研究了几天感觉不太对。后来渐渐看到 HOC 相关的内容,感觉应该差不多是这个。

但是在 HOC 的文章中,作者都会定义一个方法,接收一个组件,返回一个被扩展的组件,而我需要的仅仅只是一个扩展好的组件,能直接将这个组件注册到全局中或者在局部被父组件引用,不需要再传入返回这些操作。但是感觉方向上和 HOC 是一致的,于是开始尝试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
import { Upload } from 'iview';
export default {
name: 'MyUpload',
props: Upload.props,
render(h) {
return h(Upload, {
on: this.$listeners,
attrs: this.$attrs,
props: {
...this.props,
data: this.data || {
'system': 'mySystem'
}
},
scopedSlots: this.$scopedSlot
})
}
}
</script>

h函数就相当于createElement函数,官网有详细介绍。这样创建的MyUpload组件其实就是把Upload组件包装了一下,Upload原本的属性事件都能直接用在MyUpload上,并且为自己定制了data的默认属性。

CATALOG