-
Notifications
You must be signed in to change notification settings - Fork 434
[BUG]v8.0.0-rc.1,使用createDecorator创建自定义装饰器,如果用在多次继承的类里,会导致混乱 #548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
我把createDecorator方法里的源代码修改了一下,请参考 原代码: 修改后的新代码:
|
Had to use google translate to understand what is going on but this does solve the problem with inherited classes. |
There is a release final date for support vue 3 ? |
I don't know how to PR |
这里说中文,外国人看到懂吗。。。 |
代码文件: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
The text was updated successfully, but these errors were encountered: