Vue官方文档梳理-DOM
原创
2018-3-14
16:18
编辑于
2022-6-17
15:25
el
!>如果 render 函数和 template 属性都不存在,挂载 DOM 元素的 HTML 会被提取出来用作模板,此时,必须使用 Runtime + Compiler 构建的 Vue 库。
Vue$3.prototype.$mount = function(el, hydrating) {
el = el && query(el);
// 不能挂载到 body 和 html 上
if (el === document.body || el === document.documentElement) {
// 发出警告
return this
}
var options = this.$options;
// 如果没有配置 render
if (!options.render) {
var template = options.template;
if (template) {
// ...
} else if (el) {
// 配置了el,没有配置 render,那么将 el 的 html 作为 template
template = getOuterHTML(el);
}
if (template) {
// 调用 compileToFunctions 将 template 编译成 render 函数
// ...
}
}
return mount.call(this, el, hydrating)
}
template
!>如果 Vue 选项中包含 render 函数,template 选项将被忽略。
上面的源码中,如果配置了 render,则不会对 template 配置项编译。因此优先级如下:
render > template > el
!>但是如果你在 vue 文件中即使用了 <template>
,又配置了 render,<template>
的内容会被编译成 render 函数,渲染的时候使用的是编译生成的 render,而不是配置的。
render
官网指出:组件树中的所有 VNodes 必须是唯一的。这意味着,下面的 render function 是无效的:
render: function (createElement) {
var myParagraphVNode = createElement('p', 'hi')
return createElement('div', [
// 错误-重复的 VNodes
myParagraphVNode, myParagraphVNode
])
}
即使在开发版本下运行,上面的代码也没有报错。不知道这里的影响点具体是什么。
##renderError
在 2.2.0 版本之前的版本只会调用全局配置的 config.errorHandler,比如 2.1.2 的源码如下。
try {
vnode = render.call(vm._renderProxy, vm.$createElement);
} catch (e) {
if (config.errorHandler) {
config.errorHandler.call(null, e, vm);
} else {
// ...
}
vnode = vm._vnode;
}
在 2.2.0 版本之后,不仅会调用全局配置的 errorHandler,而且还会调用配置的 renderError。
try {
vnode = render.call(vm._renderProxy, vm.$createElement);
} catch (e) {
handleError(e, vm, "render function"); // handleError 里面调用了 config.errorHandler
// return error render result,
// or previous vnode to prevent render error causing blank component
{
vnode = vm.$options.renderError ? vm.$options.renderError.call(vm._renderProxy, vm.$createElement, e) : vm._vnode;
}
}
转载请注明出处。本文地址:
https://www.qinshenxue.com/article/20170918102007.html
关注我的公众号