欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Vue笨蛋学原理:数据(data)是如何出现在页面上的?

程序员文章站 2024-02-02 11:17:16
...

本篇只是为了让大家看懂原理,写出来的代码并不是Vue源码

<div id="app">
	<h1> {{ name }} </h1>
	<p> {{ mes }} </p>
</div>
console.log(app) // 打印出来看一下

new Vue({
	el:'#app',
	data:{
		name:'刘亦菲',
		mes:'我爱你'
	}
})
console.log(app) // 在这里打印出来看一下

Vue笨蛋学原理:数据(data)是如何出现在页面上的?

  • 可以看出来,虽然两个都是app,但是在两个不同的div里出现的内容是不同的,而且后者是渲染在页面上的,鼠标放上去,页面有高亮反应
  • 那么,Vue是怎么把实例中的data里的name和mes渲染到页面上的呢

四个步骤

  • 找到标签
  • 拿到数据
  • 找到双大括号,进行替换
  • 渲染上去

找到标签

重新创建一个新的页面,把引入的Vue文件删除

let tempNode = document.querySelector('#app')

拿到数据

let data = {
	name:'刘亦菲',
	mes:'我爱你'
}

找到双大括号,将数据与模板结合

  • 先找到模板的所有子元素
  • 一般都是使用递归
  • 在真正的Vue源码中是 DOM–>字符串模板–>VNode–>真正的DOM
function compiler(template,data) {
  let chileNodes = template.childeNode  // 拿到所有子节点
}
  • 我们知道,DOM节点对应不同的数值,代表着不同的节点
  • 我们来遍历所有的子节点,当这个节点是元素节点的时候,我们就需要进行递归,因为他可能是个嵌套标签
  • 考虑它有没有子元素,是否需要将其子元素进行判断是否要插值
function compiler(template,data) {
  let chileNodes = template.childNodes
  for(let i = 0; i < childNodes.length; i++) {
    let type = childNodes[i].nodeType
    if(type === 3){ // 文本节点
    
    } else if(type === 1) { // 元素节点
      compiler(childNodes[i],data)
    }
  }
}
  • 当这个节点是文本节点的时候,就说明这里面可能有咱们需要的双大括号
// 使用正则来选择
let reg = /\{\{(.+?)\}\}/g;
if(type === 3){
  	let txt = childNodes[i].nodeValue // 该属性只有文本节点才有意义
	txt =	txt.replace(reg,function(_,g) {
		let key = g.trim(); // 剔除掉不必要的东西
		let value = data[key] // 把保存在data里的对应的数据赋值给选出来的值
		return value // 返回被data赋值后的新的值
	})
	childNodes[i].nodeValue = txt 
}
  • 可能对replace的用法不太熟悉,我们来看一下

Vue笨蛋学原理:数据(data)是如何出现在页面上的?

  • 所匹配到的东西是函数的第一个参数
  • 函数的返回值用来替换被匹配到的东西
  • 函数的第个参数以及以后的参数是正则表达式里的对应的第几组
    Vue笨蛋学原理:数据(data)是如何出现在页面上的?
    Vue笨蛋学原理:数据(data)是如何出现在页面上的?

把数据渲染到页面上

  • 此时是没有生成新的template, 所以这里看到的是直接在页面中就更新的数据,因为DOM是引用类型

  • 这样做模板就没有了

  • 我们不会去直接改变模板,所以clone一下

let generateNode = tempNode.cloneNode(true)
console.log(tempNode)
// compiler(tempNode,data)
compiler(generateNode,data)
console.log(tempNode)

app.parentNode.replaceChild(generateNode,app)
  • 看一下打印到页面的效果

Vue笨蛋学原理:数据(data)是如何出现在页面上的?

看一下完整的代码

<body>
	<div id="app">
		<h1> {{ name }} </h1>
		<p> {{ mes }} </p>
	</div>
	// js部分
	<script>
		let tempNode = document.querySelector('#app')
		
		let data = {
			name:'刘亦菲',
			mes:'我爱你'
		}
		
		let reg = /\{\{(.+?)\}\}/g;
		
		function compiler(template,data) {
			let childNodes = template.childNodes
			for(let i = 0; i < childNodes.length; i++) {
				let type = childNodes[i].nodeType
				if(type === 3) {
					let txt = childNodes[i].nodeValue
					txt =	txt.replace(reg,function(_,g) {
						let key = g.trim();
						let value = data[key]
						return value
					})
					childNodes[i].nodeValue = txt
				} else if(type === 1) {
					compiler(childNodes[i],data)
				}
			}
		}
		
		let generateNode = tempNode.cloneNode(true)
		console.log(tempNode)
		// compiler(tempNode,data)
		compiler(generateNode,data)
		console.log(tempNode)
		
		app.parentNode.replaceChild(generateNode,app)
	</script>
</body>
相关标签: Vue原理