vuejs / core

πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
46.94k stars 8.24k forks source link

using object factory and class factory to support class component #2689

Closed John0King closed 3 years ago

John0King commented 3 years ago

What problem does this feature solve?

vue3 is writing using typescript , but it seems your team do not want we to use typescript to write vue app, today it's harder to use typescript with a non-class style object data define to define a component. and I don't know why your team is reject typescript as your first class language support. and maybe because the metadata standard not finish yet, but I want to say is that without metadata support in ES we can even use it now , that means that no matter what happened , metadata work for now will work tomorrow too ! and my idea is to use a factory to get component, if you do not want the metadata then make the factory can be replaced. eg. default vue3.js only use object component factory, and with class support library , that replace with a two type factory (class factory + object factory).

why use a factory ?

because we can stop map class to object and then we can get a clear class component without mix the object component behaviors.

in object component (I called it data configure style instance) , you try to hide the lifetime method, and in class there are no need ( the factory active the method and any lifetime stuff is doing in factory instead of class lifetime ). ts

export class MyComponent implement {  // stop using export default  please

     @Prop("inValue")
     inValue:string = "abc" // no don't need map to object data , so we get class default value too. and the `type` we can use typeof() in class factory
 }

and for js users

export class MyComponent {

}
__decorator([
Prop("inValue",  ) // this is just a propototype , and we should see how typescript add metadata
],MyComponent.prototype, "invalue", null)

the good thing with type component

with ref component

export class MyComponent{
    @Ref('xComponent')
    xComp!: XComponent

  dothing():void{
    this.xComp.<methodName> // we don't have too search document again.
 }
}

other change

mixin and vuex repalce with service (maybe we need rxjs to resolve the changing event).

@Servers(Lifetime.Singleton)
export class CartService{
   cartNumber:number = 0;

   addCartItem(item:CartItem){
       .....
       cartNumber += 1;
    }
}

using

export class MyComponent{

   @InjectService(CartService)  // this should mark the class factory to observe event from CartService too
    private cartService!:CartService  

}

What does the proposed API look like?

import { ClassFactory } from  "vue-class"
Vue.Factory = ClassFactory // default is `ObjectFactroy` from "vue"
edison1105 commented 3 years ago

see https://github.com/vuejs/vue-class-component But there is still some difference from what you expected

posva commented 3 years ago

Vue 3 supports typescript out of the box. It doesn't require class or decorator usage but you can with the mentioned libraries if you want to. The reasoning behind this has been extensively discussed during the composition API RFC. You can take a look at the rfcs repo to read about it

John0King commented 3 years ago

@posva I do not care about composition API, and @edison1105 I know that repo ( and it's different than my proposal, it map class to use js object like api and it will missing many decorators in vue-property-decorator for vue3, and my proposal is about direct support class component instead of mapping , and with this we can have great typescript support for coding experience ) . if you try use typescript (not anyscript) you will find that to use vue3 with typescript is hard , and it doesn't provide the benefit that typescript have, for example the ref component, can it have intellsence for the js data reconfigured component (also composition API, and also jsx/ tsx) ? and with this proposal the class will work both for js and ts , and all those thing will became standard for IDE to support intellsence .

and by the way , the composition is a good idea, but we do not need dynamic composition for component (any component we write is static , no member/method will be dynamic add/remove, with current implementation , it hard to to get the type of it , but if we use class, then we can use inherit , then the type will be fixed). Angular also have composition , it provide composition via DI , property and rxjs to achieve that. "react" also use class to describe the component , and it has class memeber, so when you use tsx , it has great experience to work with typescript.

and @posva have you try to write a vue3 app that fully use typescript ? and have you try react or Angular ? don't you think that with typescript vue core, it's still hard to fully use typescript to write vue (you can but does the type system in typescript provide any advantage? or just became a burden)

please consider the possibility of this proposal instead of reject this immediately , because this won't effect current js like api

// mixed factory
if(component instanceof Object){
    ObjectFactory.doItsWork();
}
else{
    ClassFactory.doItsWork();
}
posva commented 3 years ago

The things you propose have been discussed already and that's why there is an officially supported library vue-class-component. As a maintainer, I would appreciate if you search existing RFCs https://github.com/vuejs/rfcs before opening this kind of proposals, it would really save us time πŸ™‚

edison1105 commented 3 years ago

I can also understand your thoughts very well. For back-end development, using classes, factories, decorators, etc. has become a habit (I am also very inclined to your opinion). Vue3 also tried the class api at the beginning, but finally gave up, partly because there are many features that are still in the proposal stage and are unstable, such as decorators. The class api can be seen in the initial code submission. Perhaps these ideas you mentioned will be added in a future version.Angular has better support for typescript, more like a strongly typed language. But the cost is too high for beginners. After all, there are still relatively few masters like you.

edison1105 commented 3 years ago

You can take a look at this if you are interested. https://github.com/vuejs/rfcs/pull/17 and https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121

John0King commented 3 years ago

@edison1105 @posva I read that a few month ago, that's why I open a new issue instead of talking in that closed issue again. and it seems that you and your team is hate class for some reason, but IMO I like class because it provide best language feature and most consistent API surface (there no other way to describe the property and methods, but there will be many way that without class eg. composition API and data() method , setup() method ).

edison1105 commented 3 years ago

@edison1105 I read that a few month ago, that's why I open a new issue instead of talking in that closed issue again. and it seems that you and your team is hate class for some reason, but IMO I like class because it provide best language feature and most consistent API surface (there no other way to describe the property and methods, but there will be many way that without class eg. composition API and data() method , setup() method ).

I also prefer class api, but it is really not supported yet.And,unfortunately, I am only a contributor, not a team member 😭. I have been paying attention to issues recently because I have some time.

John0King commented 3 years ago

@edison1105 sorry that I @ for wrong person, I should @posva instead.

edison1105 commented 3 years ago

@edison1105 sorry that I @ for wrong person, I should @posva instead.

oh~ ,this is more embarrassing.πŸ˜†πŸ˜†πŸ˜†