五十行javascript代码实现简单的双向数据绑定
2017-04-24 22:08
1116 查看
五十行javascript代码实现简单的双向数据绑定
Vue框架想必从事前端开发的同学都使用过,它的双向数据绑定机制能给我们带来很大的方便。今天闲着没事,尝试着实现一下双向数据绑定,接下来给大家分享一下。Object.defineProperty(obj, prop, descriptor)
Object.defineProperty方法允许精确添加或修改对象的属性。它的第一个参数
obj是要在其上定义属性的对象,第二个参数
prop是要定义或修改的属性的名称,第三个参数
descriptor是一个将被定义或修改的属性的描述符。
返回值: 被传递给函数的对象。
来举个例子:
var o = Object.defineProperty({}, 'name', { value: 1 }); console.log(o) // {name: 1}
这是最基本的定义一个对象的方式。对于属性描述符,还有很多其他属性:
数据描述符和存取描述符均具有以下可选键值:
configurable当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,也能够被删除。默认为 false。
enumerable当且仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false。
数据描述符同时具有以下可选键值:
value该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
writable当且仅当该属性的 writable 为 true 时,该属性才能被赋值运算符改变。默认为 false。
存取描述符同时具有以下可选键值:
get一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。
set一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给属性。默认为 undefined。
这里只说一下
get和
set:
看一下这个例子:
var o = Object.defineProperty({}, 'name', { get: function () { return this._name_; }, set: function (value) { this._name_ = value * 2; } }); o.name = 1; console.log(o.name); // 2
给属性
name定义了一个
get和
set,为什么使用
_name_而不是
name呢?因为
name是正在被定义的属性,如果在
get或者
set中使用
name无形之中就会发生递归,导致栈溢出。
_name_这个是自己自定义的,你完全可以设置为
$name、
__name__等等。
另外,使用对象的字面量形式也可以设置
get与
set:
var o = { get name(){ return this._name_; }, set name(value){ this._name_ = value * 2; } }; o.name = 1; console.log(o.name); // 2
实现双向数据绑定
要实现双向数据绑定,肯定要从get与
set下手,在
set的函数中重新渲染相关的数据,所以一开始应该是这样的:
var o = { get name(){ return this._name_; }, set name(value){ this._name_ = value; this.render('name'); }, render: function(pro){ document.write(this[pro]); } };
在浏览器控制台修改一下
o.name试试:
如何实现表单控件到数据的绑定呢?在
Vue中,表单元素通过
v-model绑定一个变量,类型这样:
<input type="text" v-model="name">
其实
v-model的元素是绑定了一个
input的自定义事件,我们不考虑那么多,就使用原生的
oninput事件来模拟下。
var o = { get name(){ return this._name_; }, set name(value){ this._name_ = value; console.log(this._name_); }, inputInit: function () { var self = this; var vModels = document.querySelectorAll('[v-model]'); for (let i = 0; i < vModels.length; i++) { vModels[i].addEventListener('input', function () { var property = this.getAttribute('v-model'); var value = this.value; self.name = value; }) } } }.inputInit();
至此一个简单的双向数据绑定就差不多了,我们模仿一下
Vue的api格式,再将代码封装一下:
html:
<input type="text" v-model="name"> <p v-text="name"></p>
javascript:
function Vue(options) { var data = options.data || {}; var dKeys = Object.keys(data); var _this = this; this.vData = {}; // 根据data中的变量数量动态的绑定 get 与 set for (let i = 0; i < dKeys.length; i++) { Object.defineProperty(this.vData, dKeys[i], { get: function () { return this['__' + dKeys[i] + '__']; }, set: function (value) { this['__' + dKeys[i] + '__'] = value; _this.render(dKeys[i]); // 重新渲染相关数据 } }) } for(let i in data) { // 初始化时设置一变vData,触发一遍 set this.vData[i] = data[i]; } this.inputInit(); // 给表单组件绑定事件监听 } Vue.prototype.render = function (pro) { var vModels = document.querySelectorAll('[v-model=' + pro + ']'); var vText = document.querySelectorAll('[v-text=' + pro + ']'); for (var i = 0; i < vModels.length; i++) { vModels[i].value = this.vData[pro]; } for (var j = 0; j < vText.length; j++) { vText[j].innerText = this.vData[pro]; } }; Vue.prototype.inputInit = function () { var self = this; var vModels = document.querySelectorAll('[v-model]'); for (let i = 0; i < vModels.length; i++) { vModels[i].addEventListener('input', function () { var property = this.getAttribute('v-model'); var value = this.value; self.vData[property] = value; }) } }; var vm = new Vue({ data: { name: 1 } })
相关文章推荐
- 五十行javascript代码实现简单的双向数据绑定
- 五十行javascript代码实现简单的双向数据绑定
- 五十行javascript代码实现简单的双向数据绑定
- 如何用javascript实现双向数据绑定 / Backbone.js简单入门范例
- JavaScript实现简单的双向数据绑定(Ember、Angular、Vue)
- Javascript实现简单的双向绑定
- JavaScript数据绑定实现一个简单的 MVVM 库
- JavaScript实现简单的双向绑定
- JS原生数据双向绑定实现代码
- 轻松实现javascript数据双向绑定
- javascript实现数据双向绑定的三种方式小结
- Javascript动态绑定事件的简单实现代码
- 用原生Javascript对象中的访问器属性实现双向数据绑定
- JavaScript数据绑定实现一个简单的 MVVM 库
- 实现非常简单的js双向数据绑定
- angularjs中$http、$location、$watch及双向数据绑定学习实现简单登陆验证
- 用jquery实现的简单数据双向绑定
- 轻松实现javascript数据双向绑定
- 用vue的双向绑定简单实现一个todo-list的示例代码
- 11、react之 实现数据的简单双向绑定