The principle of Vue idiots: how does data appear on the page?

This article is just for everyone to understand the principle, the code written is not Vue source code

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

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

Insert picture description here

  • It can be seen that although both are apps, the content that appears in the two different divs is different, and the latter is rendered on the page. When the mouse is placed on it, the page has a highlight response
  • So, how does Vue render the name and mes in the data in the instance to the page?

Four steps

  • Find the label
  • Get data
  • Find double braces and replace them
  • Render up

Find the label

Recreate a new page and delete the imported Vue file

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

Get data

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

Find double braces, combine data with template

  • First find all child elements of the template
  • Recursion is generally used
  • In the real Vue source code is JUDGMENT–>String template–>VNode–>Real DOM
function compiler(template,data) {
    
    
  let chileNodes = template.childeNode  // 拿到所有子节点
}
  • We know that DOM nodes correspond to different values ​​and represent different nodes
  • Let's traverse all the child nodes. When this node is an element node, we need to recurse, because it may be a nested label
  • Consider whether it has sub-elements and whether it needs to be interpolated.
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)
    }
  }
}
  • When this node is a text node, it means that there may be double braces we need
// 使用正则来选择
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 
}
  • You may not be familiar with the usage of replace, let’s take a look

Insert picture description here

  • The matched thing is the first parameter of the function
  • The return value of the function is used to replace what is matched
  • The first parameter and subsequent parameters of the function are the corresponding groups in the regular expression
    Insert picture description here
    Insert picture description here

Render the data to the page

  • At this time, no new template is generated, so what you see here is the data that is updated directly on the page, because DOM is a reference type

  • The template will be gone

  • We will not change the template directly, so clone

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

app.parentNode.replaceChild(generateNode,app)
  • Look at the effect of printing to the page

Insert picture description here

Take a look at the complete code

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

Guess you like

Origin blog.csdn.net/m0_47883103/article/details/108635271