vue框架原理学习的第一天

vue框架原理的学习

这是Szziyy 对vue框架原理学习的第一天

前期需要了解学习的方法

//获取对象的key
Object.keys(data).forEach(key=>{
	console.log('获取到对象里面的key值':key:data[key])
})

Object.defineProperty(对象,属性名称,{
	get:()=> 
	set:(new,old)=>{  },
	// 设置改属性对应值 
    // value:"",
    // 是否可被修改属性 true为可修改 false为不可修改
     // configurable:true,
     // 是否可以枚举  true 是否能获取到这个属性
   // enumerable:true,
      // 是否可以写入
    // writable:true
}

简单的HTML使用vue的方式

我们通过引用vue.js 创建vue实例对象 通过设置绑定对象
实现MVVM

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
	// 通过vue实例对象绑定
    <div id="app">
    	// 插值显示data对应的msg值
        {{msg}}
    </div>
    // 引入vue文件
    <script src="./vue.js"></script>
    <script >
    	// 设置参数对象
        var option = {
        	// 绑定对象
            el:"#app",
            // 数据
            data:{
                msg:"helloVue"
            }
        };
        // 创建vue实例对象 
        var app = new Vue(option);
    </script>
</body>
</html>

接下来我们将根据这个例子做出一个自己简单的框架

  1. 首先创建出属于我们的自己vue框架的js文件
    sueVue.js
    在这里插入图片描述

2.根据前面简单的引入 创建出对应的实力对象
我们这个文件中需要定义一个class Vue 传入需要传入对应的参数属性 则如下

class Vue{
	// 构造器 需要传入跟vue参数一样的属性
	constructor(options){
	//  绑定实例对象的this
	var vm = this;
	// 绑定传过来的options
	this.$options = options;
	// 绑定传过来的options的data
	this.$data = options.data;
	// 因为 vue 创建的实例对象 属性也在实例对象上,我们需要创建一个方法将options上的data属性绑定到当前的实例对象上去
	// 通过获取Object.keys获取对应的属性值
	Oject.keys(this.$data).forEach(key=>{
		// 创建一个绑定对象的方法
		vm._proxy(key)
	})
	},
	_proxy(key){
		// 通过Object.defineProperty() 方法设置在实例对象上
		Object.defineProperty(vm,key,{
			// 是否枚举 显示出来
			 enumerable:true,
			 // 获取对象属性返回的方法
			 get:()=> this.$data[key],
			 // 设置属性的方法
			 set:(value)=> {this.$data[key] = value}
		})
	}
}

那么我们第一部分就做好创建实例对象,加上把参数上的属性绑定到们的实例对象上。那么我们接下来需要再构建一个能把页面对象进行获取,创建虚拟dom,获取对应的节点,重新生出渲染出来

// 创建一个能生成虚拟dom的类
class Compile{
	// 需要告诉要绑定页面的那个dom  生成的实例对象
	constructor(el,vm){
		// 绑定传过来的实例对象
		this.$vm = vm;
		// 获取页面对象dom
		this.$el = document.querySelector(el);
		// 判断对象是否存在
		if(this.$el){
			// 1.将元素节点取出
			this.$fragment = fragmentObj(this.$el);
			// 2.创建对应的虚拟dom对象
			// 3.将生成的虚拟dom重新渲染到页面上
		}
	},
	fragmentObj(el){
		// 创建虚拟dom
		let fragment = document.createDocumentFragment();
		// 创建一个子元素
		let child ;
		// 判断是否对象有第一个子节点
		while(child = el.first.childNode){
			// 降子节点存储到虚拟dom上
			fragment.appendChild(child) 
		}
		// 返回出去
		return fragment;
	}
}

到了这一步 我们就可以回去到页面对象并存储在我们创建的虚拟dom上了,接下来进行完善

// 创建一个能生成虚拟dom的类
class Compile{
	// 需要告诉要绑定页面的那个dom  生成的实例对象
	constructor(el,vm){
		// 绑定传过来的实例对象
		this.$vm = vm;
		// 获取页面对象dom
		this.$el = document.querySelector(el);
		// 判断对象是否存在
		if(this.$el){
			// 1.将元素节点取出
			this.$fragment = fragmentObj(this.$el);
			// 2.创建对应的虚拟dom对象
			this.createDom(this.$fragment)
			// 3.将生成的虚拟dom重新渲染到页面上
		}
	},
	fragmentObj(el){
		// 创建虚拟节点对象
		let fragment = document.createDocumentFragment();
		// 创建一个子元素
		let child ;
		// 判断是否对象有第一个子节点
		while(child = el.first.childNode){
			// 降子节点存储到虚拟节点对象上
			fragment.appendChild(child) 
		}
		// 返回出去
		return fragment;
	},
	createDom(fragment){
		// 获取虚拟节点对象的子节点
		let childNodes = fragment.childNodes;
		// 变成数组循环遍历
		Array.prototype.slice.forEach(childNode=>{
			// 1.提取文本节点
			let text = childNode.TextContent;
			// 2.设置正则
			let reg = /\{\{(.*)\}\}/
			// 3.根据节点进行编译
			if(childNode.contentType == 3 && reg.test(text)){
				// 根据类型的函数 RegExp.$1 为正则判断获取的()里面的值
				this.compileText(childNode,RegExp.$1)
			}
		})
	},
	compileText(node,temp){
		// 创建一个dom更新函数
		this.updateDomVal(node,temp,"textContent",this.vm[temp]);
	},
	updateDomVal(node,temp,domType,domValue){
		// 通过传过来的值 对属性进行更新
		node[type] = value;
	}
	
}

到此 我们将页面的{{}} 里面的对我们data进行替换
我们就剩最后的重新渲染到页面上了

class Vue{
	// 构造器 需要传入跟vue参数一样的属性
	constructor(options){
	//  绑定实例对象的this
	var vm = this;
	// 绑定传过来的options
	this.$options = options;
	// 绑定传过来的options的data
	this.$data = options.data;
	// 因为 vue 创建的实例对象 属性也在实例对象上,我们需要创建一个方法将options上的data属性绑定到当前的实例对象上去
	// 通过获取Object.keys获取对应的属性值
	Oject.keys(this.$data).forEach(key=>{
		// 创建一个绑定对象的方法
		vm._proxy(key)
	})

	},
	_proxy(key){
		// 通过Object.defineProperty() 方法设置在实例对象上
		Object.defineProperty(vm,key,{
			// 是否枚举 显示出来
			 enumerable:true,
			 // 获取对象属性返回的方法
			 get:()=> this.$data[key],
			 // 设置属性的方法
			 set:(value)=> {this.$data[key] = value}
		})
	}
}

// 创建一个能生成虚拟dom的类
class Compile{
	// 需要告诉要绑定页面的那个dom  生成的实例对象
	constructor(el,vm){
		// 绑定传过来的实例对象
		this.$vm = vm;
		// 获取页面对象dom
		this.$el = document.querySelector(el);
		// 判断对象是否存在
		if(this.$el){
			// 1.将元素节点取出
			this.$fragment = fragmentObj(this.$el);
			// 2.创建对应的虚拟dom对象
			this.createDom(this.$fragment);
			// 3.将生成的虚拟dom重新渲染到页面上
			this.$el.appendChild(this.$fragment);
		}
	},
	fragmentObj(el){
		// 创建虚拟节点对象
		let fragment = document.createDocumentFragment();
		// 创建一个子元素
		let child ;
		// 判断是否对象有第一个子节点
		while(child = el.first.childNode){
			// 降子节点存储到虚拟节点对象上
			fragment.appendChild(child) 
		}
		// 返回出去
		return fragment;
	},
	createDom(fragment){
		// 获取虚拟节点对象的子节点
		let childNodes = fragment.childNodes;
		// 变成数组循环遍历
		Array.prototype.slice.forEach(childNode=>{
			// 1.提取文本节点
			let text = childNode.TextContent;
			// 2.设置正则
			let reg = /\{\{(.*)\}\}/
			// 3.根据节点进行编译
			if(childNode.contentType == 3 && reg.test(text)){
				// 根据类型的函数 RegExp.$1 为正则判断获取的()里面的值
				this.compileText(childNode,RegExp.$1)
			}
		})
	},
	compileText(node,temp){
		// 创建一个dom更新函数
		this.updateDomVal(node,temp,"textContent",this.vm[temp]);
	},
	updateDomVal(node,temp,domType,domValue){
		// 通过传过来的值 对属性进行更新
		node[type] = value;
	}
	
}

至此 我们最简单的Vue框架创建完毕
第一天的学习到此结束

学习到 了 Object.defineProperty 和 Object.keys 的用法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值