Skip to content
This repository has been archived by the owner on Feb 7, 2024. It is now read-only.

inject[reactiveInjectKey] 的默认值问题 #401

Open
uwjiaoxing opened this issue Sep 11, 2021 · 1 comment
Open

inject[reactiveInjectKey] 的默认值问题 #401

uwjiaoxing opened this issue Sep 11, 2021 · 1 comment

Comments

@uwjiaoxing
Copy link

在文件 vue-property-decorator/src/helpers/provideInject.ts 中的函数 inheritInjected,inject 的默认值不应该是 () => ({}) 吗?

export function inheritInjected(componentOptions: ComponentOptions<Vue>) {
  // inject parent reactive services (if any)
  if (!Array.isArray(componentOptions.inject)) {
    componentOptions.inject = componentOptions.inject || {}
    componentOptions.inject[reactiveInjectKey] = {
      from: reactiveInjectKey,
      default: {},  // look here
    }
  }
}

这是一个低级错误,所以我以为作者可能是故意这么设计的,但想不出原因。

这个问题引发了我项目的一个BUG,父组件被刷新时,新的父子组件将会断开联系,InjectReactive 引用的是旧的父组件实例的值。

设计一个 demo 重现 BUG, 代码如下

const InjectKey = Symbol();

@Component
class ParentComponent extends Vue {
    @ProvideReactive(InejctKey) foo: any = 1;  

    created(){
      this.foo = Math.random()
    }
}

@Component
class ChildComponent extends Vue {
    @InjectReactive({
        from: InejctKey,
        default: 1
    })
    readonly foo!: any;
    mounted(){
      console.log(this.foo); // always a same number
    }
}
<template>
 ​<div
   ​<ParentComponent :key="key">
      <ChildComponent />
   </ParentComponent>
   ​<button @click="key = Math.random()">refresh</button>
 ​</div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'

@Component({ components: { ParentComponent, ChildComponent } })
export default class DemoPage extends Vue {
 ​key = 1;
}
</script>

修改 default 的值为 ()=>({}) 时,我的BUG将会消失。只是想不能作者的意图何在,望解惑。

@shamscorner
Copy link

Hi,
Do you know how to test @InjectReactive() on vue-test-utils? If you know anything about it, pls leave a comment.

Here is my child component:

@Component
export default class CarrierFilters extends Mixins(PreferencesMixin) {
  @InjectReactive() readonly serviceLevels!: CarrierFilterType[];
   // more code here...

Here is my test file:

describe('Settings > Preferences > Content > CarrierFilters.vue', () => {
  beforeAll(() => {
    PreferencesService.getUserPreferences = () => {
      return { ...mockPreferencesData };
    };
  });

  beforeEach(() => {
    options = {
      localVue,
      i18n,
      store,
      router,
      vuetify: new Vuetify(),
      provide: { // I am not sure how to provide the inject reactive data here...?
        __reactiveInject__: 'serviceLevels',
        serviceLevels: () => [...supportedServiceLevels],
      },
    };

    initWrapper = shallowMount(CarrierFilters, options);
  });
  // more code here...

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants