aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar wulinsheng123 <409187100@qq.com> 2023-04-01 01:42:03 +0800
committerGravatar GitHub <noreply@github.com> 2023-03-31 13:42:03 -0400
commitd59e511d16482cfc7067555dd0a456098ec69e30 (patch)
tree78726248d30b6b01455db8eb3bed12a73dae9df2
parent07e8a1bab4f1d1442854cec65e8f66b247fc87c7 (diff)
downloadastro-d59e511d16482cfc7067555dd0a456098ec69e30.tar.gz
astro-d59e511d16482cfc7067555dd0a456098ec69e30.tar.zst
astro-d59e511d16482cfc7067555dd0a456098ec69e30.zip
supporting top of await (#6671)
* add fix * fix * revert verison * fix fn is undefined g * add e2e test * fix unit test * delete redundant code * add changeset --------- Co-authored-by: wuls <linsheng.wu@beantechs.com>
-rw-r--r--.changeset/spotty-keys-change.md5
-rw-r--r--packages/astro/e2e/fixtures/vue-component/src/components/Test.vue19
-rw-r--r--packages/astro/e2e/fixtures/vue-component/src/pages/index.astro2
-rw-r--r--packages/astro/e2e/fixtures/vue-component/src/pages/mdx.mdx3
-rw-r--r--packages/astro/e2e/vue-component.test.js19
-rw-r--r--packages/integrations/vue/client.js19
-rw-r--r--packages/integrations/vue/test/app-entrypoint.test.js1
7 files changed, 63 insertions, 5 deletions
diff --git a/.changeset/spotty-keys-change.md b/.changeset/spotty-keys-change.md
new file mode 100644
index 000000000..3518721f3
--- /dev/null
+++ b/.changeset/spotty-keys-change.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/vue': patch
+---
+
+Supporting the top of the await syntax sugar for Vue in the template's setup
diff --git a/packages/astro/e2e/fixtures/vue-component/src/components/Test.vue b/packages/astro/e2e/fixtures/vue-component/src/components/Test.vue
new file mode 100644
index 000000000..da05a1029
--- /dev/null
+++ b/packages/astro/e2e/fixtures/vue-component/src/components/Test.vue
@@ -0,0 +1,19 @@
+<script setup lang="ts">
+import {onMounted, ref} from 'vue'
+const props = defineProps(['id'])
+/** The top-level await causes event handling to not work (button click) */
+await new Promise((resolve) => setTimeout(resolve, 10));
+
+const a = ref(1);
+
+onMounted(()=>{
+ a.value = 2
+})
+
+</script>
+
+<template>
+ <div :id="props.id">
+ {{ a }}
+ </div>
+</template>
diff --git a/packages/astro/e2e/fixtures/vue-component/src/pages/index.astro b/packages/astro/e2e/fixtures/vue-component/src/pages/index.astro
index 73b5b2cf0..5ea9823b6 100644
--- a/packages/astro/e2e/fixtures/vue-component/src/pages/index.astro
+++ b/packages/astro/e2e/fixtures/vue-component/src/pages/index.astro
@@ -1,6 +1,7 @@
---
import Counter from '../components/Counter.vue';
import VueComponent from '../components/VueComponent.vue';
+import AsyncTest from '../components/Test.vue'
const someProps = {
count: 0,
@@ -33,5 +34,6 @@ const someProps = {
</Counter>
<VueComponent id="client-only" client:only="vue" />
+ <AsyncTest id="client-test" client:only="vue" />
</body>
</html>
diff --git a/packages/astro/e2e/fixtures/vue-component/src/pages/mdx.mdx b/packages/astro/e2e/fixtures/vue-component/src/pages/mdx.mdx
index 5d0a141b0..ed8d80746 100644
--- a/packages/astro/e2e/fixtures/vue-component/src/pages/mdx.mdx
+++ b/packages/astro/e2e/fixtures/vue-component/src/pages/mdx.mdx
@@ -1,6 +1,7 @@
export { default } from '../components/Layout.astro';
import Counter from '../components/Counter.vue';
import VueComponent from '../components/VueComponent.vue';
+import AsyncTest from '../components/Test.vue';
export const someProps = {
count: 0,
@@ -27,3 +28,5 @@ export const someProps = {
</Counter>
<VueComponent id="client-only" client:only="vue" />
+
+<AsyncTest id="client-test" client:only="vue" />
diff --git a/packages/astro/e2e/vue-component.test.js b/packages/astro/e2e/vue-component.test.js
index 0cc41c74e..42f0d80ef 100644
--- a/packages/astro/e2e/vue-component.test.js
+++ b/packages/astro/e2e/vue-component.test.js
@@ -1,5 +1,5 @@
import { prepareTestFactory } from './shared-component-tests.js';
-
+import { expect } from '@playwright/test';
const { test, createTests } = prepareTestFactory({ root: './fixtures/vue-component/' });
const config = {
@@ -23,3 +23,20 @@ test.describe('Vue components in MDX files', () => {
pageSourceFilePath: './src/pages/mdx.mdx',
});
});
+
+
+test('test the async vue component in astro', async ({ page, astro }) => {
+ await page.goto(astro.resolveUrl('/'));
+
+ const label = page.locator('#client-test');
+
+ await expect(label, 'component not hydrated').toHaveText('2');
+});
+
+test('test the async vue component in mdx', async ({ page, astro }) => {
+ await page.goto(astro.resolveUrl('/mdx/'));
+
+ const label = page.locator('#client-test');
+
+ await expect(label, 'component not hydrated').toHaveText('2');
+});
diff --git a/packages/integrations/vue/client.js b/packages/integrations/vue/client.js
index 7e67825df..508cc59c0 100644
--- a/packages/integrations/vue/client.js
+++ b/packages/integrations/vue/client.js
@@ -1,4 +1,4 @@
-import { h, createSSRApp, createApp } from 'vue';
+import { h, createSSRApp, createApp, Suspense } from 'vue';
import { setup } from 'virtual:@astrojs/vue/app';
import StaticHtml from './static-html.js';
@@ -13,13 +13,26 @@ export default (element) =>
for (const [key, value] of Object.entries(slotted)) {
slots[key] = () => h(StaticHtml, { value, name: key === 'default' ? undefined : key });
}
+
+ let content = h(Component, props, slots);
+ // related to https://github.com/withastro/astro/issues/6549
+ // if the component is async, wrap it in a Suspense component
+ if (isAsync(Component.setup)) {
+ content = h(Suspense, null, content)
+ }
+
if (client === 'only') {
- const app = createApp({ name, render: () => h(Component, props, slots) });
+ const app = createApp({ name, render: () => content });
await setup(app);
app.mount(element, false);
} else {
- const app = createSSRApp({ name, render: () => h(Component, props, slots) });
+ const app = createSSRApp({ name, render: () => content });
await setup(app);
app.mount(element, true);
}
};
+
+function isAsync (fn) {
+ const constructor = fn?.constructor
+ return constructor && constructor.name === 'AsyncFunction';
+}
diff --git a/packages/integrations/vue/test/app-entrypoint.test.js b/packages/integrations/vue/test/app-entrypoint.test.js
index 0c60818a3..5c9ea840c 100644
--- a/packages/integrations/vue/test/app-entrypoint.test.js
+++ b/packages/integrations/vue/test/app-entrypoint.test.js
@@ -1,7 +1,6 @@
import { loadFixture } from './test-utils.js';
import { expect } from 'chai';
import { parseHTML } from 'linkedom';
-
describe('App Entrypoint', () => {
/** @type {import('./test-utils').Fixture} */
let fixture;