类中的vue3反应性

Posted

技术标签:

【中文标题】类中的vue3反应性【英文标题】:vue3 reactivity inside a class 【发布时间】:2021-09-09 22:50:52 【问题描述】:

我试图在一个类中拥有一个反应性属性,所以这就是我所做的:

Class B
  index = ref(-1);

  canUndo: ComputedRef<boolean>;

  canRedo: ComputedRef<boolean>;

  constructor(private max: number) 
    this.canUndo = computed(() => 
      return this.index.value > -1;
    );
    this.canRedo = computed(() => 
      const  length  = this.items;
      return length > 0 && this.index.value < length - 1;
    );
  

  undo() 
    console.log(this.canUndo); // -> true
    console.log(this.canUndo.value); // -> undefined
    if (!this.canUndo.value) return false;

    console.log(this.index); // -> 1
    this.index.value -= 1;
    return this.items.slice(0, this.index.value + 1);
  
  


// this is how I use it
class A
  b:B;

  undo() this.b.undo() 


export default defineComponent(
  setup()
    const a= ref<A>();

    function initA() 
      a.value = new A();
    

    return  a ;
  
);
<BaseButton
        :disabled="!a.b.canUndo"
        color="light" size="sm" @click="a.undo()"
        start-icon="undo"></BaseButton>

我原以为这会起作用,但我看到了一个奇怪的行为!this.canUndoboolean,我预计是 ComputedRef&lt;boolean&gt;,因此 this.canUndo.valueundefined

this.index?!? 也是如此?

为什么?难道我做错了什么?这是一个错误吗?

根据@tony19 的回答更新: 组件其实是这样的:

export default defineComponent(
  setup()
    const elRef = ref<htmlElement>();
    const a = ref<A>();

    function initA() 
      a.value = new A(elRef);
    

    onMounted(initA);

    return  a ;
  
);

我无法执行任何建议的解决方法因为我需要一个元素 ref 来实际启动类,所以它需要在 onMounted 钩子中启动。

【问题讨论】:

【参考方案1】:

我认为这与refs 如何在模板as noted in setup() docs 中自动解包有关。这似乎包括在类的方法中解开 refs。

一种解决方法是将原始实例公开给模板。它不需要是 ref,除非您打算更改它的值(例如,更改为 A 的新实例):

export default defineComponent(
  setup() 
    //const a = ref<A>(new A())
    const a = new A()

    return  a 
  
)

如果您确实需要保留ref,则可以将ref 与原件一起公开:

export default defineComponent(
  setup() 
    const rawA = new A()
    const a = ref<A>(rawA)

    return  a, rawA 
  
)

然后在您的模板中,将原始用于任何具有refs 的方法:

<BaseButton @click="rawA.undo()">

【讨论】:

tnx 回复,很遗憾不能做这些,添加了更多信息来发布,请检查一下,我使用 ref 的唯一原因是因为 A 类的初始化较晚

以上是关于类中的vue3反应性的主要内容,如果未能解决你的问题,请参考以下文章

在 vue3 中导入外部组件和松散的反应性

来自 reactive() 的 Vue3/Vuex 对象一旦在突变中作为有效负载传递给 vuex,就会失去反应性

多个 Vue 应用程序,多个入口文件,相同的 Vuex/Vue3CompostitionApi 存储 [失去反应性]

未从类实例内部触发 Vue 3 反应性

Vue 3 通过双向绑定将反应对象传递给组件

如何使 Vue 3 对象属性具有反应性