微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

vue实现动态数据绑定

实现的步骤:

1.监听对象属性的读取与变化

Object.defineproperty() 方法会直接在对象上定义一个新的的属性,或者已经存在的属性并且返回这个属性

语法是 Object.defineProperty(obj,prop,descript)

obj: 目标对象

prop: 需要定义或修改属性的名字

descript: 将被定义或修改属性的描述符

描述:

这个方法精确添加修改对象的属性,我们添加属性是可以枚举的属性(Object.keys()/ for...in)

对象里面存在是属性描述存在的形式是:

数据描述符:拥有可写入或不可以写入的属性(相当于口令密码)

存取描述符:由一对getter-setter 函数功能来描述的属性方法

注意:**描述符**必须是两种形式之一,不能同时是两者。

数据描述符和存取描述符均具有以下可选键值:

1.configurable:当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,也能够被删除认为 false

2.enumerable:当且仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。认为 false

数据描述符:

1.value:该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。认为 undefined。

2.writable:当且仅当该属性的 writable 为 true 时,该属性才能被赋值运算符改变。认为 false。

存取描述符同时具有以下可选键值:

1.get:一个属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。认为 undefined。

2.set:一个属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性认为 undefined。

示例:

创建属性

rush:js;"> var o = {}; Object.defineProperty(o,"a",{value : 37,writable : true,enumerable : true,configurable : true});

console.log(o.a);
Object.defineProperty(o,"b",{get : function(){ /console.log( bValue)/ return value },set : function(newValue){ bValue = newValue; },configurable : true});
o.b = 38;

修改属性

属性特性(property attribute) writable 设置为false时,表示 non-writable,属性不能被修改

rush:js;"> var o = {}; // 创建一个新对象

Object.defineProperty(o,{ value : 37,writable : false });

console.log(o.a); // 打印 37
o.a = 25; // 没有错误抛出(在严格模式下会抛出,即使之前已经有相同的值)
console.log(o.a); // 打印 37, 赋值不起作用。

一般的setter 和 getters

rush:js;"> var pattern = { get: function () { return 'I alway return this string,whatever you have assigned'; },set: function () { this.myname = 'this is my name string'; } }; function TestDefinesetAndGet() { Object.defineProperty(this,'myproperty',pattern); } var instance = new TestDefinesetAndGet(); instance.myproperty = 'test';

// 'I alway return this string,whatever you have assigned'
console.log(instance.myproperty);
// 'this is my name string'
console.log(instance.myname);

解题

rush:js;"> function Observer(property) { this.data = {}; this.recursion(data); }

Observer.prototype.recursion = function(obj) {
var val = null;
for (key in obj) {
if(obj.hasOwnProperty(key)) {
val = obj[val];
if(typeof val === 'object' && !!val) {
new Observer(val);
}
this.access(key,val);
}
}
}

Observer.prototype.access = function(key,val) {
Object.defineProperty(this.data,key,{
enumerable: true,configurable: true,get: function () {
console.log('你访问了' + key);
return val
},set: function (newVal) {
console.log('你设置了' + key);
console.log('新的' + key + ' = ' + newVal)
if (newVal === val) return;
val = newVal
}
})
}

let app1 = new Observer({
name: 'youngwind',age: 25
});
let app2 = new Observer({
university: 'bupt',major: 'computer'
});

// 要实现的结果如下:
app1.data.name // 你访问了 name
app1.data.age = 100; // 你设置了 age,新的值为100
app2.data.university // 你访问了 university
app2.data.major = 'science' // 你设置了 major,新的值为 science

多层级对象

当传入的对象是

rush:js;"> let app1 = new Observer({ user: { name: "liangshaofeng",age: "24" },address: { city: "beijing" } });

递归解决问题!!

rush:js;"> function Observer(data) { this.data = data; this.recursion(this.data); }

Observer.prototype.recursion = function(obj) {
var val = null;
for (key in obj) {
if(obj.hasOwnProperty(key)) {
val = obj[key];
if(typeof val === 'object' && !!val) {
new Observer(val);
}
this.access(key,set: function (newVal) {
console.log('你设置了' + key);
console.log('新的' + key + ' = ' + newVal)
if (newVal === val) return;
val = newVal
}
})
}

let app1 = new Observer({
user: {
name: "liangshaofeng",address: {
city: "beijing"
}
});

app1.data.user.name // 你访问了 name
app1.data.user.age = 100; // 你设置了 age,新的值为100

增加事件系统

rush:js;"> // 事件系统 function Event() { this.events = {}; }

Event.prototype.emit = function(attr,val,newVal) {
this.events[attr] && this.events[attr].forEach(function(item){
item(val,newVal)
})
}

Event.prototype.on = function(attr,callback){
if(this.events[attr]){
this.events[attr].push(callback);
}else{
this.events[attr] = [callback];
}
}

function Observer(data) {
this.data = data;
this.recursion(this.data);
this.eventsBus = new Event();
}

Observer.prototype.recursion = function(obj) {
var val = null;
for (key in obj) {
if(obj.hasOwnProperty(key)) {
val = obj[key];
if(typeof val === 'object' && !!val) {
new Observer(val);
}
this.access(key,val) {
var self = this;
Object.defineProperty(this.data,set: function (newVal) {
if (typeof newVal === 'object' && !!newVal) {
new Observer(newVal);
}
console.log('你设置了' + key);
console.log('新的' + key + ' = ' + newVal)
self.eventsBus.emit(key,newVal);
if (newVal === val) return;
val = newVal
}
})
}
Observer.prototype.$watch = function(attr,callback){
this.eventsBus.on(attr,callback);
}

let app1 = new Observer({
user: {
name: "liangshaofeng",address: {
city: "beijing"
}
});

app1.data.user.name // 你访问了 name
app1.data.user.age = 100; // 你设置了 age,新的值为100

app1.data.user.name = {
lastName: 'liang',firstName: 'shaofeng'
};
app1.data.user.name.lastName;
// 这里还需要输出 '你访问了 lastName '
app1.data.user.name.firstName = 'lalala';
// 这里还需要输出 '你设置了firstName,新的值为 lalala'
var app1 = new Observer({
name: 'liujianhuan',age: 25,company: 'Qihoo 360',address: 'Chaoyang,Beijing'
})

app1.$watch('age',function(oldVal,newVal){
console.log(我的年龄变了,原来是: ${oldVal}岁,现在是:${newVal}岁了)
})

app1.$watch('age',newVal){
console.log(我的年龄真的变了诶,竟然年轻了${oldVal - newVal}岁)
})

app1.data.age = 20;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐