渲染器的核心功能就是挂载与更新
首先,有一个虚拟dom的代码如下:
1 | const vnode = { |
检查vnode.props字段可以使用el[key]=vnode.props[key]或者el.setAttribute(key,vnode.props[key]),先来了解下HTML Attributes和DOM Properties的不同
HTML Attributes和DOM Properties
1 | <div id="foo"></div> |
这个DOM对象有很多属性,HTML Attributes在DOM对象上有与之同名的DOM Properties,例如id=”my-input”对应el.id,但DOM Properties并不与HTML Attributes的名字总是一样,例如
1 | <div class="foo"> |
class=’foo’对应的DOM Properties是el.className,不是所有的HTML Adttributes都有和它对应的DOM Properties,例如aria-*类的HTML Attributes就没有和它对应的DOM Properties
1 | <input value='foo'/> |
当用户修改了文本框的值,那么el.value的值时当前文本的值,而el.getAttribute(‘value’)仍然是之前的值
总之:HTML Attributes的作用是设置与之对应的DOM Properties的初始值
正确设置元素的属性
例子:
1 | <button :disabled='false'> |
这个HTML模板会被编译成vnode:
1 | const button = { |
这里的props.disabled的值时空字符串,如果在渲染器中调用setAttribute函数设置属性,相当于:
1 | el.setAttribute('disabled',false) |
用户本意是不禁用,但是用setAttribute按钮仍然被禁用了,这是因为使用setAttribute函数设置的值总是会被字符串化,等价于
1 | el.setAttribute('disabled','false') |
el.disabled的值时布尔值,我们不关心值是什么,只要disabled属性存在,按钮就被禁用,不使用setAttribute,用el.disabled=false
但是如果是下面的模板:
1 | <button disabled> |
对应的vnode:
1 | const button = { |
用DOM Properties设置元素属性时,el.disabled=’’,类型转换会设置为el.disabled=false,用户本意是禁用按钮,则只能优先设置setAttribute,如果是空字符串则手动矫正
1 | function mountElement(vnode,container) { |