facing-dev / vue-facing-decorator

Vue typescript class component decorators
MIT License
353 stars 31 forks source link

Need a mechanism to prevent some class properties being transformed to Vue data #98

Open ericlogic opened 8 months ago

ericlogic commented 8 months ago

Sometimes we don't need all of the class properties to be transformed to Vue data. Actually, I'm in trouble with three.js. When I define a Scene as a class property(It's a very common practice), It is transformed to Vue data and wrapped by Vue so it can't be rendered by three.js any more.

You might suggest that define it as a global variable. But it is not a "class style" way.

So. I suggest to provide a mechanism(maybe a @NonData decorator) to prevent some class properties being transformed to Vue data.

ruojianll commented 8 months ago

You could use vanilla accessors and WeakMap to map vue instance and JS native data.

const insMap = new WeakMap

class Foo .... {
@vanilla
get rawData(){
  if(!insMap.has(this)){
    insMap.set(this,{})
  }
  return insMap.get(this)
}
}
ericlogic commented 8 months ago

Thanks for your suggestion.

It works, but I don't think it's a elegant way. It's not "class style" and make the code a bit obscure. Is it possible to make @vanilla work on properties, just like this:

class Foo ... {
  @vanilla
  private nondata: number = 0;
}
ruojianll commented 8 months ago

It is possible. It may be implemented in next version, but I can't give you a certian time.

ruojianll commented 8 months ago

Keep this open until we implement the feature.

ruojianll commented 5 months ago

@ericlogic Did you try markRaw? https://vuejs.org/api/reactivity-advanced.html#markraw

ericlogic commented 5 months ago

I'm not using Vue Composition API at all. could you give me an example of how to use it in a class-style component. Thanks!

ruojianll commented 5 months ago

Just wrap your object with markRaw imported from vue wherever you use it.

import {markRaw} from 'vue'
import {...} from 'vur-facing-decorator'
@Component
class C extends Vue{
    field = markRaw(yourObject)
    onMounted(){
         //or
         this.field = markRaw(yourObject)
    }
}
ericlogic commented 1 month ago

Sory for my late reply. markRaw works, but only object is supported. It means I cannot wrap primary types with it.