1. Vue 是什么?
Vue.js 是一个用于构建用户界面的渐进式框架:
- 核心库:专注视图层(约40KB),提供数据驱动、组件系统等核心功能
- 渐进式:可逐步集成路由、状态管理等扩展
- 设计理念:通过简洁的API实现高效开发
渐进式框架实践路径:
<!-- 阶段1:核心视图渲染 -->
<div id="app">{{ message }}</div>
<!-- 阶段2:添加组件系统 -->
<user-profile :user="currentUser"></user-profile>
<!-- 阶段3:集成路由 -->
<router-link to="/dashboard">控制台</router-link>
<!-- 阶段4:加入状态管理 -->
<script setup>
import { useCartStore } from '@/stores/cart'
</script>
2. data
属性深度解析
作用:声明组件的响应式数据
原理:Vue3 使用 Proxy 实现数据劫持,自动追踪依赖
export default {
data() {
return {
// 基本类型(自动响应)
count: 0,
// 对象类型(嵌套属性自动响应)
user: {
name: '张三',
address: {
city: '北京'
}
},
// 数组类型(需使用变异方法)
items: ['苹果', '香蕉']
}
}
}
注意事项:
- 必须使用函数返回新对象(避免组件复用数据共享)
- 新增属性需使用
this.$set()
(Vue2) 或直接赋值 (Vue3) - 数组修改需使用
push()/pop()/splice()
等变异方法
3. methods
全面指南
作用:定义可在模板中调用的方法
export default {
data() { return { count: 0 } },
methods: {
// ✅ 标准函数 - this 指向组件实例
increment() {
this.count++
console.log(this.$data) // 访问组件数据
},
// ✅ 带参数方法
add(num) {
this.count += num
},
// ❌ 错误:箭头函数导致 this 丢失
decrement: () => {
// 此处 this 为 undefined 或 window 对象
this.count--
}
}
}
为什么 this 能访问 data?
Vue 在初始化时自动绑定 methods 的 this 上下文到组件实例
4. 模板语法:Mustache 插值
双大括号 {{ }}
支持所有 JavaScript 表达式
<div>
<!-- 1. 基础文本绑定 -->
<p>{{ message }}</p>
<!-- 2. 表达式计算 -->
<p>总价: ¥{{ (price * quantity).toFixed(2) }}</p>
<!-- 3. 三元运算 -->
<p>状态: {{ isActive ? '已激活' : '未激活' }}</p>
<!-- 4. 方法调用 -->
<p>倒序文本: {{ reverseString('Vue3') }}</p>
<!-- 5. 受限使用:不能包含语句 -->
<!-- ❌ 错误:{{ let x = 10 }} -->
<!-- 6. 对象属性访问 -->
<p>城市: {{ user.address.city }}</p>
</div>
5. 指令系统深度解析
指令是带有 v-
前缀的特殊属性,用于 DOM 动态操作
5.1 v-text 与 v-html
<!-- 文本内容绑定(等效于 {{}}) -->
<p v-text="rawText"></p>
<!-- 原始HTML渲染(慎用XSS风险) -->
<div v-html="htmlContent"></div>
<!-- 使用场景:渲染富文本编辑器内容 -->
<div v-html="sanitizedContent"></div>
5.2 v-show 与 v-if
<!-- v-show:CSS display 切换(适合频繁切换) -->
<div v-show="isLoggedIn">用户控制台</div>
<!-- v-if/v-else:条件渲染(适合不频繁切换) -->
<template v-if="score >= 90">
<span class="gold">A+</span>
<p>优秀!</p>
</template>
<div v-else-if="score >= 60">B</div>
<div v-else class="warning">C(需补考)</div>
<!-- 特殊场景:与 v-for 共用 -->
<template v-for="item in list">
<li v-if="item.isVisible">{{ item.name }}</li>
</template>
5.3 v-for 循环指令
<!-- 数组遍历 -->
<ul>
<li v-for="(item, index) in items" :key="item.id">
{{ index + 1 }}. {{ item.name }}
</li>
</ul>
<!-- 对象遍历 -->
<div v-for="(value, key) in userInfo" :key="key">
{{ key }}: {{ value }}
</div>
<!-- 使用范围值 -->
<span v-for="n in 10">{{ n }} </span>
<!-- 注意事项 -->
<!-- ❌ 错误:缺少 key -->
<!-- ❌ 错误:v-for 和 v-if 同元素(Vue3允许但性能不佳) -->
5.4 v-on 事件绑定
<!-- 基础用法 -->
<button v-on:click="submitForm">提交</button>
<!-- 缩写语法 -->
<button @click="count += 1">+1</button>
<!-- 内联语句 -->
<button @click="showAlert('确认操作?')">提示</button>
<!-- 事件修饰符 -->
<form @submit.prevent="onSubmit">...</form>
<input @keyup.enter="search">
<div @click.self="closeModal">...</div>
<!-- 事件对象访问 -->
<button @click="handleClick($event)">按钮</button>
<!-- 修饰符串联 -->
<div @click.stop.prevent="doThis"></div>
5.5 v-bind 属性绑定
<!-- 基础绑定 -->
<img v-bind:src="imageUrl">
<!-- 缩写语法 -->
<img :src="dynamicPath">
<!-- Class 绑定 -->
<div :class="{ active: isActive, 'text-danger': hasError }"></div>
<div :class="[isActive ? 'active' : '', errorClass]"></div>
<!-- Style 绑定 -->
<div :style="{ color: activeColor, fontSize: size + 'px' }"></div>
<div :style="[baseStyles, overridingStyles]"></div>
<!-- 属性绑定 -->
<button :disabled="isProcessing">提交</button>
5.6 v-model 双向绑定
<!-- 文本输入 -->
<input v-model="username" placeholder="请输入用户名">
<!-- 多行文本 -->
<textarea v-model="description"></textarea>
<!-- 单个复选框 -->
<input type="checkbox" v-model="agree"> 同意协议
<!-- 多个复选框 -->
<input type="checkbox" value="vue" v-model="skills">
<input type="checkbox" value="react" v-model="skills">
<!-- 单选按钮 -->
<input type="radio" value="A" v-model="answer">
<!-- 下拉选择 -->
<select v-model="selectedCity">
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
</select>
<!-- 修饰符 -->
<input v-model.lazy="searchQuery"> <!-- 失焦时更新 -->
<input v-model.number="age"> <!-- 自动转数字 -->
<input v-model.trim="email"> <!-- 自动去空格 -->
5.7 特殊指令
<!-- v-pre:跳过编译 -->
<div v-pre>{{ 原始模板内容 }}</div>
<!-- v-cloak:隐藏未编译模板 -->
<style>
[v-cloak] { display: none }
</style>
<div v-cloak>{{ message }}</div>
<!-- v-once:单次渲染 -->
<footer v-once>© 2023 公司名称</footer>
<!-- 自定义指令(简例) -->
<p v-highlight="'yellow'">重点内容</p>
6. 指令综合应用案例
<div id="app">
<!-- 搜索过滤 + 列表渲染 -->
<input v-model="searchText" placeholder="搜索...">
<ul>
<li v-for="item in filteredList"
:key="item.id"
:class="{ highlight: item.important }">
{{ item.name }}
<button @click.stop="deleteItem(item.id)">删除</button>
</li>
</ul>
<!-- 表单验证 + 条件渲染 -->
<form @submit.prevent="submitForm">
<input v-model.trim="email" type="email">
<p v-if="!emailValid" class="error">邮箱格式错误</p>
<select v-model="department">
<option v-for="dept in departments" :value="dept.id">
{{ dept.name }}
</option>
</select>
<button :disabled="!formValid">提交</button>
</form>
<!-- 动态样式 -->
<div :style="{
width: progress + '%',
backgroundColor: progressColor
}" class="progress-bar"></div>
</div>
关键概念对比表
指令/特性 | 使用场景 | 注意事项 |
---|---|---|
v-show vs v-if | 频繁切换 vs 初始条件 | v-if 有更高切换开销 |
v-for key | 列表渲染 | 必须使用唯一标识 |
v-model | 表单输入绑定 | 修饰符改变更新时机 |
methods 函数 | 事件处理/数据操作 | 避免箭头函数 |
data 属性 | 存储响应式数据 | 复杂对象需深度响应 |
Mustache | 文本插值 | 不支持语句 |