计数器和随机笑话

87 阅读2分钟

用 Vite、TypeScript、UnoCSS 和 Vue 3 的 setup 语法糖构建的一个应用。将创建一个点击计数器,每次点击按钮时都会增加计数,并展示一个随机笑话,最后通过路由增加随机一言。

步骤如下:

  1. 初始化 Vite 项目;
  2. 安装依赖项;
  3. 配置 UnoCSS;
  4. 创建 Vue 组件,使用 TypeScript 和
  5. 在 App.vue 中使用组件。

1. 初始化 Vite 项目

在终端中运行:

npm create vite@latest my-vue-app -- --template vue-ts
cd my-vue-app
npm install

2. 安装 UnoCSS

npm install unocss -D

在 vite.config.ts 中配置 UnoCSS:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import UnoCSS from 'unocss/vite'

export default defineConfig({
  plugins: [
    vue(),
    UnoCSS()
  ]
})

3. 配置 UnoCSS

在项目根目录创建 uno.config.ts:

import { defineConfig, presetUno, presetAttributify, presetIcons } from 'unocss'

export default defineConfig({
  presets: [
    presetUno(),
    presetAttributify(),
    presetIcons(),
  ],
})

在 main.ts 中引入 UnoCSS:

import { createApp } from 'vue'
import App from './App.vue'
import 'uno.css'

createApp(App).mount('#app')

4. 创建计数器组件

在 src/components 目录下创建 Counter.vue 文件:

<template>
  <div class="flex flex-col items-center mt-10 p-4 border rounded shadow-lg">
    <h1 class="text-2xl font-bold mb-4">{{ title }}</h1>
    <p class="text-lg mb-4">点击次数:{{ count }}</p>
    <button class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-700" @click="incrementCount">点击我</button>
    <p v-if="joke" class="text-lg mt-4">{{ joke }}</p>
  </div>
</template>

<script setup lang="ts">
  import { ref, onMounted } from 'vue';

  const title = ref<string>('点击计数器');
  const count = ref<number>(0);
  const joke = ref<string>('');

  const incrementCount = () => {
    count.value++;
    fetchJoke();
  };

  const fetchJoke = async () => {
    try {
      const response = await fetch('https://official-joke-api.appspot.com/jokes/random');
      const data = await response.json();
      joke.value = `${data.setup} - ${data.punchline}`;
    } catch (error) {
      joke.value = '无法获取笑话';
    }
  };

  onMounted(fetchJoke);
</script>

5. 在 App.vue 中使用组件

修改 src/App.vue 文件:

<template>
  <div class="flex justify-center items-center min-h-screen bg-gray-100">
    <Counter />
  </div>
</template>

<script setup lang="ts">
  import Counter from './components/Counter.vue';
</script>

6. 运行应用

7. 添加路由

npm install vue-router@next

创建 src/router/index.ts

import { createRouter, createWebHistory } from 'vue-router'
import Counter from '../components/Counter.vue'
import QuoteGenerator from '../components/QuoteGenerator.vue'

const routes = [
  { path: '/', redirect: '/counter' },
  { path: '/counter', component: Counter },
  { path: '/quotes', component: QuoteGenerator },
]

const router = createRouter({
  history: createWebHistory(),
  routes,
})

export default router

main.ts 引入路由

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import 'uno.css'

const app = createApp(App)
app.use(router)
app.mount('#app')

8. 创建随机一言组件

在 src/components 目录下创建 QuoteGenerator.vue 文件。

<template>
  <div class="flex flex-col items-center mt-10 p-4 border rounded shadow-lg">
    <h1 class="text-2xl font-bold mb-4">{{ title }}</h1>
    <button
      class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-700"
      @click="fetchQuote"
    >
      获取名言
    </button>
    <p v-if="quote" class="text-lg mt-4 italic">{{ quote }}</p>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const title = ref<string>('随机名言生成器')
const quote = ref<string>('')

const fetchQuote = async () => {
  try {
    const response = await fetch('https://api.quotable.io/random')
    const data = await response.json()
    quote.value = `${data.content} — ${data.author}`
  } catch (error) {
    quote.value = '无法获取名言'
  }
}
</script>

9. 配置 App.vue

在 src/App.vue 中设置导航菜单和路由视图:

<template>
  <div>
    <nav class="flex justify-around bg-gray-200 p-4">
      <router-link to="/counter" class="text-blue-500 hover:underline">点击计数器</router-link>
      <router-link to="/quotes" class="text-green-500 hover:underline">随机名言生成器</router-link>
    </nav>
    <router-view class="flex justify-center items-center min-h-screen bg-gray-100"></router-view>
  </div>
</template>

完成上述步骤后,应用将包含两个功能:点击计数器和随机名言生成器,可以通过导航菜单切换不同的页面。