前言:
笔者本文谈论的vue仅仅狭小的指vue.js文件,而非整套Vue框架(如:router、template范畴)。
简单原理:
通过重写变量的setter
方法实现当属性值改变的时候获取该属性绑定的DOM元素从而改变界面控件的值。 具体实现是通过重写JS的根对象Object
的 Object.defineProperty(obj,key,func)
方法实现。
核心代码
Object.defineProperty(obj,key,{
configurable:false,//可配置
set:function rectiveSetter (newValue){
console.log(key);
var v_binds = el.querySelectorAll('[v-bind='+key+']');
for(var i = 0;i < v_binds.length; i++){
v_binds[i].innerHTML = newValue;
}
var v_models_o = el.querySelectorAll('[v-model='+key+']');
for(var i = 0;i < v_models_o.length; i++){
v_models_o[i].value = newValue;
}
this.value = newValue;
},
get:function rectiveGetter(){
return this.value;
}
其中:
-
defineProperty
就是用来定义一个 对象的某个属性(属性的一些描述) -
defineProperty
内其他属性拓展:- value:"和set/get同时存在,打开就报错了",
- writable:false,//可写
- configurable:false,//可配置
- enumerable:false,//可迭代: for遍历不出东西来
- set方法是属性改变的时候会触发的方法,在这儿加上DOM操作即可
- 注意:在使用
for
循环对属性进行添加监听的时候,let的时候可以不使用闭包。(temporal dead zone)ES6的let让js真正拥有了块级作用域
自定义vue_custom.js加HTML使用
1.vue_custom.JS代码
var vue_custom = (function(){
var __DEFUALTS__ = {
el: "body",
data:{},
methods: { },
}
function Vues(options){
this.extend_c(__DEFUALTS__,options);
this.el = document.querySelector(this.el);
var data_c = this.data;
var v_models = this.el.querySelectorAll('[v-model]');
for(var i = 0;i < v_models.length ;i++ ){
v_models[i].onkeyup = function(){
data_c[this.getAttribute('v-model')] = this.value;
}
}
this.observer_c();//让模型对象具备观察者模式的功能(加钩子)
}
Vues.prototype = {
//将传入参数复制到本实例对象Vue中
extend_c : function(){
console.log('======'+JSON.stringify(arguments) );
//arguments 代表的是 __DEFUALTS__ 详细了解:请百度 HTML arguments
for (var i = 0;i < arguments.length;i++){
for(var prop in arguments[i]){
this[prop] = arguments[i][prop];
}
}
},
//将实例对象Vue中属性的Setter方法重写:属性值改变的时候刷新DOM
observer_c : function(){
var el = this.el;;
for(var key in this.data){//let的时候可以不使用闭包。(temporal dead zone)ES6的let让js真正拥有了块级作用域
(function(obj,key){
Object.defineProperty(obj,key,{
configurable:false,//可配置
set:function rectiveSetter (newValue){
console.log(key);
var v_binds = el.querySelectorAll('[v-bind='+key+']');
for(var i = 0;i < v_binds.length; i++){
v_binds[i].innerHTML = newValue;
}
var v_models_o = el.querySelectorAll('[v-model='+key+']');
for(var i = 0;i < v_models_o.length; i++){
v_models_o[i].value = newValue;
}
this.value = newValue;
},
get:function rectiveGetter(){
return this.value;
},
});
})(this.data,key);
}
}
}
return Vues;
})()
2.HTML调用
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>vue从入门到豁然开朗</title>
<head>
</head>
<body>
<div id="custom_app">
<input v-model = "message" ><br>
<input v-model = "text" ><br>
<a href="#" v-bind="message"></a><br>
<span v-bind = "message"></span><br>
<span v-bind = "text"></span><br>
</div>
<script src="JS/vue_custom.js"></script>
<script>
var model_custom = {"message":"真的难以","text":"好"};
var vue_custom = new vue_custom({
el:"#custom_app",
data:model_custom
});
model_custom.message = "呵呵呵";
model_custom.text = "哈哈";
console.log(model);
console.log(model_custom);
</script>
</body>
</html>
网友评论