当然, 我们可以扩展之前的 Todo 例程, 加入编辑功能和 Markdown 支持。我们将使用一个简单的 Markdown 解析器 (如 marked. Js)来实现 Markdown 功能。以下是更新后的代码:

  1. 首先, 安装必要的依赖:
bun add marked
  1. 更新 src/App.vue:
<template>
  <div class="p-4 max-w-2xl mx-auto">
    <h1 class="text-3xl font-bold mb-4">Todo App with Markdown</h1>
    <form @submit.prevent="addTodo" class="mb-4">
      <input v-model="newTodo" type="text" placeholder="Add a new todo" class="border p-2 mr-2 w-full mb-2">
      <button type="submit" class="bg-blue-500 text-white p-2 rounded hover:bg-blue-600">Add</button>
    </form>
    <ul>
      <li v-for="todo in todos" :key="todo.id" class="mb-4 bg-gray-100 p-4 rounded">
        <div v-if="editingId !== todo.id">
          <div class="flex items-center mb-2">
            <input type="checkbox" v-model="todo.completed" class="mr-2">
            <span :class="{ 'line-through': todo.completed }">{{ todo.text }}</span>
            <button @click="startEditing(todo)" class="ml-auto text-blue-500 mr-2">Edit</button>
            <button @click="removeTodo(todo.id)" class="text-red-500">Remove</button>
          </div>
          <div v-html="renderMarkdown(todo.text)" class="markdown-content text-sm text-gray-600"></div>
        </div>
        <div v-else>
          <textarea v-model="editingText" class="w-full p-2 border rounded mb-2"></textarea>
          <button @click="saveEdit(todo)" class="bg-green-500 text-white p-2 rounded mr-2">Save</button>
          <button @click="cancelEdit" class="bg-gray-500 text-white p-2 rounded">Cancel</button>
        </div>
      </li>
    </ul>
  </div>
</template>
 
<script lang="ts">
import { defineComponent, ref } from 'vue'
import { marked } from 'marked'
 
interface Todo {
  id: number
  text: string
  completed: boolean
}
 
export default defineComponent({
  name: 'App',
  setup() {
    const newTodo = ref('')
    const todos = ref<Todo[]>([])
    const editingId = ref<number | null>(null)
    const editingText = ref('')
 
    const addTodo = () => {
      if (newTodo.value.trim()) {
        todos.value.push({
          id: Date.now(),
          text: newTodo.value,
          completed: false
        })
        newTodo.value = ''
      }
    }
 
    const removeTodo = (id: number) => {
      todos.value = todos.value.filter(todo => todo.id !== id)
    }
 
    const startEditing = (todo: Todo) => {
      editingId.value = todo.id
      editingText.value = todo.text
    }
 
    const saveEdit = (todo: Todo) => {
      if (editingText.value.trim()) {
        todo.text = editingText.value
        cancelEdit()
      }
    }
 
    const cancelEdit = () => {
      editingId.value = null
      editingText.value = ''
    }
 
    const renderMarkdown = (text: string) => {
      return marked(text)
    }
 
    return {
      newTodo,
      todos,
      editingId,
      editingText,
      addTodo,
      removeTodo,
      startEditing,
      saveEdit,
      cancelEdit,
      renderMarkdown
    }
  }
})
</script>
 
<style>
.markdown-content {
  @apply prose prose-sm;
}
</style>
  1. 更新 uno.config.ts 以支持 Markdown 样式:
import { defineConfig, presetUno, presetTypography } from 'unocss'
 
export default defineConfig({
  presets: [
    presetUno(),
    presetTypography(),
  ],
})

这个更新后的 Todo 应用现在具有以下新功能:

  1. 编辑功能: 用户可以点击 “Edit” 按钮来编辑现有的 Todo 项目。
  2. Markdown 支持: Todo 项目的文本内容支持 Markdown 格式, 并会被渲染为 HTML。
  3. 改进的 UI: 使用了更多的 UnoCSS 类来美化界面。

使用说明:

  • 添加新的 Todo 项目时, 可以使用 Markdown 语法。
  • 点击 “Edit” 按钮可以编辑现有的 Todo 项目。
  • 编辑时, 可以查看和修改原始的 Markdown 文本。
  • 保存编辑后, Markdown 内容会被重新渲染。

这个例子展示了如何将 UnoCSS 与 Vue 3、TypeScript 和 Markdown 功能结合使用, 创建一个功能更丰富的 Todo 应用。UnoCSS 的 prose 类用于美化渲染后的 Markdown 内容, 使其更易读。

注意: 为了安全起见, 在实际应用中, 你可能需要使用一个 Markdown 解析器, 它可以防止 XSS 攻击, 例如使用 DOMPurify 来清理 HTML 输出。