首先在ts中属性、模板名字等都有个横杠和大写的转换的,比如父组件中是 <color-drawer>
,则子组件的名字是ColorDrawer.vue
其次在ts中全部都需要用装饰器说明下面的内容是啥(是组件、还是信号发射器、还是prop属性等),所以必须引入装饰器:import { Component, Prop, Vue, Emit, Mixins, Watch } from 'vue-property-decorator'
接下来就是在父组件中引入子组件,并且注册组件,引入组件和js中是一样的。
import ColorDrawer from './moudle/ColorDrawer'
注册则需要在component装饰器下面,注意这里有两层component,漏掉一个会导致错误TS2769: No overload matches this call.
并且注意这个@Component 是装饰器,用来装饰 下面的class ColorFather的,装饰器和被装饰类之间不能插入其他语句,否则会报错Decorators are not valid here
//这是父组件
@Component({
components: {
ColorDrawer
}
})
export default class ColorFather extends Mixins(UploadMixin){
}
然后创建子组件之后就可以在父组件引用了,但是如果不是单一的展示,比如这里的子组件是一个抽屉,那还要控制子组件的打开关闭/抽屉的内容。这时候就需要父组件朝子组件传递值或函数。注意,也就是父组件往:color-list传递test值,子组件的prop为ColorList赋值test。
<color-drawer
:color-list="test"
@ok="ok"
/>
子组件prop修饰并且监听类型,这里是object类型的一个字典序列,子组件模板内部就可以任意使用test值,和子组件自身自定义的data一样,但是不能进行修改:
@Prop({
type: Object,
required: true,
default: () => ({})
}) private test!: any
当然如果父组件传递的是函数,则也相当于子组件多定义了传递进去的函数.
// 父组件
<child :before-upload="test"></child>
// ts部分
test (file: any) {
if (file.size < 1024 * 1024) {
return false
}
else
return true
}
也就是子组件内部可以自由调用这个函数。
@Prop(uploadProps.test)
public test!: Function
// 组件内部
ChildTest (file: any) {
if (this.test(file)) {
// 调用父组件传入的test的结果完成内容
}
最后就是子组件像父组件传递值。注意emit除了绑定一个信号之外,还一定要绑定一个函数,这个test函数是可以反复使用的,意思是只要在子组件中遇到test函数,就会发送bindSend的信号。这里传递的参数是msg。
@Emit('bindSend') test(msg: string){}; // send 处理给父组件传值的逻辑
父组件通过自定义的方法bindSend接收传递的参数msg,并且触发函数propMsg,msg默认为传递过来的参数。
<Child @bindSend="propMsg"/>
propMsg(msg: string){
this.msg = msg;
}
当然@bindSend="propMsg"
是省略的写法,当只有一个参数是等价于@bindSend='propMsg($event,userDefined)'
,如果没有用户自定义的userDefined就是@bindSend="propMsg"
。
但是当参数有两个或以上的参数时相当于@bindSend='propMsg(arguments,userDefined)'
,只是这个时候arguments变成了数组。此时接收的msg是数组,并且msg[0]是其中第一个参数,以此类推。