有哪些营销型网站推荐,湖南省住房和城乡建设厅网,wordpress怎么加动态背景图图片,厦门网站建设价格xm37在之前我们就提到#xff0c;首次渲染之后#xff0c;后续如果再调用 render 函数时#xff0c;传递的 vnode 为 null 则表示是卸载。
当时我们是直接通过执行 container.innerHTML ‘’ 来实现的#xff0c;但是这样做会有以下几个问题#xff0c;如下#xff1a;
容…在之前我们就提到首次渲染之后后续如果再调用 render 函数时传递的 vnode 为 null 则表示是卸载。
当时我们是直接通过执行 container.innerHTML ‘’ 来实现的但是这样做会有以下几个问题如下
容器内可能是由某个或者多个组件渲染的当卸载操作发生时应该正确的调用这些组件的 beforUnmount、unmounted 等生命周期函数。即使内容不是由组件渲染的有的元素存在自定义指令我们应该再在卸载操作发生时正确的执行这些对应指令的钩子函数。使用 innerHTML 清空容器的还有一个缺陷是它并不会移除绑定在 DOM 元素上的事件处理函数
正确的卸载方式应该是根据 vnode 对象获取对应与其相关联的真实 DOM 元素然后使用原生 DOM 操作方式将该元素移除。为此我们需要再 vnode 与真实 DOM 元素之间建立联系修改 mountElement 函数如下
function mountElement(vnode, container) {// 让 vnode.el 引用真实的 dom 元素const el (vnode.el hostCreateElement(vnode.type))// ... 省略其他代码
}这样建立联系之后当卸载的时候只需要根据 vnode.el 属性即可获取真实的 dom 元素然后在将其从父元素中移除如下
function render(vnode, container) {if (vnode) {patch(container._vnode, vnode, container)} else {// 卸载操作if (container._vnode) {// 获取 vnode 关联的真实 domconst { el } container._vnode// 获取 el 的父元素const parent el.parentNode// 调用父元素的 removeChild 方法if (parent) {parent.removeChild(el)}}container._vnode vnode}
}根据之前的设计方案这个卸载子元素的操作会经常用到我们将其提取出来封装到 unmount 函数中如下
function unmount(vnode) {const { el } vnodeconst parent el.parentNodeif (parent) {parent.removeChild(el)}
}