vue源码分析1

本文深入探讨Vue源码中的关键技术点,包括伪数组转换、节点类型获取、数据属性定义、对象键值遍历及Fragment应用,揭示Vue高效运行的秘密。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.源码中主要的方法

1.如何把伪数组转换成真数组的方法

在vue的源码中使用的是es5的方法 [].prototype.slice.bind(obj) 来实现的

例如:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>源码主要技术点</title>
</head>
<body>
	<div id="test">
		<ul>
			<li>1</li>
			<li>2</li>
			<li>3</li>
		</ul>
	</div>
</body>
<script>
	// 如何把伪数组转换真数组
	const ls = document.getElementsByTagName('li');
    此时的ls是假数组虽然可以根据索引能获取值
	console.log(ls instanceof Array); // false

    // 方法1 该方法为es6的方法 也可以转换es6中的set语句
	const arrls = Array.from(ls);
	console.log(arrls instanceof Array); // true
    // 方法2 es5实现继承数组原型的方法 用call或者apply都可以实现
	const arrls1 = Array.prototype.slice.apply(ls)
	console.log(arrls1 instanceof Array);  // true
 
    const arrls1 = Array.prototype.slice.call(ls)
	console.log(arrls1 instanceof Array); // true
</script>
</html>

2.node.nodeType :获取节点类型

已代码为例:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>源码主要技术点</title>
</head>
<body>
	<div id="test1">
		<ul>
			<li>1</li>
			<li>2</li>
			<li>3</li>
		</ul>
	</div>
</body>
<script>
	const elementNode = document.getElementById('test1'); // 元素节点 1

	const attrNode = elementNode.getAttributeNode('id');  // 属性节点  

	const textNode = elementNode.firstChild // 文本节点

	console.log(elementNode.nodeType, attrNode.nodeType, textNode.nodeType)
    // 1 , 2 , 3

	console.log(elementNode, attrNode, textNode)
    // 元素
    // id="text"
    // #text

</script>
</html>

3.Object.defineProperty(obj, prop, descriptor)

obj: 定义属性的对象
prop: 定义或修改属性的名称
descriptor: 将被定义或修改的属性描述符

数据描述符

value: 默认值
configurable:  是否可以重新定义
enumerable: 是否可以枚举
writable: 是否可以写或者更改

访问描述符

get: 动态计算读取当前属性的值
set: 监视属性值的变化,更新其他相关属性

    const obj = {
		firstName: 1,
		lastName: 2
	}

	Object.defineProperty(obj, 'fullName', {
		get: function() {
			return this.firstName+ '~' +this.lastName
		},
		set:function(value) {
			const names = value.split('~')
			this.firstName = names[0]
			this.lastName = names[1]
		}
	})

	console.log(obj.fullName) // 1~2
	obj.firstName = 3
	obj.lastName = 4
	console.log(obj.fullName) // 3~4
	obj.fullName = 5~7
    console.log(obj.firstName) // 5
    console.log(obj.lastName) // 7 

vue的计算属性就是运用了该语法

该语法IE8不支持,所以vue不支持IE8

4.Object.keys(obj) 

obj: 要遍历的对象

代码如下

const obj = {
	firstName: 1,
	lastName: 2
}

const arr = Object.keys(obj)
console.log(arr) //  ["firstName", "lastName"]

vue中的v-for就是用该语法来遍历的

5.obj.hasOwnProperty(prop)

判断prop是否为自身的属性

const obj = {
	firstName: 1,
	lastName: 2
}

console.log(obj.hasOwnProperty('fullName')) // true
console.log(obj.hasOwnProperty('toString')) // false
toString()是对象原型的方法, 不是自身属性

  6.Document.Fragment

高效一次批量更新多个节点,提高性能

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>源码主要技术点</title>
</head>
<body>
	<div id="test1">
		<ul id="test_fragment">
			<li>1</li>
			<li>2</li>
			<li>3</li>
		</ul>
	</div>
</body>

<script>
	const ul = document.getElementById('test_fragment');
	// 1.创建fragment
	const fragment = document.createDocumentFragment();
	// 2.取出ul中的所有子节点保存到fragment
	let child;
	while(child = ul.firstChild) {
		fragment.appendChild(child);
	}
	console.log(fragment)
	// 3.更新fragment使用li的文本
	Array.prototype.slice.call(fragment.childNodes).forEach(function(item) {
		if (item.nodeType === 1) {
			item.textContent = 'fragment'
		}
	})
	// 4.将fragment放入ul中
	ul.appendChild(fragment)
</script>
</html>

此时显示的应该是fragment而不是1, 2, 3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值