Description
代码文件:prop.ts
import { createDecorator } from 'vue-class-component'
function createProp(params:any, target: any, propertyKey: string,descriptor?: PropertyDescriptor){
createDecorator(function (options, key) {
if(!options.props){
options.props = {}
}
const props = options.props
if(descriptor && typeof params.default === 'undefined'){
params.default = function(){ return descriptor.value }
if(options.methods){
delete options.methods[key]
}
}
//添加新的prop 到 options.props里
props[key] = params
})(target, propertyKey);
}
export function Prop(params?:any):any;
export function Prop(target: any, propertyKey: string):void;
export function Prop(target: any, propertyKey: string,descriptor: PropertyDescriptor):void;
export function Prop(target: any={}, propertyKey="",descriptor?: PropertyDescriptor):void | any {
if(propertyKey){
createProp({},target,propertyKey,descriptor)
}else{
const params = target;
return function (target: any, propertyKey: string,descriptor?: PropertyDescriptor) {
createProp(params,target,propertyKey,descriptor)
}
}
}
代码文件:my-test-input.vue
<template>
<div></div>
</template>
<script lang="ts">
import { Vue} from 'vue-class-component';
import { Prop } from '@/lib-ref/vue-class';
class MyTestSuper extends Vue {
@prop({
type:String,
default:'MyTestSuper'
})
declare readonly label:string
}
class MyTestBase1 extends MyTestSuper {
@prop({
type:String,
default:'MyTestBase1'
})
declare readonly label:string
}
export default class MyTestInput extends MyTestSuper {
}
</script>
测试文件:Test.vue
<template>
<div class="test">
<my-test-input ref="testComp" ></my-test-input>
<el-button @click="test">测试</el-button>
</div>
</template>
<script lang="ts">
import { Options,Vue } from 'vue-class-component';
import { refs} from '@/utils/app-utils';
import MyTestInput from '@/components/my/my-test/my-test-input.vue';
@Options({
components:{
MyTestInput
}
})
export default class Test extends Vue {
test(){
const testComp = refs(this,'testComp')
console.log('testComp label',testComp.label)
}
}
</script>
使用createDecorator方法定义了一个新的装饰器:Prop
MyTestSuper 类是基类
MyTestBase1 和 MyTestInput 都继承MyTestSuper 类
MyTestBase1 类里覆盖了MyTestSuper 类的 label属性定义
在测试页面点击按钮测试。
**实际输出的 label 值 是 'MyTestBase1' **
期望输出的 label 值应该是 MyTestInput 的父类MyTestSuper 里定义的 默认值:'MyTestSuper'
经过调试源码发现,createDecorator 方法里 是把 工厂函数 factory,添加到 类的构造函数的 __d 属性里,
但因为多重继承的原因,createDecorator 里取到的 Ctor.__d 都是基类 MyTestSuper 的引用,而非重新创建的数组。
所以,所有子类 使用 自定义装饰器 都 添加了一条记录到 基类的 __d里了。而子类是引用的 基类 __d,导致
MyTestSuper 的所有子类里定义的prop 都应用到所有子类,即便是非直接继承的类。
附上源代码文件:
bug-src.zip