【vue设计与实现】挂载和更新 8-文本节点和注释节点

本文详细介绍了如何使用VNode结构来描述HTML中的注释节点和文本节点,通过创建唯一的type属性值进行区分。同时,展示了如何在patch函数中处理文本节点的更新,以及如何通过封装特定的DOM API来增强渲染器的跨平台能力。最后,对patch函数进行了优化,提高了代码效率。
摘要由CSDN通过智能技术生成

看下面HTML代码:

<div>
	<!-- 注释节点 -->
	我是文本节点
</div>

上面的代码中包含,元素节点<div>,注释节点和文本节点。那么如何用vnode描述注释节点和文本节点?
要注意的是注释节点与文本节点不同于普通标签节点,不具有标签名称,所以要人为创造一些唯一的标识,并将其作为type属性值,如下面代码:

// 文本节点
const Text = Symbol()
const newVnode = {
	// 描述文本节点
	type: Text,
	children: '我是文本内容'
}

// 注释节点的type标识
const Comment = Symbol()
const newVnode = [
	type: Comment,
	children:'我是注释内容'
}

这样就能用vnode来描述文本节点和注释节点了。由于文本节点和注释节点只关心文本内容,所以用vnode.children来存储它们对应的文本内容

有了vnode后,就可以用渲染器来渲染了,如下面代码所示:

function patch(n1,n2,container){

	if(n1 && n1.type !== n2.type){
		unmount(n1)
		n1 = null
	}

	const {type} = n2

	if(typeof type === 'string'){
		/.../
	}else if(type === Text){
		// 如果是文本节点
		if(!n1){
			// 如果没有旧节点,则进行挂载
			// 使用createTextNode创建文本节点
			const el = n2.el = document.createTextNode(n2.children)
			// 将文本节点插入到容器中
			insert(el,container)
		}else{
			// 如果旧vnode存在,只需要使用新文本节点的文本内容更新旧文本节点即可
			const el = n2.el = n1.el
			if(n2.children !== n1.children){
				el.nodeValue = n2.children
			}
		}
	}
}

注意这里使用的是文本节点的nodeValue属性来完成文本内容的更新

此外上面代码使用到的createTextNode和el.nodeValue都是浏览器平台特有的API,为了保证渲染器核心的跨平台能力,需要将这两个操作DOM的API封装到渲染器的选项中,如下面代码:

const renderer = createRenderer({
	/.../
	createText(text){
		return document.createTextNode(text)
	}
	setText(el,text){
		el.nodeValue = text
	}
	/.../
})

接着再优化patch代码如下:

function patch(n1,n2,container){
	if(n1 && n1.type !== n2.type){
		unmount(n1)
		n1 = null
	}

	const {type} = n2

	if(typeof type === 'string'){
		/.../
	}else if(type === Text){
		// 如果是文本节点
		if(!n1){
			const el = n2.el = createText(n2.children)
			insert(el,container)
		}else{
			const el = n2.el = n1.el
			if(n2.children !== n1.children){
				setText(el,n2.children)
			}
		}
	}
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值