何为数据的单向绑定?
传统开发模式下,如使用jQuery开发,我们想将一个变量显示到html中,首先要定义一个变量name,然后通过jq代码操作dom将变量放到HTML中,如果name发生修改,还要再次通过jq代码操作dom将新的变量值放到HTML中。这就是传统的MVC框架,其中的Model和View是我们通过代码联系在一起的。
在MVVM框架中,我们不再过多的关注数据与视图间的操作,而是使用一种新的机制,数据的单/双向绑定。
Vue单向数据绑定
Vue单向数据绑定,数据只能从data流向页面,即数据改变,页面元素也会跟着改变;而页面元素改变时,数据并不会跟着变。主要有两种形式:
1.插值形式
<template>
<div id="vm">
<p>Hello, {{name}}!</p>
<p>You are {{age}} years old!</p>
</div>
</template>
<script>
export default {
data(){
return{
name:'951',
age:28
}
}
}
<script>
2.v-bind形式
<template>
<div id="vm">
<p v-bind:class="classed">Hello, {{name}}!</p>
</div>
</template>
<script>
export default {
data(){
return{
name:'951',
classed:'red'
}
}
}
<script>
<style>
.red {
background: red;
}
.blue {
background: blue;
}
</style>
单向数据流过程:
简单的单向数据流(unidirectional data flow)是指用户访问View,View发出用户交互的Action,在Action里对state进行相应更新。state更新后会触发View更新页面的过程。这样数据总是清晰的单向进行流动,便于维护并且可以预测
原生js实如何现数据单向绑定?
首先会用到Object.defineProperty(),这个方法直接在对象上定义一个新属性,或修改对象上的现有属性,并返回该对象。
Object.defineProperty(obj, prop, descriptor)
参数
obj 定义属性的对象。
prop 要定义或修改的属性的名称。
descriptor 定义或修改属性的描述符。
返回值 传递给函数的对象。
注意:数据描述符和访问器描述符,不能同时存在(value,writable 和 get,set)
get:函数return将被用作属性的值。
set:该函数将仅接收参数赋值给该属性的新值。(在属性改变时调用)
看下边示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<input type="text" id="model"/>
<span id="spanCont">{{hello}}</span>
<script>
// 双向数据绑定的原理:属性拦截
// 属性拦截实现方式 : 使用Object.defineProperty()将对象的属性变成访问器属性。
var obj = {};
var model = document.querySelector("#model")
var spanCont = document.querySelector("#spanCont")
// obj 定义属性的对象。
//prop 要定义或修改的属性的名称。
//descriptor 定义或修改属性的描述符。
Object.defineProperty(obj, 'hello', {
get: function () {
return model.value;
},
set: function (val) {
spanCont.innerHTML = obj.hello;
}
});
document.getElementById('model').onkeyup = function () {
obj.hello = this.value;
};
obj.hello = ""; //属性名必须设置为空,否则在使用插值表达式的时候直接会把插值表达式显示出来
</script>
</body>
</html>