vue实现动态数据绑定

网友投稿 438 2023-05-20


vue实现动态数据绑定

实现的步骤:

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

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

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

obj: 目标对象

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

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

描述:

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

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

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

存取描述符:由一对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。

示例:

创建属性

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; },

enumerable : true,

configurable : true});

o.b = 38;

修改属性

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

var o = {}; // 创建一个新对象

Object.defineProperty(o, "a", { value : 37,

writable : false });

console.log(o.a); // 打印 37

o.a = 25; // 没有错误抛出(在严格模式下会抛出,即使之前已经有相同的值)

console.log(o.a); // 打印 37, 赋值不起作用。

一般的setter 和 getters

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);

解题

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

多层级对象

当传入的对象是

let app1 = new Observer({

user: {

name: "liangshaofeng",

age: "24"

},

address: {

city: "beijing"

}

});

递归解决问题!!

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, 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({

user: {

name: "liangshaofeng",

age: "24"

},

address: {

city: "beijing"

}

});

app1.data.user.name // 你访问了 name

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

增加事件系统

// 事件系统

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);

}

}

}

Observer.prototype.access = function(key, val) {

var self = this;

Object.defineProperty(this.data, key, {

enumerable: true,

configurable: true,

get: function () {

console.log('你访问了' + key);

return val

},

set: function (newVal) {

if (typeof newVal === 'object' && !!newVal) {

new Observer(newVal);

}

console.log('你设置了' + key);

console.log('新的' + key + ' = ' + newVal)

self.eventsBus.emit(key, val, 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",

age: "24"

},

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'http://, function(oldVal, newVal){

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

})

app1.$watch('age', function(oldVal, newVal){

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

})

app1.data.age = 20;


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring boot实现热部署的两种方式详解
下一篇:利用Spring boot如何创建简单的web交互应用
相关文章

 发表评论

暂时没有评论,来抢沙发吧~