1、双向绑定是数据Model和视图View相互驱动更新
2、vue的双向绑定是基于MVVM模式设计开发的
3、vue中通过v-model体现双向绑定;v-model实际上是v-on和v-bind的语法糖
即和vue一样的方式来实现数据的双向绑定。那么,我们可以把整个实现过程分为下面几步:
输入框以及文本节点与 data 中的数据绑定
输入框内容变化时,data 中的数据同步变化,即 view => model 的变化 ( Object.defineProperty)
data 中的数据变化时,文本节点的内容同步变化,即 model => view 的变化 (模板编译)
vue2.0简易实现方法:
父组件
<template>
<div id="app">
{{username}} <br/>
<my-input type="text" :value="username" @input="update"></my-input>
</div>
</template>
<script>
import myinput from './components/myinput'
export default {
name: 'App',
components:{
myinput
},
data(){
return {
username:''
}
}
methods:{
update(val) {
this.userName = val
}
}
</script>
子组件
<template>
<div class="my-input">
<input type="text" class="my-input__inner" @input="handleInput"/>
</div>
</template>
<script>
export default {
name: "myinput",
props:{
value:{ //获取父组件的数据value
type:String,
default:''
}
},
methods:{
handleInput(e){
this.$emit('input',e.target.value) //触发父组件的input事件
}
}
}
</script>
原生js实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>forvue</title>
</head>
<body>
<input type="text" id="textInput">
输入:<span id="textSpan"></span>
<script>
var obj = {},
textInput = document.querySelector('#textInput'),
textSpan = document.querySelector('#textSpan');
Object.defineProperty(obj, 'foo', {
set: function (newValue) {
textInput.value = newValue;
textSpan.innerHTML = newValue;
}
});
textInput.addEventListener('keyup', function (e) {
obj.foo = e.target.value;
});
</script>
</body>
</html>
使用Object.defineProperty()来定义属性的set函数,属性被赋值的时候,通过操作dom修改Input的value值以及span中的innerHTML;然后监听input的keyup事件,修改对象的属性值,即可实现这样的一个简单的数据双向绑定