双向数据绑定指的就是,绑定对象属性的改变到用户界面的变化的能力,反之亦然。换种说法,如果我们有一个user对象和一个name属性,一旦我们赋了一个新值给user.name,在UI上就会显示新的姓名了。同样地,如果UI包含了一个输入用户姓名的输入框,输入一个新值就应该会使user对象的name属性做出相应的改变。
详细的解释和例子可以看下这篇文章,http://www.php.cn/js-tutorial-4385.html,希望对你有帮助。
子组件在props中定义数据,然后父组件传数据过去,例如:子组件:props:{show:{default:false}}父组件://test是子组件名字parentShow是父组件定义的data数据。
vue将数据绑定到组件的原理如下:
1、当实例化一个Vue构造函数,会执行 Vue 的 init 方法,在 init 方法中主要执行三部分内容,一是初始化环境变量,而是处理 Vue 组件数据,三是解析挂载组件。以上三部分内容构成了 Vue 的整个执行过程。
2、Vue 实现了一个 观察者-消费者(订阅者) 模式来实现数据驱动视图。通过设定对象属性的 setter/getter 方法来监听数据的变化,而每个属性的 setter 方法就是一个观察者, 当属性变化将会向订阅者发送消息,从而驱动视图更新。
3、Vue 的订阅者 watcher 实现在 /src/watchr.js 。构建一个 watcher 最重要的是 expOrFn 和 cb 两个参数,cb 是订阅者收到消息后需要执行的回调,一般来说这个回调都是视图指令的更新方法,从而达到视图的更新,但是这也不是必须的,订阅回调也可以是一个和任何无关的纯函数。一个订阅者最重要的是要知道自己订阅了什么,watcher 分析 expOrFn 的 getter 方法,从而间接获得订阅的对象属性。
4、Vue 双向数据绑定实现
数据与视图的绑定与同步,最终体现在对数据的读写处理过程中,也就是 Object.defineProperty() 定义的数据 set、get 函数中。Vue 中对于的函数为 defineReactive,在精简版实现中,我只保留了一些基本特性:
function defineReactive(obj, key, value) {。
var dep = new Dep()。
Object.defineProperty(obj, key, {。
enumerable: true,。
configurable: true,。
get: function reactiveGetter() {。
if (Dep.target) {。
dep.depend()。
}
return value。
},
set: function reactiveSetter(newVal) {。
if (value === newVal) {。
return。
} else {。
value = newVal。
dep.notify()。
}
}
})
在对数据进行读取时,如果当前有 Watcher(对数据的观察者吧,watcher 会负责将获取的新数据发送给视图),那将该 Watcher 绑定到当前的数据上(dep.depend(),dep 关联当前数据和所有的 watcher 的依赖关系),是一个检查并记录依赖的过程。而在对数据进行赋值时,如果数据发生改变,则通知所有的 watcher(借助 dep.notify())。这样,即便是我们手动改变了数据,框架也能够自动将数据同步到视图。
贴出代码看看
以下是参照DEMO:
<!DOCTYPE html>。
<html>
<head lang="en">。
<meta charset="UTF-8">。
<title></title>。
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>。
</head>
<body>
<!--ng-model指令可以将输入域的值与AngularJS创建的变量绑定-->。
<div data-ng-app="myApp" data-ng-controller="Ctrl">。
名字:<input type="text" data-ng-model="name"/>。
</div>。
<script>。
var app=angular.module('myApp',[]);。
app.controller('Ctrl',function($scope){。
$scope.name='John Doe';。
})
</script>。
<hr/>。
<!--双向绑定-->。
<div id="dblBind" data-ng-app="dblBind" data-ng-controller="dblCtrl">。
名字:<input type="text" data-ng-model="name"/>。
<h1>你输入了:{{name}}</h1>。
</div>。
<script>。
var dblBind=angular.module('dblBind',[]);。
dblBind.controller('dblCtrl',function($scope){。
$scope.name='John Doe';。
})
angular.bootstrap(document.getElementById('dblBind'),['dblBind']);。
</script>。
<hr/>。
<!--验证用户输入-->。
<form data-ng-app="myForm" name="myFormValid">。
<!--注意ng-app的值与name值不能相同-->。
Email:
<input type="email" name="myEmail" data-ng-model="text"/>。
<span data-ng-show="myFormValid.myEmail.$error.email">不是一个合法的邮箱地址</span>。
</form>。
<script>。
var myFormApp=angular.module('myFormApp',[]);。
angular.bootstrap(document.getElementsByName('myFormValid'),['myFormApp']);。
</script>。
<hr/>。
<!--应用状态-->。
<!--ng-model可以为应用程序提供状态值(valid,dirty,touched,error)-->。
<form data-ng-app="myForm2" name="appStatus" data-ng-init="myText='test@163.com'">。
<p>Email:。
<input type="email" data-ng-model="myText" name="myEmail" required />。
</p>。
<h1>状态</h1>。
<!--$valid ng-valid Boolean 告诉我们这一项当前基于你设定的规则是否验证通过-->。
<!--$invalid ng-invalid Boolean 告诉我们这一项当前基于你设定的规则是否验证未通过-->。
<!--$pristine ng-pristine Boolean 如果表单或者输入框没有使用则为True-->。
<!--$dirty ng-dirty Boolean 如果表单或者输入框有使用到则为True-->。
is valid:{{appStatus.myEmail.$valid}}<br/>。
is dirty:{{appStatus.myEmail.$dirty}}<br/>。
is change:{{appStatus.myEmail.$touched}}<br/>。
is invalid:{{appStatus.myEmail.$invalid}}<br/>。
is pristine:{{appStatus.myEmail.$pristine}}<br/>。
is error:{{appStatus.myEmail.$error}}。
</form>。
<script>。
var appStatus=angular.module('appStatus',[]);。
angular.bootstrap(document.getElementsByName('appStatus'),['appStatus']);。
</script>。
<hr/>。
<!--ng-model指令基于他们的状态为HTML元素提供了CSS类-->。
<style>。
input.ng-invalid{。
background-color: lightblue;。
}
</style>。
<form data-ng-app="cssTestApp" name="cssTest">。
输入你的名字:
<input type="text" name="myName" data-ng-model="text" required />。
is valid:{{cssTest.myName.$valid}}<br/>。
</form>。
<script>。
var cssTestApp=angular.module('cssTestApp',[]);。
angular.bootstrap(document.getElementsByName('cssTest'),['cssTestApp']);。
</script>。
<!--ng-model指令可根据表单域的状态添加/移除以下类-->。
<!--ng-empty,ng-not-empty,ng-touched,ng-untouched,ng-valid,ng-invalid,ng-dirty,ng-pending,ng-pristine-->。
</body>
</html>
望采纳
结果:
代码如下:
<!DOCTYPE html>。
<html>
<head>
<meta charset="UTF-8">。
<title>Title</title>。
</head>
<body>
<table border="1"; style="width: 80%; margin: auto;" id="user_table">。
<tr>
<th rowspan="2">姓名</th>。
<th rowspan="2">手机号码</th>。
<th rowspan="2">员工id</th>。
<th colspan="5">用户信息</th>。
</tr>
<tr>
<th>safemobile</th>。
<th>用户名</th>。
<th>gravatar</th>。
<th>skin_id</th>。
<th>email</th>。
</tr>
</table>
<script>
/**
* 练习将数据绑定到页面中
* userList是一个数组,里面有3个对象,每个对象中包含一些值,其中:
* nickname:字符串 姓名。
* user:对象 里面是用户信息,里面的htcode是用户名。
* telephone:字符串 电话号码。
*/
var userList = [{。
"nickname": "lizeze",。
"user": {"safemobile": "13000000000", "htcode": "lize123", "gravatar": null, "skin_id": null, "email": null},。
"telephone": "13000000000",。
"employee_id": "ba5bb7a8a15c11e986c00242c0a88003",。
}, {
"nickname": "\u7533\u5c0f\u4e3d",。
"user": {"safemobile": "13940000000", "htcode": "cloudass", "gravatar": null, "skin_id": null, "email": null},。
"telephone": "13940000000",。
"employee_id": "2fca26bca15a11e9a21f0242c0a88003",。
}, {
"nickname": "wym001",。
"user": {"safemobile": "17600000000", "htcode": "wym001", "gravatar": null, "skin_id": null, "email": null},。
"telephone": "17600000000",。
"employee_id": "0158b1069ca811e9be780242c0a88003",。
}];
var html='';
for (var user of userList){。
(function (user) {。
html += ' <tr>\n' +。
' <td>'+user.nickname+'</td>\n' +。
' <td>'+user.telephone+'</td>\n' +。
' <td>'+user.employee_id+'</td>\n' +。
' <td>'+user.user.safemobile+'</td>\n' +。
' <td>'+user.user.htcode+'</td>\n' +。
' <td>'+user.user.gravatar+'</td>\n' +。
' <td>'+user.user.skin_id+'</td>\n' +。
' <td>'+user.user.email+'</td>\n' +。
' </tr>'。
})(user);
var table = document.getElementById("user_table");。
var srcHtml = table.innerHTML ;。
table.innerHTML = srcHtml + html;。
</script>。
</body>
</html>