vue实现双向绑定代码
Vue 2 实现双向绑定
Vue 2 使用 v-model 指令实现双向绑定,主要基于 Object.defineProperty 实现数据劫持。
<template>
<div>
<input v-model="message" placeholder="输入内容">
<p>输入的内容是: {{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
}
}
}
</script>
自定义组件中实现双向绑定:
<template>
<custom-input v-model="message"></custom-input>
</template>
<script>
export default {
components: {
'custom-input': {
props: ['value'],
template: `
<input
:value="value"
@input="$emit('input', $event.target.value)"
>
`
}
},
data() {
return {
message: ''
}
}
}
</script>
Vue 3 实现双向绑定
Vue 3 使用 v-model 指令,底层基于 Proxy 实现响应式。

<template>
<input v-model="message" placeholder="输入内容">
<p>输入的内容是: {{ message }}</p>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const message = ref('')
return { message }
}
}
</script>
自定义组件中实现双向绑定:
<template>
<custom-input v-model="message"></custom-input>
</template>
<script>
import { ref } from 'vue'
export default {
components: {
'custom-input': {
props: ['modelValue'],
emits: ['update:modelValue'],
template: `
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
`
}
},
setup() {
const message = ref('')
return { message }
}
}
</script>
手动实现简易双向绑定
以下是一个基于 Object.defineProperty 的简易实现:

function defineReactive(obj, key) {
let value = obj[key]
const dep = new Dep()
Object.defineProperty(obj, key, {
get() {
if (Dep.target) {
dep.addSub(Dep.target)
}
return value
},
set(newVal) {
if (newVal === value) return
value = newVal
dep.notify()
}
})
}
class Dep {
constructor() {
this.subs = []
}
addSub(sub) {
this.subs.push(sub)
}
notify() {
this.subs.forEach(sub => sub.update())
}
}
class Watcher {
constructor(vm, exp, cb) {
this.vm = vm
this.exp = exp
this.cb = cb
Dep.target = this
this.value = vm[exp]
Dep.target = null
}
update() {
const value = this.vm[this.exp]
if (value !== this.value) {
this.value = value
this.cb.call(this.vm, value)
}
}
}
使用示例:
const data = { message: 'Hello' }
defineReactive(data, 'message')
new Watcher(data, 'message', value => {
console.log('值变化:', value)
})
data.message = 'World' // 控制台输出: 值变化: World
注意事项
Vue 2 中数组和对象需要特殊处理,Vue.set 或 this.$set 用于添加响应式属性
Vue 3 的 Proxy 实现可以自动检测深层对象变化,无需特殊处理
自定义组件中,Vue 2 默认使用 value 属性和 input 事件,Vue 3 使用 modelValue 属性和 update:modelValue 事件






