admin管理员组

文章数量:1400218

I'm writing a class using private fields:

export default class Foo {
    #bar;
    init(number){
        this.#bar = number;
    }
    getBar(){
        return this.#bar;
    }
}

I'm testing it in a vue ponent:

<template>
  <div class="hello">
    <div>{{bar}}</div>
  </div>
</template>

<script>
import Foo from '../api/foo.js';
export default {
  data(){
    return {
      foo: new Foo(),
      bar: '',
    }
  },
  mounted() {
    // doesn't work
    this.foo.init(2);
    this.bar = this.foo.getBar();
  },
}
</script>

But this code throws the following error:

Uncaught TypeError: attempted to set private field on non-instance
    at _classExtractFieldDescriptor (classExtractFieldDescriptor.js?06d5:3)
    at _classPrivateFieldSet (classPrivateFieldSet.js?9bd1:4)
    at Proxy.init (foo.js?c8b1:8)
    at Proxy.mounted (HelloWorld.vue?fdab:18)
    at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:6990)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?5c40:6999)
    at Array.hook.__weh.hook.__weh (runtime-core.esm-bundler.js?5c40:2270)
    at flushPostFlushCbs (runtime-core.esm-bundler.js?5c40:7191)
    at render (runtime-core.esm-bundler.js?5c40:5142)
    at mount (runtime-core.esm-bundler.js?5c40:3477)

It seems that I can't use my init() method on this.foo which is declared in my vue data member, but I can use a local variable and then set my data member:

  mounted() {
    // works
    const foo = new Foo();
    foo.init(2);
    this.bar = foo.getBar();
  },

Is this a normal behavior? Is there any ways to have this.foo.init(2) work?

I'm writing a class using private fields:

export default class Foo {
    #bar;
    init(number){
        this.#bar = number;
    }
    getBar(){
        return this.#bar;
    }
}

I'm testing it in a vue ponent:

<template>
  <div class="hello">
    <div>{{bar}}</div>
  </div>
</template>

<script>
import Foo from '../api/foo.js';
export default {
  data(){
    return {
      foo: new Foo(),
      bar: '',
    }
  },
  mounted() {
    // doesn't work
    this.foo.init(2);
    this.bar = this.foo.getBar();
  },
}
</script>

But this code throws the following error:

Uncaught TypeError: attempted to set private field on non-instance
    at _classExtractFieldDescriptor (classExtractFieldDescriptor.js?06d5:3)
    at _classPrivateFieldSet (classPrivateFieldSet.js?9bd1:4)
    at Proxy.init (foo.js?c8b1:8)
    at Proxy.mounted (HelloWorld.vue?fdab:18)
    at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:6990)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?5c40:6999)
    at Array.hook.__weh.hook.__weh (runtime-core.esm-bundler.js?5c40:2270)
    at flushPostFlushCbs (runtime-core.esm-bundler.js?5c40:7191)
    at render (runtime-core.esm-bundler.js?5c40:5142)
    at mount (runtime-core.esm-bundler.js?5c40:3477)

It seems that I can't use my init() method on this.foo which is declared in my vue data member, but I can use a local variable and then set my data member:

  mounted() {
    // works
    const foo = new Foo();
    foo.init(2);
    this.bar = foo.getBar();
  },

Is this a normal behavior? Is there any ways to have this.foo.init(2) work?

Share Improve this question edited Aug 31, 2021 at 12:48 Raphaël asked Aug 31, 2021 at 12:41 RaphaëlRaphaël 1902 silver badges13 bronze badges 3
  • 1 Can't reproduce your problem. Everything seems to be working fine here: codesandbox.io/s/petent-khorana-ij02n?file=/src/App.vue – Mythos Commented Aug 31, 2021 at 15:00
  • Thank you very much for your time, I'll look into it tomorrow. Maybe I misconfigured something. – Raphaël Commented Aug 31, 2021 at 15:51
  • indeed, it works with vue2 but not with vue3 : codesandbox.io/s/agitated-chatterjee-uohy9?file=/src/App.vue – Raphaël Commented Sep 1, 2021 at 8:13
Add a ment  | 

1 Answer 1

Reset to default 6

Thanks to Mythos, it appeared that it works with vue2 (example here) but not with vue3 (example here). After some digging, it looks like private members break proxies and that Proxy were introduced in vue3 for ponents' data function :

When we return a plain JavaScript object from a ponent's data function, Vue will wrap that object in a Proxy (opens new window)with handlers for get and set. Proxies were introduced in ES6 and allow Vue 3 to avoid some of the reactivity caveats that existed in earlier versions of Vue.

本文标签: