feat: add basic-jsx and basic-template examples

- basic-jsx: Counter + Clock with defineComponent() + JSX
- basic-template: Counter + Clock with .vue SFC + <template>
- Both demonstrate HMR via vue-tui dev
- Fix vite-plugin: strip build.lib and external config for bundledDev,
  add node builtins resolveId to prevent browser-external shimming
- Remove old hmr-demo example (superseded by basic-template)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yunfei He
2026-05-24 21:21:08 +08:00
parent e8ef31814a
commit 020fd0d85a
22 changed files with 333 additions and 92 deletions
+7
View File
@@ -0,0 +1,7 @@
<!doctype html>
<html>
<head></head>
<body>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
+21
View File
@@ -0,0 +1,21 @@
{
"name": "@vue-tui/example-basic-template",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vue-tui dev",
"build": "vite build",
"start": "vite build && node dist/game.mjs"
},
"dependencies": {
"@vue-tui/cli": "workspace:*",
"@vue-tui/runtime": "workspace:*",
"vue": "^3.4.0"
},
"devDependencies": {
"@types/node": "catalog:",
"@vitejs/plugin-vue": "^6",
"vite": "catalog:"
}
}
+31
View File
@@ -0,0 +1,31 @@
<script lang="ts">
import { shallowRef, defineComponent } from "vue";
import { Box, Text, useInput } from "@vue-tui/runtime";
import Counter from "./Counter.vue";
import Clock from "./Clock.vue";
export default defineComponent({
components: { Box, Text, Counter, Clock },
setup() {
const showClock = shallowRef(true);
useInput((input) => {
if (input === "c") showClock.value = !showClock.value;
if (input === "q") process.exit(0);
});
return { showClock };
},
});
</script>
<template>
<Box flexDirection="column" :paddingX="1">
<Text bold color="cyan">vue-tui basic (template)</Text>
<Text dimColor>Try editing Counter.vue or App.vue</Text>
<Text dimColor>Press c=toggle clock, q=quit</Text>
<Text> </Text>
<Counter />
<Clock v-if="showClock" />
</Box>
</template>
+31
View File
@@ -0,0 +1,31 @@
<script lang="ts">
import { shallowRef, onMounted, onUnmounted, defineComponent } from "vue";
import { Box, Text } from "@vue-tui/runtime";
export default defineComponent({
components: { Box, Text },
setup() {
const time = shallowRef(new Date().toLocaleTimeString());
let timer: ReturnType<typeof setInterval>;
onMounted(() => {
timer = setInterval(() => {
time.value = new Date().toLocaleTimeString();
}, 1000);
});
onUnmounted(() => {
clearInterval(timer);
});
return { time };
},
});
</script>
<template>
<Box>
<Text>Clock: </Text>
<Text bold color="yellow">{{ time }}</Text>
</Box>
</template>
+26
View File
@@ -0,0 +1,26 @@
<script lang="ts">
import { shallowRef, defineComponent } from "vue";
import { Box, Text, useInput } from "@vue-tui/runtime";
export default defineComponent({
components: { Box, Text },
setup() {
const count = shallowRef(0);
useInput((input) => {
if (input === "+") count.value++;
if (input === "-") count.value--;
});
return { count };
},
});
</script>
<template>
<Box>
<Text>Count: </Text>
<Text bold color="green">{{ count }}</Text>
<Text dimColor> (+/- to change)</Text>
</Box>
</template>
+4
View File
@@ -0,0 +1,4 @@
import { createApp } from "@vue-tui/runtime";
import App from "./App.vue";
createApp(App).mount();
+5
View File
@@ -0,0 +1,5 @@
declare module "*.vue" {
import type { Component } from "vue";
const component: Component;
export default component;
}
+11
View File
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "bundler",
"strict": true,
"noEmit": true,
"jsx": "preserve"
},
"include": ["src/**/*.ts", "src/**/*.vue"]
}
+23
View File
@@ -0,0 +1,23 @@
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { fileURLToPath } from "node:url";
const here = fileURLToPath(new URL(".", import.meta.url));
export default defineConfig({
plugins: [vue()],
build: {
target: "node22",
outDir: "dist",
emptyOutDir: true,
minify: false,
lib: {
entry: `${here}src/main.ts`,
formats: ["es"],
fileName: () => "game.mjs",
},
rollupOptions: {
external: (id) => !id.startsWith(".") && !id.startsWith("/") && !id.startsWith("\0"),
},
},
});