工学云
150.99MB · 2026-02-11
在 React、Angular、Svelte 等框架中,Vue 凭借以下优势成为新手友好之选:
| 特性 | 说明 |
|---|---|
| 渐进式框架 | 可从 CDN 引入,也可构建大型 SPA |
| 中文文档完善 | 官方提供高质量中文文档 |
| Composition API | 逻辑复用更灵活(类似 React Hooks) |
| 开发体验优秀 | Vite 极速启动,HMR 热更新毫秒级 |
<!DOCTYPE html>
<html>
<head>
<title>My First Vue App</title>
<!-- 从 CDN 加载 Vue 3 -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h1>{{ message }}</h1>
<button @click="reverseMessage">反转消息</button>
</div>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
const message = ref('Hello Vue!')
const reverseMessage = () => {
message.value = message.value.split('').reverse().join('')
}
return {
message,
reverseMessage
}
}
}).mount('#app')
</script>
</body>
</html>
# 创建项目
npm create vue@latest my-vue-app
# 按提示选择(建议全选默认)
Project name: … my-vue-app
Add TypeScript? … No
Add JSX Support? … No
Add Vue Router? … No
Add Pinia? … No
Add Vitest? … No
Add Cypress? … No
Add ESLint? … Yes
Add Prettier? … Yes
# 进入目录并安装依赖
cd my-vue-app
npm install
# 启动开发服务器
npm run dev
访问 ,看到 Vue 官方欢迎页即成功!
ref 与 reactiveref:用于基本类型(字符串、数字、布尔值)<script setup>
import { ref } from 'vue'
// 创建响应式引用
const count = ref(0)
// 修改值必须通过 .value
const increment = () => {
count.value++
}
</script>
<template>
<p>计数: {{ count }}</p>
<button @click="increment">+1</button>
</template>
reactive:用于对象/数组<script setup>
import { reactive } from 'vue'
const user = reactive({
name: 'Alice',
age: 25
})
const updateAge = () => {
user.age++ // 直接修改属性
}
</script>
<template>
<p>{{ user.name }} - {{ user.age }}岁</p>
<button @click="updateAge">长大一岁</button>
</template>
@click 与方法<template>
<!-- 方法调用 -->
<button @click="greet">打招呼</button>
<!-- 内联处理器 -->
<button @click="count++">直接修改</button>
<!-- 传递参数 -->
<button @click="deleteItem(item.id)">删除</button>
<!-- 修饰符:阻止默认行为 -->
<form @submit.prevent="handleSubmit">
<input type="text" v-model="input">
<button type="submit">提交</button>
</form>
</template>
<script setup>
const greet = () => {
alert('Hello!')
}
const deleteItem = (id) => {
console.log('删除ID:', id)
}
const handleSubmit = () => {
console.log('表单提交')
}
</script>
v-if vs v-show<template>
<!-- v-if:条件为假时完全移除 DOM -->
<div v-if="isLoggedIn">欢迎回来!</div>
<!-- v-else / v-else-if -->
<div v-else-if="isLoading">加载中...</div>
<div v-else>请先登录</div>
<!-- v-show:始终渲染 DOM,仅切换 display -->
<div v-show="showModal" class="modal">弹窗内容</div>
</template>
v-for<template>
<!-- 渲染数组 -->
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
<!-- 渲染对象 -->
<div v-for="(value, key) in userInfo" :key="key">
{{ key }}: {{ value }}
</div>
<!-- 带索引 -->
<div v-for="(item, index) in list" :key="item.id">
{{ index + 1 }}. {{ item.title }}
</div>
</template>
<script setup>
const items = [
{ id: 1, name: '苹果' },
{ id: 2, name: '香蕉' }
]
const userInfo = {
name: 'Bob',
email: 'bob@example.com'
}
</script>
v-model<template>
<!-- 文本输入 -->
<input v-model="message" placeholder="输入消息">
<p>实时预览: {{ message }}</p>
<!-- 多行文本 -->
<textarea v-model="description"></textarea>
<!-- 复选框 -->
<input type="checkbox" v-model="isChecked">
<span>{{ isChecked ? '已选中' : '未选中' }}</span>
<!-- 单选按钮 -->
<input type="radio" v-model="picked" value="A"> A
<input type="radio" v-model="picked" value="B"> B
<!-- 下拉选择 -->
<select v-model="selected">
<option disabled value="">请选择</option>
<option>A</option>
<option>B</option>
</select>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('')
const description = ref('')
const isChecked = ref(false)
const picked = ref('A')
const selected = ref('')
</script>
<!-- src/components/MyButton.vue -->
<template>
<button
class="my-button"
:class="{ 'primary': primary }"
@click="handleClick"
>
<slot></slot> <!-- 插槽:接收父组件内容 -->
</button>
</template>
<script setup>
defineProps({
primary: Boolean // 接收父组件传入的属性
})
const emit = defineEmits(['click']) // 声明触发的事件
const handleClick = () => {
emit('click') // 触发 click 事件
}
</script>
<style scoped>
.my-button {
padding: 8px 16px;
border: 1px solid #ccc;
border-radius: 4px;
cursor: pointer;
}
.primary {
background: #409eff;
color: white;
}
</style>
<script setup>
import MyButton from './components/MyButton.vue'
import { ref } from 'vue'
const count = ref(0)
const increment = () => count.value++
</script>
<template>
<div>
<p>计数: {{ count }}</p>
<!-- 使用组件,传递 props 和事件 -->
<MyButton
:primary="true"
@click="increment"
>
点我加1!
</MyButton>
</div>
</template>
将所学知识整合为一个完整小应用!
src/
├── components/
│ └── TodoItem.vue
└── App.vue
<script setup>
import { ref } from 'vue'
import TodoItem from './components/TodoItem.vue'
const newTodo = ref('')
const todos = ref([
{ id: 1, text: '学习 Vue', done: false }
])
const addTodo = () => {
if (newTodo.value.trim()) {
todos.value.push({
id: Date.now(),
text: newTodo.value,
done: false
})
newTodo.value = ''
}
}
const removeTodo = (id) => {
todos.value = todos.value.filter(todo => todo.id !== id)
}
</script>
<template>
<div class="todo-app">
<h1>我的待办事项</h1>
<!-- 添加新任务 -->
<form @submit.prevent="addTodo">
<input
v-model="newTodo"
placeholder="输入新任务..."
@keyup.enter="addTodo"
>
<button type="submit">添加</button>
</form>
<!-- 任务列表 -->
<ul>
<TodoItem
v-for="todo in todos"
:key="todo.id"
:todo="todo"
@remove="removeTodo(todo.id)"
/>
</ul>
<p>剩余: {{ todos.filter(t => !t.done).length }} 项</p>
</div>
</template>
<template>
<li class="todo-item">
<input
type="checkbox"
v-model="todo.done"
>
<span :class="{ done: todo.done }">{{ todo.text }}</span>
<button @click="$emit('remove')">删除</button>
</li>
</template>
<script setup>
defineProps({
todo: Object
})
defineEmits(['remove'])
</script>
<style scoped>
.done {
text-decoration: line-through;
color: #999;
}
</style>
安装 Vue Devtools 扩展:
// 在 setup() 中
console.log('当前状态:', reactiveData)
| 错误现象 | 解决方案 |
|---|---|
| 数据不更新 | 检查是否用 ref/reactive 包裹 |
| 事件不触发 | 检查 @click 是否拼写正确 |
| 组件不显示 | 检查是否正确 import 和注册 |
| 样式失效 | 检查 <style scoped> 是否冲突 |
| 概念 | 关键语法 | 用途 |
|---|---|---|
| 响应式 | ref(), reactive() | 数据驱动视图 |
| 模板指令 | v-if, v-for, v-model | 声明式渲染 |
| 事件处理 | @click, .prevent | 用户交互 |
| 组件通信 | props, emit, slots | 模块化开发 |
| 组合式 API | setup(), script setup | 逻辑复用 |
资源推荐:
如果你希望我提供 完整的 Todo List 项目代码仓库 或 Vue 3 + TypeScript 版本示例,欢迎继续提问!