Vue数据绑定
一、什么是数据绑定?
数据绑定是指将 JavaScript 中的数据与 HTML 视图建立关联,当数据变化时,视图自动更新;在某些情况下(如表单),视图的变化也能反过来更新数据。
Vue 的数据绑定分为两种主要形式:
类型 | 方向 | 典型场景 |
---|---|---|
单向数据绑定 | 数据 → 视图 | 文本、属性、条件渲染 |
双向数据绑定 | 数据 ⇄ 视图 | 表单输入(v-model ) |
二、单向数据绑定:数据驱动视图
1. 文本插值 {{ }}
最简单的数据绑定方式,将数据渲染为文本。
<p>{{ message }}</p>
<p>{{ user.name }}</p>
data() {return {message: 'Hello Vue!',user: { name: 'Alice' }}
}
当 message
或 user.name
变化时,<p>
标签内容自动更新。
2. 属性绑定 v-bind
(简写 :
)
用于动态绑定 HTML 属性。
<img :src="imageSrc" :alt="imageAlt">
<button :disabled="isButtonDisabled">点击我</button>
<div :class="{ active: isActive }"></div>
data() {return {imageSrc: 'https://example.com/logo.png',imageAlt: 'Logo',isButtonDisabled: true,isActive: false}
}
✅ 特点:数据变化 → 属性/样式自动更新。
三、双向数据绑定:v-model
的魔法
v-model
是 Vue 中实现表单元素与数据双向同步的核心指令。
1. 基本用法
<input v-model="message" placeholder="输入内容" />
<p>你输入的是:{{ message }}</p>
data() {return {message: ''}
}
- 当用户在输入框中输入时,
message
数据自动更新。 - 当
message
在代码中被修改时,输入框的值也同步变化。
2. v-model
的本质
v-model
并非“魔法”,而是语法糖,等价于:
<!-- v-model="message" 等价于: -->
<input :value="message" @input="message = $event.target.value" />
即:
:value
实现 数据 → 视图@input
监听输入事件,实现 视图 → 数据
3. v-model
在不同表单元素中的应用
(1)<textarea>
<textarea v-model="text"></textarea>
(2)复选框(Checkbox)
<input type="checkbox" v-model="isChecked" />
<label>是否同意</label>
data() {return {isChecked: false // 布尔值}
}
(3)单选框(Radio)
<input type="radio" v-model="gender" value="male" name="gender"> 男
<input type="radio" v-model="gender" value="female" name="gender"> 女
data() {return {gender: 'male' // 字符串}
}
(4)下拉框(Select)
<select v-model="selected"><option value="A">选项 A</option><option value="B">选项 B</option>
</select>
data() {return {selected: 'A'}
}
(5)多个复选框绑定到数组
<input type="checkbox" v-model="hobbies" value="reading" /> 阅读
<input type="checkbox" v-model="hobbies" value="coding" /> 编程
data() {return {hobbies: [] // 数组}
}
四、Vue 响应式系统:数据绑定的基石
为什么数据变化,视图能自动更新?这得益于 Vue 的响应式系统。
Vue 2 vs Vue 3 实现原理
版本 | 原理 | 局限性 |
---|---|---|
Vue 2 | 使用 Object.defineProperty() 劫持对象属性的 getter 和 setter | 无法检测对象属性的添加/删除 |
Vue 3 | 使用 Proxy 代理整个对象 | 拦截能力更强,性能更好 |
Vue 3 响应式核心流程
import { reactive, effect } from 'vue';// 1. 创建响应式对象
const state = reactive({count: 0,message: 'Hello'
});// 2. 定义副作用(类似视图渲染)
effect(() => {console.log(state.count); // 依赖收集
});// 3. 修改数据 → 触发更新
state.count++; // 控制台自动打印新值
🔍 过程解析:
- 读取
state.count
时,Proxy
的get
拦截器触发,进行依赖收集。- 修改
state.count
时,set
拦截器触发,通知所有依赖更新。
五、如何让数据“响应式”?
1. 使用 reactive()
(Vue 3 Composition API)
import { reactive } from 'vue';const state = reactive({count: 0,user: { name: 'Bob' }
});
2. 使用 ref()
(支持基本类型)
import { ref } from 'vue';const count = ref(0); // ref 包装基本类型
const message = ref('Hello');// 访问值:count.value
console.log(count.value); // 0
3. data()
函数中的响应式(选项式 API)
export default {data() {return {count: 0,message: 'Hello'}}
}
Vue 会自动将 data
返回的对象转换为响应式。
六、常见问题与注意事项
1. 数组变更检测
Vue 能检测以下数组操作:
push()
,pop()
,shift()
,unshift()
,splice()
,sort()
,reverse()
但以下操作不会触发视图更新:
// ❌ 错误:直接通过索引设置
vm.items[indexOfItem] = newValue;// ✅ 正确:使用 Vue.set 或数组方法
Vue.set(vm.items, indexOfItem, newValue);
// 或
vm.items.splice(indexOfItem, 1, newValue);
2. 对象属性添加/删除
// ❌ 新增属性不会响应
this.user.age = 25;// ✅ 使用 Vue.set 或 $set
this.$set(this.user, 'age', 25);
// 或替换对象
this.user = { ...this.user, age: 25 };
✅ Vue 3 中
Proxy
已解决此问题,但为保持一致性,建议仍使用reactive
/ref
。
七、v-model
的修饰符
Vue 提供了便捷的修饰符来处理常见表单需求:
修饰符 | 作用 | 示例 |
---|---|---|
.lazy | 将 input 事件改为 change 事件 | <input v-model.lazy="msg"> |
.number | 自动将输入值转换为数字 | <input v-model.number="age"> |
.trim | 自动过滤首尾空格 | <input v-model.trim="name"> |
八、自定义组件上的 v-model
你也可以在自定义组件上使用 v-model
。
<!-- Parent.vue -->
<CustomInput v-model="message" /><!-- CustomInput.vue -->
<template><input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template><script>
export default {props: ['modelValue'],emits: ['update:modelValue']
}
</script>
✅ Vue 3 中
v-model
默认绑定modelValue
属性和update:modelValue
事件。
九、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!