Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement and export defineAsyncComponent compatible version in 2.7.x #12608

Closed
renatodeleao opened this issue Jul 4, 2022 · 8 comments
Closed

Comments

@renatodeleao
Copy link

renatodeleao commented Jul 4, 2022

What problem does this feature solve?

  1. Allows to drop @vue/composition-api plugin after migrating from vue@^2.6.x into ^2.7.x.
  2. It makes migration from 2.x to 3.x one step easier.

If you were previously using @vue/composition-api, update imports from it to vue instead. Note that some APIs exported by the plugin, e.g. createApp, are not ported in 2.7.
https://blog.vuejs.org/posts/vue-2-7-naruto.html

The release notes do mention that some APIs are not ported to 2.7, that's why this is not a bug report because it might be intentional.

defineAsyncComponent looks like something that would be a nice addition to this final 2.x version, since async components already exist in vue2 land: the syntax just slightly changed (v2 vs v3).

Also @vue/composition-api version does it and it does not appear to use any vue3 internals, so it seems technically achievable.

What does the proposed API look like?

implement and export a defineAsyncComponent using prior art (@vue/composition-api plugin version as base).

- import { defineAsyncComponent } from '@vue/composition-api'
+ import { defineAsyncComponent } from 'vue'
@renatodeleao renatodeleao changed the title implement and export defineAsyncComponent compatible version implement and export defineAsyncComponent compatible version in 2.7.x Jul 4, 2022
@iceprosurface
Copy link

same issue !

@yyx990803
Copy link
Member

The reason it's not ported is because it's unnecessary in Vue 2... defineAsyncComponent exists in Vue 3 is because plain functions are treated as functional components in Vue 3. You don't need it in Vue 2.

You already have the equivalent of all the functionality: https://v2.vuejs.org/v2/guide/components-dynamic-async.html#Handling-Loading-State

@iceprosurface
Copy link

iceprosurface commented Jul 5, 2022

it's unnecessary for implement for defineAsyncComponent, but we need a shape for defineAsyncComponent(just like defineComponent):

function defineAsyncComponent(option: AsyncComponent): AsyncComponent;
export function defineAsyncComponent(option: any) {
  return option
}

@renatodeleao
Copy link
Author

renatodeleao commented Jul 5, 2022

@yyx990803 i understand it's not necessary for vue2 to achieve the desired goal — as i've mentioned in the issue description and pointed to the same doc link as you did — but would make future migrations to v3 more convenient, because the syntax would be interoperable/cross compatible, meaning one less migration error to worry about.

https://v3-migration.vuejs.org/breaking-changes/async-components.html#async-components

// Vue2 vs Vue3
- const asyncModal = () => import('./Modal.vue')
+ const asyncModal = defineAsyncComponent(() => import('./Modal.vue'))

// Async component with options
- const asyncModal = {
+ const asyncModal = defineAsyncComponent({
-  component: () => import('./Modal.vue'),
+  loader: () => import('./Modal.vue'),
   delay: 200,
   timeout: 3000,
-  error: ErrorComponent,
+  errorComponent: ErrorComponent,
-  loading: LoadingComponent
+  loadingComponent: LoadingComponent
}

Anyways, thanks for taking the time to look at it!

@yyx990803 yyx990803 reopened this Jul 8, 2022
@renatodeleao
Copy link
Author

Thanks :shipit:

@MatthewAry
Copy link

I'm happy to see movement on this but https://github.com/vuejs/vue/blob/main/types/index.d.ts#L45 seems to be preventing me from being able to use the method and type.

I would expect import { defineAsyncComponent } from 'vue' to work now but it's not. Am I missing something?

@achaphiv
Copy link

I'm guessing that

// export { defineAsyncComponent } from './defineAsyncComponent'

is supposed to be:

-// export { defineAsyncComponent } from './defineAsyncComponent
+export { defineAsyncComponent } from './v3-define-async-component

@jacekkarczmarczyk
Copy link

I would expect import { defineAsyncComponent } from 'vue' to work now but it's not. Am I missing something?

For me it looks like the type is exported, autocompletion in IDE suggests this:

import type { defineAsyncComponent } from 'vue/types/v3-define-async-component';

That type leads to:

export function defineAsyncComponent(
  source: AsyncComponentLoader | AsyncComponentOptions
): AsyncComponent

My workaround is to create my own "loader"

export function defineAsyncComponent<T> (loader: T): T {
  return loader;
}

and import this one, later when it's fixed i'll just change the import to vue

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

No branches or pull requests

6 participants