使用 Vite、TypeScript 、 Vue 3 Composition API、Tailwind CSS 搭建的一个待办应用。 下面是一个简单的步骤指南.
1. 创建 Vite 项目
首先,通过 Vite 创建一个新的 Vue 项目:
npm create vite@latest my-todo-app -- --template vue-ts
cd my-todo-app
npm install
2. 安装依赖
安装 Tailwind CSS 来快速构建 UI。
npm install tailwindcss postcss autoprefixer
npx tailwindcss init -p
3. 配置 Tailwind CSS
在 tailwind.config.js 文件中,添加以下内容:
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
theme: {
extend: {},
},
plugins: [],
}
在 src/main.ts 中导入 Tailwind CSS:
import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
createApp(App).mount('#app')
创建 src/index.css 文件并添加以下内容:
@tailwind base;
@tailwind components;
@tailwind utilities;
4. 创建 ToDo 组件
在 src/components 文件夹下创建 TodoItem.vue 和 TodoList.vue 组件。
TodoItem.vue
<template>
<div class="flex items-center justify-between p-4 bg-white rounded shadow-md">
<div @click="toggleComplete" class="cursor-pointer">
<input
type="checkbox"
v-model="item.completed"
@change="toggleComplete"
class="mr-2"
/>
<span :class="{ 'line-through': item.completed }">{{ item.text }}</span>
</div>
<button @click="deleteItem" class="text-red-500">删除</button>
</div>
</template>
<script setup lang="ts">
const props = defineProps<{
item: { text: string; completed: boolean }
}>()
const emit = defineEmits(['update', 'delete'])
const toggleComplete = () => {
emit('update', { ...props.item, completed: !props.item.completed })
}
const deleteItem = () => {
emit('delete', props.item)
}
</script>
<style scoped>
.line-through {
text-decoration: line-through;
}
.cursor-pointer {
cursor: pointer;
}
</style>
TodoList.vue
<template>
<div class="max-w-xl mx-auto mt-10">
<h1 class="text-3xl font-bold mb-4">ToDo List</h1>
<div class="flex mb-4">
<input
v-model="newTodo"
@keyup.enter="addTodo"
type="text"
placeholder="添加新任务"
class="flex-1 p-2 border rounded"
/>
<button @click="addTodo" class="ml-2 p-2 bg-blue-500 text-white rounded">
添加
</button>
</div>
<div v-if="todos.length">
<TodoItem
v-for="(item, index) in todos"
:key="index"
:item="item"
@update="updateTodo"
@delete="deleteTodo"
/>
</div>
<div v-else class="text-center">没有任务</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import TodoItem from './TodoItem.vue'
const todos = ref<{ text: string; completed: boolean }[]>([])
const newTodo = ref('')
const addTodo = () => {
if (newTodo.value.trim()) {
todos.value.push({ text: newTodo.value, completed: false })
newTodo.value = ''
}
}
const updateTodo = (updatedItem: { text: string; completed: boolean }) => {
const index = todos.value.findIndex((item) => item.text === updatedItem.text)
if (index !== -1) {
todos.value[index] = updatedItem
}
}
const deleteTodo = (itemToDelete: { text: string; completed: boolean }) => {
todos.value = todos.value.filter((item) => item !== itemToDelete)
}
</script>
5. 使用组件
在 App.vue 中使用 TodoList 组件:
<template>
<div>
<TodoList />
</div>
</template>
<script setup lang="ts">
import TodoList from './components/TodoList.vue'
</script>
<style>
body {
font-family: 'Arial', sans-serif;
background-color: #f7fafc;
}
</style>
6. 运行项目
最后,启动项目:
npm run dev
打开浏览器访问 http://localhost:5173/,就可以看到一个简洁的待办应用了。可以新增和删除待办项,点击每个待办项,可以实现任务【完成】和【未完成】的状态。