Vue 基础与核心
Vue 是渐进式 JS 框架,核心思想是数据驱动视图(MVVM):你只管改数据,视图自动更新,不用再手动操作 DOM。
这一篇讲 Vue 的基础与核心:实例、插值、响应式原理、指令、修饰符、class/style 绑定、计算属性、侦听器、生命周期。
Java 对照:传统方式(含 jQuery)是”手动查 DOM、改 DOM”;Vue 是”改数据、框架帮你改 DOM”。这是理解 Vue 最重要的思维转变。
一、MVVM 思想
1
| Model(数据 data) ⇄ ViewModel(Vue 实例) ⇄ View(模板 DOM)
|
- Model:数据(
data)
- View:页面模板(HTML)
- ViewModel:Vue 实例,负责双向绑定——数据变了自动更新视图,视图输入自动更新数据。
二、创建 Vue 实例与插值
1 2 3 4 5 6 7 8 9 10
| <div id="app">{{ message }}</div>
<script src="vue.js"></script> <script> const vm = new Vue({ el: "#app", data: { message: "Hello Vue" }, methods: {} }); </script>
|
插值表达式 {{ }}:
1 2 3
| <p>{{ message }}</p> <p>{{ 1 + 1 }}</p> <p>{{ message.toUpperCase() }}</p>
|
⚠️ 插值里只能写表达式(有返回值),不能写语句(if、for、var 等都不行)。
三、响应式原理
Vue2 通过 Object.defineProperty 劫持 data 里的属性,数据一变,用到它的视图自动更新:
1 2 3
| data: { count: 0 }
vm.count = 1;
|
⚠️ 坑:data 里后添加的属性不是响应式的(改它视图不更新),要用 Vue.set(obj, key, value) 或 this.$set 添加。所以 data 里最好提前声明所有要用的字段。
四、常用指令
| 指令 |
作用 |
简写 |
v-html |
解析 HTML 插入 |
无 |
v-show |
切换显示(display:none) |
无 |
v-if / v-else-if / v-else |
条件渲染(销毁/重建) |
无 |
v-on |
绑定事件 |
@ |
v-bind |
绑定属性 |
: |
v-for |
列表渲染 |
无 |
v-model |
双向绑定 |
无 |
1. v-html(对比插值)
1 2
| <div v-html="htmlStr"></div> <p>{{ htmlStr }}</p>
|
⚠️ v-html 有 XSS 风险,不要渲染用户输入的内容。
2. v-show vs v-if
1 2
| <div v-show="flag">显示/隐藏</div> <div v-if="flag">条件渲染</div>
|
v-show:始终渲染,只是切换 display:none,适合频繁切换。
v-if:条件为假时不渲染/销毁,适合不常切换或初始不渲染。
3. v-on 事件绑定
1 2
| <button v-on:click="count++">点我</button> <button @click="handleClick">点我</button>
|
1 2 3 4 5
| methods: { handleClick(e) { console.log(e); } }
|
传参:@click="handle(1, $event)"($event 是事件对象)。
4. v-bind 属性绑定
1 2 3
| <img :src="imgUrl"> <a :href="url">链接</a> <button :disabled="isDis">按钮</button>
|
5. v-for 列表渲染
1
| <li v-for="(item, index) in list" :key="item.id">{{ item.name }}</li>
|
1 2 3
| data: { list: [{ id: 1, name: "A" }, { id: 2, name: "B" }] }
|
⚠️ key 很重要:v-for 必须加 :key(唯一值,一般用 id,不要用 index),Vue 靠 key 做 diff 优化,key 不对会导致列表错乱/复用错误。
6. v-model 双向绑定
1 2
| <input v-model="message">
|
- 数据 → 视图(输入框显示 message)
- 视图 → 数据(输入时自动更新 message)
五、指令修饰符
1. 事件修饰符
1 2 3
| <button @click.stop="fn">阻止冒泡</button> <a @click.prevent="fn">阻止默认行为(如跳转)</a> <button @click.once="fn">只触发一次</button>
|
2. v-model 修饰符
1 2 3
| <input v-model.trim="name"> <input v-model.number="age"> <input v-model.lazy="msg">
|
六、class 与 style 绑定
1. class 对象语法
1
| <div :class="{ active: isActive, red: isRed }"></div>
|
1 2
| data: { isActive: true, isRed: false }
|
2. class 数组语法
1
| <div :class="[classA, classB]"></div>
|
3. style 绑定
1
| <div :style="{ color: textColor, fontSize: size + 'px' }"></div>
|
七、计算属性 computed
计算属性根据已有数据派生新值,且有缓存。
1 2 3 4 5 6 7 8 9 10 11 12
| new Vue({ data: { num: 1 }, computed: { double() { return this.num * 2; }, full: { get() { return this.num; }, set(val) { this.num = val; } } } });
|
computed vs methods
|
computed |
methods |
| 缓存 |
✅ 依赖不变不重新计算 |
❌ 每次调用都执行 |
| 写法 |
{{ double }}(不加括号) |
{{ double() }}(加括号) |
记忆点:有依赖、要缓存、要派生值 → 用 computed;纯逻辑操作、要传参 → 用 methods。
八、侦听器 watch
watch 监听数据变化,执行副作用(发请求、异步操作、操作 DOM)。
1 2 3 4 5 6 7 8 9 10 11 12 13
| new Vue({ data: { keyword: "" }, watch: { keyword(newVal, oldVal) { console.log(newVal, oldVal); }, user: { handler(newVal) { }, deep: true, immediate: true } } });
|
watch vs computed
|
computed |
watch |
| 目的 |
派生新值(有返回值) |
执行副作用(无返回值) |
| 缓存 |
有 |
无 |
| 场景 |
根据数据算结果 |
数据变化时发请求、异步 |
记忆:要”算一个新值”用 computed,要”数据变了去做事”用 watch。
九、生命周期(四大阶段、八个钩子)
Vue 实例从创建到销毁会依次触发 8 个钩子:
| 阶段 |
钩子 |
时机与常用场景 |
| 创建 |
beforeCreate |
数据/方法还没初始化(少用) |
| 创建 |
created |
data/methods 已就绪,DOM 未生成,常用:发请求 |
| 挂载 |
beforeMount |
模板编译完成,未挂载(少用) |
| 挂载 |
mounted |
DOM 已挂载,常用:操作 DOM、初始化图表 |
| 更新 |
beforeUpdate |
数据更新,DOM 未重渲染(少用) |
| 更新 |
updated |
DOM 已更新(少用) |
| 销毁 |
beforeDestroy |
销毁前,常用:清定时器、解绑事件 |
| 销毁 |
destroyed |
已销毁(少用) |
1 2 3 4 5 6 7 8 9 10 11 12 13
| new Vue({ el: "#app", data: {}, created() { }, mounted() { }, beforeDestroy() { } });
|
⚠️ 两个高频场景记住:created 里发请求(数据早拿到)、mounted 里操作 DOM(DOM 已就绪)。
十、速查表
| 需求 |
写法 |
| 创建实例 |
new Vue({ el, data, methods }) |
| 插值 |
{{ message }} |
| 解析 HTML |
v-html="str" |
| 条件渲染 |
v-if / v-else / v-show |
| 事件绑定 |
@click="fn" |
| 属性绑定 |
:href="url" |
| 列表渲染 |
v-for="(item, i) in list" :key="item.id" |
| 双向绑定 |
v-model="msg" |
| 事件修饰符 |
@click.stop / @click.prevent / .once |
| v-model 修饰符 |
.trim / .number / .lazy |
| class 对象绑定 |
:class="{ active: isActive }" |
| 计算属性 |
computed: { double() { return ... } } |
| 侦听器 |
watch: { key(newVal, oldVal) {} } |
| 深度/立即监听 |
deep: true / immediate: true |
| 发请求钩子 |
created() |
| 操作 DOM 钩子 |
mounted() |
十一、复习要点
- MVVM:改数据 → 视图自动更新,不手动操作 DOM(这是 Vue 的核心思想)。
new Vue({ el, data, methods, computed, watch }) 是 Options API 的骨架。
- v-show 是 display:none 切换,v-if 是销毁/重建;频繁切换用 v-show。
v-for 必须加 :key(唯一值,别用 index)。
v-model = :value + @input 的语法糖。
- computed 有缓存、用于派生值;watch 用于副作用(发请求/异步)。
- 生命周期八钩子,重点记 created(发请求) 和 mounted(操作 DOM)。
data 里后加属性不是响应式,要用 $set;提前声明所有字段。
- 忘了某条,回本文对应小节看示例即可。
下一篇预告:组件化开发——组件注册、props/事件、插槽、自定义指令、$refs、v-model 原理等组件通信全体系。