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

Vue 3.0 support #294

Closed
avxkim opened this issue Jan 5, 2020 · 93 comments
Closed

Vue 3.0 support #294

avxkim opened this issue Jan 5, 2020 · 93 comments
Labels

Comments

@avxkim
Copy link

avxkim commented Jan 5, 2020

Hi, do you plan to support this project when 3.0 arrives? Or the Vue core team would integrate classes API natively?

@kaorun343
Copy link
Owner

@webcoderkz

Hi.
This library depends on vue-class-component. If vue-class-component supports v3.0 and it provides an API for third party libraries including vue-property-decorator, I will continue maintaining this library.

@kaorun343
Copy link
Owner

In my humble opinion, the new api, the composition api is much better than the class style syntax.

@kaorun343 kaorun343 pinned this issue Feb 5, 2020
@GerardSmit
Copy link

Fyi, vue-class-component will support Vue 3. See vuejs/vue-class-component#402 (comment) for more information.

@avxkim
Copy link
Author

avxkim commented Apr 6, 2020

Yeah, they are going to support classes in 3.0, even make a bridge for composition API, what do you think @kaorun343

@haoqunjiang
Copy link

vue-class-component v8.0.0-alpha.2 has been released to support Vue 3.
Any plans for this package to move along?

@haoqunjiang
Copy link

https://github.com/vuejs/vue-class-component/tree/next

@CharlieBrownCharacter
Copy link

Any news on this? If you wouldn't support Vue 3 some people would have to switch to other class based component alternative. Could you let us know, please

@zischler
Copy link

@kaorun343 any updates? I'm currently starting to migrate everything to the newest Vue 3 beta in my boilerplate, which I use for all my projects.

@sunhao0313
Copy link

stay tuned @kaorun343

@Karnith
Copy link

Karnith commented Sep 20, 2020

Vue 3 released yesterday.

@BoBoooooo
Copy link

Looking forward to update !

@kosratdev
Copy link

@kaorun343 do you have any plan to support Vue.js 3?

@wtho
Copy link

wtho commented Oct 12, 2020

For everyone interested, the Prop decorator will probably go away, as heavily discussed currently in vue-class-component repo (see Link below).

As explained in some of these issues, the decorator has to go away to enable type completion for props inside templates of other components using TSX, which I think is an awesome feature.
WebStorm already provided this, but in an own fashion, not using TS language servers or open source plugins. Soon we all will be able to leverage this feature, but only if we give up on our loved Prop() decorator.

I personally think I can get used to a different Syntax.
Anyway I just wanted to point you guys there, as now is the time participate in the discussion.

On the other hand, if you really would not like to give up on Prop() at all, I am sure there can be a third-party library like vue-property-decorator which still offers this functionality, but this will prevent property completion in templates.

Have a look at all v8 issues and read carefully through them before jumping into the discussion, plus, be nice to ktsn, the maintainer of vue-class-component:
https://github.com/vuejs/vue-class-component/issues?q=is%3Aissue+label%3Av8+-label%3Abug+

@John0King
Copy link

@wtho vuejs/vetur#1323 I don't think so, vue-property-decorator is now be supported in vs code for intellsence

@wtho
Copy link

wtho commented Oct 17, 2020

@John0King oh, sorry about the confusion, my post was only regarding Vue version 3 (vue-class-component version 8), as this issue is as well about Vue version 3.

Vue Version 2 will always work with Prop decorators and does have some VS Code Intellisense support included in Vetur 👍

@fluffynuts
Copy link

fluffynuts commented Nov 2, 2020

@wtho please see vuejs/vue-class-component#465 (comment) which suggests that @Prop should probably not go away.

Personally, I don't care about TSX -- and I think there's probably other people out there with the same viewpoint -- so whether or not @Prop provides typings for TSX really doesn't matter to me. Property completion within templates in WebStorm work just fine too -- whilst I'm happy for people not using WebStorm to get extra support, I'm also quite happy to just keep on the way I am.

I imagine that there are a reasonable number of people who are simply comfortable with the class support that vue-class-component and vue-property-decorator provided in vue2, and would like to upgrade projects to vue3 to take advantage of newer patterns in work going forward (or not: Evan You has been quite vocal about the composition api not deprecating the class api) and / or performance enhancements that have come across the board in vue3. I'm sure there are a bunch of people who would be very grateful for continued support.

Right now, I have to decide between opening an issue for warnings against vue-property-decorator and vue3 (re-exports of default exports from vue-class-component and vue which no longer exist) and changing up how my team has worked for about 2 years now, successfully.

@Chris2011
Copy link

Thx @fluffynuts I also don't care about TSX and just adding features for one specific thing is not very well IMHO. So maybe it should have both options. One for TSX what will not be the @prop and the default way with @prop. I think it is a narrow ridge between making both happy or just one side. But I'm with you :)

@mirata
Copy link

mirata commented Nov 19, 2020

I also have the situation where we have a Vue 2 project built extensively with vue-property-decorator. Whatever the vue 3 solution is, I would hope that there is a clear migration path so that changes and regression testing can be kept to a minimum, or at very least - made predictable and quantifiable

@aliibrahimroshan
Copy link

vue-property-decorator is not working with vue 3 and typescript . When doing extends vue it says Type 'typeof import("c:/Myserver/htdocs/vue/node_modules/vue/dist/vue")' is not a constructor function type.Vetur(2507)

@sergeych
Copy link

I hate "new" syntax of vue 3 concerning properties and calculated properties. Sone ecge epoch before classes and decorators were introduced... Please give us back our @props and calculated values as getters/setters, methods or we'll get back to react... it is same ugly as vue 3 but has react native to sweet the pill.

@fluffynuts
Copy link

vue has vue native (https://vue-native.io/), so there's no real win with react native, imo

personally, I'm almost at the point of working out an upgrade-in-place alternative to this library - for us to upgrade is no minor feat, and I guess it's not that easy for anyone else either. I can deal with the stuff that we need to change to support vue 3 (like no event-bus usages), but not having the decorators that we had before is literally the only reason we aren't embarking on a vue3 upgrade at the moment.

@sergeych
Copy link

sergeych commented Jan 27, 2021 via email

@Chris2011
Copy link

vue has vue native (https://vue-native.io/), so there's no real win with react native, imo

personally, I'm almost at the point of working out an upgrade-in-place alternative to this library - for us to upgrade is no minor feat, and I guess it's not that easy for anyone else either. I can deal with the stuff that we need to change to support vue 3 (like no event-bus usages), but not having the decorators that we had before is literally the only reason we aren't embarking on a vue3 upgrade at the moment.

vue-native is just a wrapper around the APIs of React Native. So no real alternative. But to be honest, I've never tried it.

@Chris2011
Copy link

Chris2011 commented Sep 26, 2021

@rdhainaut afaik as in ECMAScript and other languages, decorators are just for class extensibility: https://github.com/tc39/proposal-decorators so I think that this is not possible, if you don't use the class syntax. At the end, do you need them if you don't use classes?

I also love the class components and also I used both packages a lot with Vue 2.* but if I wait for those packages to be working with Vue 3.* (if it is possible anyway, we don't know) I can't use Vue and all the new features. So I made myself a compromise and I use classes where I need it and will try the new setup attribute for the script tag and maybe everything is fine too :). This is my opinion.

@rdhainaut
Copy link

rdhainaut commented Sep 26, 2021

@Chris2011 Thanks for your answer. I did not know that limitation with Typescript Decorator. I have read that Typescript team will not add any new feature to decorators before the proposal will be stable .. it looks like that the proposal has changed a little since last time i have reading it (2 years ago) but it s not ready for the next stage.

Chris i think you have the right adoption strategy. It s pragmatic and you can benefit of new features.
On my side, i hope that native decorator in Js world could fill the gap and become elegant solution. (what i have today in Vue2 project + class syntax + vue-property-decorator and im happy with that. I prefer wait for the moment.

Personnaly, I love decorators because it acts as a syntaxique sugar = a huge improvement of readibility and so for DX (Devoplement eXperience).

I think a sample is more speaking

<script setup>

// Js code /  Ts code with "vue type"
const props = defineProps({
  foo: String,
  bar: Number
})

// Ts code (sorry to say but is uglier than previous sample but give TS type enhancement)
const props = defineProps<{
  foo: string
  bar?: number
}>()

// Decorator code / What i would like to write in my vuejs code
// The readability is better because the first word that i read is "Prop" so i know what it s, the second it s the name of variable and the last the type. All is together with very short syntax and i have not parenthesis or brackets visual noise
// It s litterally 1 word (4 letters + 1 special character) to declare a variable that is a prop in vue js.
@Prop
const foo: string;
@Prop
const bar: number;
</script>

One other with default value

<script setup>
// Ts code
interface Props {
  msg: string
  labels: string[]
}

const props = withDefaults(defineProps<Props>(), {
  msg: 'hello',
  labels: () => ['one', 'two']
})

// Decorator code / What i dream to write in my vuejs code
@Prop
const msg: string = 'hello';

@Prop
const labels string[] = () => ['one', 'two'];

</script>

@Chris2011
Copy link

Chris2011 commented Sep 28, 2021

@rdhainaut I think this is not the right place to discuss this, but again here is the first sentence of the TC39 proposal for decorators:

Decorators are a proposal for extending JavaScript classes which is widely adopted among developers in transpiler environments, with broad interest in standardization.

It is just for classes as you can see in Vue 2 while using the class component syntax and the vue-property-decorator package. If you don't use the class components, you will be not able to use such properties. Atm I'm trying to make friends with the new <script setupt> syntax w/o using classes and just use defineProps as mentioned in the official documentation and what you already mentioned: https://v3.vuejs.org/api/sfc-script-setup.html (https://v3.vuejs.org/api/sfc-script-setup.html#defineprops-and-defineemits)

I think it is not that much code and a good compromise. IMHO.

@carrey-k
Copy link

@webcoderkz

Hi. This library depends on vue-class-component. If vue-class-component supports v3.0 and it provides an API for third party libraries including vue-property-decorator, I will continue maintaining this library.

Seems there is no stable release for vue-class-component to support Vue 3.x

@sergeych
Copy link

sergeych commented Oct 13, 2021 via email

@kskalski
Copy link

The currently released components allow using most of the old class and decorator syntax, I'm doing it in my project by setting following deps:

    "vue": "3.2.20",
    "vue-class-component": "8.0.0-rc.1",
    "vue-property-decorator": "10.0.0-rc.3",
    "vue-decorator": "1.1.3",
    "vue-loader-v16": "16.0.0-beta.5.4",
    "vue-router": "4.0.11",
    "vuex": "4.0.2",
    "s-vuex-class": "0.4.1"

and my components are written as

@Options({
    components: {
        Address,
        AppCard,
        AppCardItem,
        AppPage,
        BIconPerson: bicon.BIconPerson,
        BIconPieChart: bicon.BIconPieChart,
        BIconTelephone: bicon.BIconTelephone
    }
})
export default class Shareholder extends Vue {
    @Prop()
    shareholder_key: number;

    @State((state: RootState) => state.Registry.ShareCompanies)
    allCompanies: { [key: string]: ShareCompanyInfo };

    @Getter("Registry/Shareholders")
    shareholders: { [key: string]: ShareholderInfo };

The only thing I would complain about this setup is the need to use Options instead of Component and the fact that two of the dependencies have rc in their tag names. Apart from that I didn't see issues, though that particular project is small and I didn't try migrating my larger project to this setup yet.

@sergeych
Copy link

sergeych commented Nov 7, 2021

Thanks. Gonna risk to start one of new projects like this

@anthony-fargnoli
Copy link

The currently released components allow using most of the old class and decorator syntax, I'm doing it in my project by setting following deps:

@kskalski This looks promising. I'm in the same boat and was wondering if you could share a little more of the setup? How are you initialising the Vue instance for the page? Any chance this in a public repo?

@kskalski
Copy link

@kskalski This looks promising. I'm in the same boat and was wondering if you could share a little more of the setup? How are you initialising the Vue instance for the page? Any chance this in a public repo?

I copied some of the relevant code to https://gist.github.com/kskalski/d34c481a0d68ce72e3451ab3eb9c5d88
If you need some more info please drop comment on the gist

@anthony-fargnoli
Copy link

@kskalski This looks promising. I'm in the same boat and was wondering if you could share a little more of the setup? How are you initialising the Vue instance for the page? Any chance this in a public repo?

I copied some of the relevant code to https://gist.github.com/kskalski/d34c481a0d68ce72e3451ab3eb9c5d88 If you need some more info please drop comment on the gist

Thanks. Using the initialisation below, the render function doesn't appear to pass the Props through correctly.
Unfortunately the entire codebase is written in this manor, so I think I'm going to bite the bullet and just re-write using the CompositionApi.

// init code using VueCompat

const vm = new Vue({
         el: '#app',
        render: (h:any) => h(MailLogView, {
         filter: data.Filter,
         items: data.Items,
         options: options
        })
     });

// vue component

@Options({
    })
    export default class MailLogViewModel extends Vue
    {
        @Prop(Object) filter: MailLogFilterViewModelData;
        @Prop(Array) items: MailLogEntryData[];
        @Prop(Object) options: any;
        
        Filter = this.filter;
        Items = this.items;
        ....
     }

@sergeych
Copy link

The currently released components allow using most of the old class and decorator syntax, I'm doing it in my project by setting following deps:

    "vue": "3.2.20",
    "vue-class-component": "8.0.0-rc.1",
    "vue-property-decorator": "10.0.0-rc.3",
    "vue-decorator": "1.1.3",
    "vue-loader-v16": "16.0.0-beta.5.4",
    "vue-router": "4.0.11",
    "vuex": "4.0.2",
    "s-vuex-class": "0.4.1"

and my components are written as

@Options({
    components: {
        Address,
        AppCard,
        AppCardItem,
        AppPage,
        BIconPerson: bicon.BIconPerson,
        BIconPieChart: bicon.BIconPieChart,
        BIconTelephone: bicon.BIconTelephone
    }
})
export default class Shareholder extends Vue {
    @Prop()
    shareholder_key: number;

    @State((state: RootState) => state.Registry.ShareCompanies)
    allCompanies: { [key: string]: ShareCompanyInfo };

    @Getter("Registry/Shareholders")
    shareholders: { [key: string]: ShareholderInfo };

The only thing I would complain about this setup is the need to use Options instead of Component and the fact that two of the dependencies have rc in their tag names. Apart from that I didn't see issues, though that particular project is small and I didn't try migrating my larger project to this setup yet.

BTW did you succeed using VModel/Model whatever with this setup? I did not found a way to make it (v-model 2-way bindings) work under vue3 and rc.3 decorators...

@kskalski
Copy link

BTW did you succeed using VModel/Model whatever with this setup? I did not found a way to make it (v-model 2-way bindings) work under vue3 and rc.3 decorators...

Yea, I use it in one component for local property inside component:

   <input type="text" class="form-control" id="setting-input-1" v-model='company.Info.Name' required>
...
export default class NewCompany extends Vue {
    company: ShareCompanyInfo = { Info: { Contact: { Address: {} } } } as ShareCompanyInfo;
}

and it seems to work, though I didn't explore more complicated uses.

@johnnyshankman
Copy link

What's the status of this? This conversation is massive and there's no clear migration guide anywhere for Vue2->Vue3.

@kaorun343
Copy link
Owner

vue-class-component does not support Vue.js 3.0 with stable release, so there's no activity on this repository.

@armenr
Copy link

armenr commented Jan 3, 2022

vue-class-component does not support Vue.js 3.0 with stable release, so there's no activity on this repository.

"Lasciate ogne speranza, voi ch'intrate..."

@fobdy
Copy link

fobdy commented Jan 12, 2022

@kaorun343 Maybe you may want to fork vue-class-component and adapt it to Vue3 as you wish?
Since I guess most users of your library doesn't depend directly on vue-class-component.
So instead of waiting for vue-class-component for 2 years we can quickly solve that issue :)
Isn't it?

@Sinneida
Copy link

I think it's better to assume that vue-class-component is dead, even though no one has made that statement officially. @ktsn seems to be uninterested in developing it anymore, as he keeps committing to his other repositories, just not to the repo with class component. I've also had a mixed feelings about Composition API, but it's far better than Options API, both in terms of TypeScript support as well as code organisation.

@Chris2011
Copy link

It is just a matter of taste. And with the <script lang="ts" setup> attribute, it is very handy and nice. So give it a chance, you will like it :). You still can use classes but not for your components, but well.

@MFJamil
Copy link

MFJamil commented Mar 1, 2022

Hello Guys, I was waiting for any of the two guys who worked on vue-class-component and vue-property-decorator to do the final update. But I guess, it is not an easy decision, specially after the introduction of the Composition APIs, whether it still feasible to keep the usage of the annotations or not. For me, as an OOP oriented developer, and I guess many others as well, we all liked Vue for its Options APIs and how close that was to our world. I had used it with pleasure together with Typescript and made several big projects with. Now after Vue 3 is there, everything seems to be different, it is more close to the JS world.
However, after all the code written with Vue 2 and the big amount of Vue Components, that made the migration not an easy task for me. Since it is stated that Options APIs will remain supported. I had took a look at the latest version of the vue-class-component library, and it was supporting Vue 3. Which is good, but the vue-property-decorator still not. What I did, that I made a small branch out of that and adopted it to work with Vue 3, also I had put back the name of "Component" as annotation instead of "Options", so that nothing will change in the code written before.
I know that this might look stupid, but I really wanted to maintain the code, as much as possible, to be backward compatible. If you guys, have the same concerns that I do, you can give this vue-property-decorator a try, and if you find it ok, we can try to discuss merging that, via a pull request and try to convince kaorun343 to put it as a new version, that only if it will work as expected, from my side, I am using it successfully now with Vue3 , but still testing it.

The link is below:

https://www.npmjs.com/package/@smyld/vue-property-decorator

To download for testing it:

npm i @smyld/vue-property-decorator

Note: please this is "just for testing", nothing official , I need the help from other colleges, to approve that it is working fine, then we can try to make it official here with the permission of Kaorun343.

UPDATE I deeply apologize, I just noticed that Kaorun343 had already made a VUE 3 Compatible version, that I did not notice before!! it is already under "10.0.0-rc.3" and can be found on the following link:

https://www.npmjs.com/package/vue-property-decorator/v/10.0.0-rc.3

The only difference, is that every Component Annotation, should be replaced with Options during the migration.

@mayuxian
Copy link

mayuxian commented Mar 4, 2022

@MFJamil Vue2 is indeed more developer-friendly, but VUe3 is more product-friendly

@kskalski
Copy link

kskalski commented Mar 5, 2022

The currently released components allow using most of the old class and decorator syntax, I'm doing it in my project by setting following deps:

This looks promising. I'm in the same boat and was wondering if you could share a little more of the setup? How are you initialising the Vue instance for the page? Any chance this in a public repo?

@anthony-fargnoli I added a complete demo project here
https://github.com/kskalski/snippets/tree/master/AspNetCoreVueJsDemo/EmissionsWeb/ClientApp

In the scope of such simple add/edit/list functionality the only difference between Vue2 and Vue3 codebase with class and decorator syntax is the use of @Options instead of @Component.

@kpturner
Copy link

kpturner commented Mar 21, 2022

It does not seem to work well for me. If every component extends Vue the it is OK, but if you have a project (like an old Vue 2 project that you are migrating) where Component A is extended by Component B the it fails at run time with Uncaught TypeError: Class extends value #<Object> is not a constructor or null

It is easy to reproduce. I just created a simple Vue 3 app using Vite. Add a component like this

<template>
  <div class="greetings">
    <h1 class="green">{{ msg }}</h1>
    <h3>
      This is the class component
    </h3>
  </div>
</template>

<script lang="ts">

import { Vue, Options } from 'vue-property-decorator';


@Options({
    name: 'ClassComponentExtends',
    components: {
    }
})
export default class ClassComponentExtends extends Vue {
}

</script>

Then create another component that extends it

<script lang="ts">

import { Options } from 'vue-property-decorator';
import ClassComponentExtends from './ClassComponentExtends.vue';

@Options({
    name: 'ClassComponent',
    components: {
    }
})
export default class ClassComponent extends ClassComponentExtends {
}

</script>

Then use ClassComponent in your app somewhere. It will fail with the error defined above. The same happens if you don't use vue-property-decorator and just use vue-class-component so the problem may well be there.

@philipwhitesysarb
Copy link

philipwhitesysarb commented Apr 27, 2022

Hi, I have encountered a strange issue with the 10.0.0-rc.3 build when trying to upgrade a vue 2 project. It seems like extending classes prevents props from being received by components unless the extended class also has the Prop defined.

More specifically I have a LoginComponent extends a VueBase class that in turn extends Vue - if i define the same props in the VueBase as I have in the LoginComponent then everything works fine, however if VueBase doesn't have the same props defined then LoginComponent never receives its prop data from the parent component.

However this only occurs if I define additional props/getters/actions in my extended class if I avoid these then it functions as expected.

Is this a bug or am I implementing something incorrectly ?

@kaorun343 kaorun343 unpinned this issue Jun 23, 2022
@ruojianll
Copy link

Try this https://github.com/facing-dev/vue-facing-decorator

@viT-1
Copy link

viT-1 commented Nov 2, 2022

It does not seem to work well for me. If every component extends Vue the it is OK, but if you have a project (like an old Vue 2 project that you are migrating) where Component A is extended by Component B the it fails at run time with Uncaught TypeError: Class extends value #<Object> is not a constructor or null

When I've got same issue without planning to support Vue3 in my project, I decided to use another variant of extending with Mixins like that:

import { debounceFn as Debounce } from 'debounce-decorator-ts';
import { Component, Mixins } from 'vue-property-decorator'; // nowadays we should import Component from vue-class-component package

import { conf } from './SomeForm-conf';

const {
	bem,
	name,
	template,
} = conf;

@Component({
	name,
	template,
})
export class SomeForm extends Mixins(BemComponent) {
	constructor() {
		super();
		this.b = bem;
	}
...
	// wrapper should be defined to be reactive! data object can'be modified on runtime
	myScope = {};

	@Debounce(500)
	onInputValue2(val: string): void {
		// this.iamInputValue2 = val;
		// this.$set(this.myScope, 'iamInputValue2', val);
		this.myScope = { ...this.myScope, iamInputValue2: val };
	}
}

@rdhelms
Copy link

rdhelms commented Feb 20, 2023

I think @ruojianll 's vue-facing-decorator has a ton of potential...of all the alternatives to the original vue-class-component and vue-property-decorator configs that I've seen so far, that seems to work the best with our existing code with minimal changes. Has anyone else had a chance to check that out? I would love if we could come up with an official vue3 successor to these packages, since the maintainers here don't seem to be responding anymore

https://facing-dev.github.io/vue-facing-decorator/
vuejs/vue-class-component#569 (comment)

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

No branches or pull requests