w

https://docs.microsoft.com/en-us/scripting/javascript/reference/object-defineproperty-function-javascript

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties

双向绑定

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>Document</title>
</head>
<body>
<div id="app">
<form>
<input type="text" v-model="count"/>
<button type="button" v-click="increment">increment</button>
<button type="button" v-click="alert('Hello world')">alert</button>
</form>
<p v-bind="count"></p>
</div>
<script>
function Lue(options) {
this._init(options);
console.log(this)
} Lue.prototype._init = function (options) {
this.$options = options; //传入的实例配置
this.$el = document.querySelector(options.el); //实例绑定的根节点
this.$data = options.data; //实例的数据域
this.$methods = options.methods; //实例的函数域 //与DOM绑定的数据对象集合
//每个成员属性有一个名为_directives的数组,用于在数据更新时触发更新DOM的各directive
this._binding = {};
this._parseData(this.$data); this._compile(this.$el); //编译DOM节点
}; //遍历数据域,添加getter/setter
Lue.prototype._parseData = function (obj) {
var value;
for (var key in obj) {
//排除原型链上的属性,仅仅遍历对象本身拥有的属性
if (obj.hasOwnProperty(key)) {
this._binding[key] = { //初始化与DOM绑定的数据对象
_directives: []
};
value = obj[key];
this.convert(key, value);
}
}
}; /**对象属性重定义
* @param key 数据对象名称,本例为"count"
* @param val 数据对象的值
*/
Lue.prototype.convert = function (key, val) {
var binding = this._binding[key];
Object.defineProperty(this.$data, key, {
enumerable: true,
configurable: true,
get: function () {
console.log(`获取$
{
val
}`)
;
return val;
},
set: function (newVal) {
console.log(`更新$
{
newVal
}`)
;
if (val != newVal) {
val = newVal;
binding._directives.forEach(function (item) {
item.update();
})
}
}
})
}; function Directive(name, el, vm, exp, attr) {
this.name = name; //指令名称,例如文本节点,该值设为"text"
this.el = el; //指令对应的DOM元素
this.vm = vm; //指令所属lue实例
this.exp = exp; //指令对应的值,本例如"count"
this.attr = attr; //绑定的属性值,本例仅实验innerHTML this.update(); //首次绑定时更新
} Directive.prototype.update = function () {
//更新DOM节点的相应属性值
this.el[this.attr] = this.vm.$data[this.exp];
}; //解析DOM的指令
Lue.prototype._compile = function (root) {
var _this = this;
//获取指定作用域下的所有子节点
var nodes = root.children;
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
//若该元素有子节点,则先递归编译其子节点
if (node.children.length) {
this._compile(node);
} if (node.hasAttribute("v-click")) {
node.onclick = (function () {
var attrVal = nodes[i].getAttribute("v-click");
var args = /\(.*\)/.exec(attrVal);
if (args) { //如果函数带参数,将参数字符串转换为参数数组
args = args[0];
attrVal = attrVal.replace(args, "");
args = args.replace(/[\(|\)|\'|\"]/g, '').split(",");
}
else args = [];
return function () {
_this.$methods[attrVal].apply(_this.$data, args);
}
})()
} if (node.hasAttribute(("v-model"))
&& node.tagName == "INPUT" || node.tagName == "TEXTAREA") {
//如果是input或textarea标签
node.addEventListener("input", (function (key) {
var attrVal = node.getAttribute("v-model");
//将value值的更新指令添加至_directives数
_this._binding[attrVal]._directives.push(new Directive(
"input",
node,
_this,
attrVal,
"value"
)) return function () {
_this.$data[attrVal] = nodes[key].value;
}
})(i));
} if (node.hasAttribute("v-bind")) {
var attrVal = node.getAttribute("v-bind");
//将innerHTML的更新指令添加至_directives数
_this._binding[attrVal]._directives.push(new Directive(
"text",
node,
_this,
attrVal,
"innerHTML"
))
}
}
} window.onload = function () {
var app = new Lue({
el: "#app",
data: {
count: 0,
},
methods: {
increment: function () {
this.count++;
},
alert: function (msg) {
alert(msg)
}
}
})
}
</script>
</body>
</html>

Object.defineProperties()的更多相关文章

  1. 分享一个Object.defineProperties 定义一个在原对象可读可写的方法

    function A(){ this.name = 'hellow word'; } Object.defineProperties( A.prototype,{ doSomething2 : { v ...

  2. Object.defineProperties()和Object.defineProperty()方法

    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象. 语法:Object.defineProperty(obj, pro ...

  3. JS Object.defineProperties()方法

    JS Object.defineProperties()方法 描述: Object.defineProperties()方法为目标对象同时配置多个属性. 语法: Object.defineProper ...

  4. Object.defineProperties()与Proxy对象代理

    Object.defineProperties() 了不起啊..vue.js通过它实现双向绑定的 Object.defineProperties(obj,props) 方法直接在一个对象上定义新的属性 ...

  5. Object.defineProperty和Object.defineProperties

    添加属性到对象,或修改现有属性的特性   用法:     Object.defineProperty(object, propertyName, descriptor); 参数:     object ...

  6. Object.defineProperties——MEAN开发后台的Model层

    Object.defineProperties是什么?有什么用? 这个问题比较听起来可能比较难以理解,确实我也是在项目中遇到的才会去想.以前看到<高级程序设计>的时候,有这么一种东西,定义 ...

  7. 定义多个属性 Object.defineProperties()

    var book = {} Object.defineProperties(book,{ _year:{ value:2004 }, editable:{ value:1 }, year:{ get: ...

  8. js中Object.defineProperties 定义一个在原对象可读可写的方法

    function A(){ this.name = 'hellow word'; } Object.defineProperties( A.prototype,{ doSomething2 : { v ...

  9. ES5 Object.defineProperties / Object.defineProperty 的使用

    临时笔记,稍后整理 var obj = { v: , render: function () { console.log(") } }; // Object.defineProperties ...

随机推荐

  1. Eclipse 一直Building Workspace 的解决办法

    Eclipse 一直不停 building workspace完美解决总结 一.产生这个问题的原因多种 1.自动升级 2.未正确关闭  3.maven下载lib挂起 等.. 二.解决总结 (1).解决 ...

  2. lucene 多索引目录搜索实现方法

    http://akululu.iteye.com/blog/314130 多索引目录就是要在多个索引目录的中进行比较搜索,类似概念在SQL中就是select * from TableA union s ...

  3. net.reflector8.5.0.179过了试用期,要求输入序列号怎么办 注册机 破解

    去网上搜索“reflector keygen注册机下载”,随便找一个版本下载(如果你之前下载的软件自带有“Keygen.exe”注册机的话,直接用自带的注册机就可以了)1.断开网络2.下载安装原程序, ...

  4. QT学习二:工具栏

    QT  的工具栏提供 Dock 功能.文字/图标显示排列的功能. void MainWindow::createToolBar(void) { QToolBar *toolBar = new QToo ...

  5. Atitit. Toast alert loading js控件   atiToast v2新特性

    Atitit. Toast alert loading js控件   atiToast v2新特性 1. 连续多个txt追加的原理 var txt = document.createElement(& ...

  6. C#类库帮助类

    前言 此篇专门记录一些常见DB帮助类及其他帮助类,以便使用时不用重复造轮子. DBHelper帮助类 ①首当其冲的就是Sql Server帮助类,创建名为DbHelperSQL 的类 ,全部代码如下: ...

  7. c++ about SLL(Static-Link Library) and DLL(Dynamic-Link Library)

    First thing first, Wiki: http://en.wikipedia.org/wiki/Dynamic-link_library http://en.wikipedia.org/w ...

  8. objc_runtime使用方法的几个简单例子(转)

    1. 给NSObject类动态添加属性h定义部分 [cpp] @interface UIWebView (LoadProgress)  @property (nonatomic, assign) NS ...

  9. UIWebView加上safari风格前进后退按钮(转)

    今天在写程序内打开网页的功能,写工具条的时候发现系统图标里面竟然没有后退按钮,,由于我这个是静态库工程,不可能自己弄张图上去,不然使用本库的时候还得附上图片,经过一下午的搜索,终于找到个比较靠谱的,这 ...

  10. FMDB使用(转载)

    来自会员pengtao的分享:(原文:https://github.com/ccgus/fmdb) 由于FMDB是建立在SQLite的之上的,所以你至少也该把这篇文章从头到尾读一遍.与此同时,把SQL ...