Open bitjjj opened 3 years ago
The scenario is following: <--BaseDlg.ts-->
import { Options, Vue } from "vue-class-component"; import { Model, Watch } from "vue-property-decorator"; @Options({ name: "BaseDlg", }) export default class BaseDlg extends Vue { @Model("modelValue", { type: Boolean, default: false }) visible!: boolean; @Watch("visible") visibleValueChanged(newVal: boolean): void { console.log("visible==?0", newVal); } }
<--Test1.vue-->
<template> <div class="hello"> <ul>{{ msg }}</ul> </div> </template> <script lang="ts"> import { Options } from "vue-class-component"; import { Prop, Watch } from "vue-property-decorator"; import BaseDlg from "BaseDlg"; @Options({ name: "Test1", }) export default class Test extends BaseDlg { @Prop(String) msg!: string; @Watch("msg") msgChanged(newVal: string): void { console.log("Test1-msg-changed", newVal); } beforeMount(): void { console.log("Test1==>", this.msg); } } </script>
<--Test2.vue-->
<template> <div class="hello"> <ul>{{ msg }}</ul> </div> </template> <script lang="ts"> import { Options } from "vue-class-component"; import { Prop, Watch } from "vue-property-decorator"; import BaseDlg from "BaseDlg"; @Options({ name: "Test2", }) export default class Test extends BaseDlg { @Prop(String) msg!: string; @Watch("msg") msgChanged(newVal: string): void { console.log("Test2-msg-changed", newVal); } beforeMount(): void { console.log("Test2==>", this.msg); } } </script>
<--App.vue -->
<test1 v-if="showTest" :msg="msg2" /> <test2 v-if="showTest" :msg="msg2" />
================================ The issue is that decorators[@Prop / @Watch] in the last loaded [Test1.vue or Test2.vue] file will not take effect.
The reason is createDecorator function in helpers.ts line 37:
if (!Ctor.__d) { Ctor.__d = [] }
When you use Ctor.__d for checking property if existed in object, 'in' operator will also check prototype chain.
But in vue.ts the following code use getOwn function to fetch __d property:
const decorators = getOwn(Ctor, '__d')
This will produce very strange behaviour in the scenario described above.
You should also use getOwn for checking __d property in Ctor.
vue-class-component:^v8.0.0-rc.1 vue-property-decorator: ^v10.0.0-rc.3 vite: ^2.0.5 vue: ^3.0.5
The scenario is following: <--BaseDlg.ts-->
<--Test1.vue-->
<--Test2.vue-->
<--App.vue -->
================================ The issue is that decorators[@Prop / @Watch] in the last loaded [Test1.vue or Test2.vue] file will not take effect.
The reason is createDecorator function in helpers.ts line 37:
When you use Ctor.__d for checking property if existed in object, 'in' operator will also check prototype chain.
But in vue.ts the following code use getOwn function to fetch __d property:
const decorators = getOwn(Ctor, '__d')
This will produce very strange behaviour in the scenario described above.
You should also use getOwn for checking __d property in Ctor.