精读《Vuejs设计与实现》(10)之组件的本质

153 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情

3.3 组件的本质

上一章里,我们说到了渲染器,所谓渲染器就是把虚拟dom转换为真实dom。但是什么是组件呢?

可能很多人把组件认为就是虚拟dom,或者是虚拟dom的集合,其实并不准确。作者把组件定义为一组DOM元素的集合

这时候,我们不能再用一个对象去表示组件,我们需要用一个函数,我认为用函数是因为需要响应式,这点后面再说

const component = ()=>({
    tag:'button', 
    children:'click Me!!!', 
    onClick(){ alert('hello world') 
})
const vdom = {
 tag:component
}

所以之前写的那个渲染器自然用不了,我们需要再封装一层,我们把之前那个改个名字叫renderDom

const render = (vnode,container)=>{
  if(typeof vode.tag === 'string'){
      renderDom(vnode,container)
  } else if(typeof vode.tag === 'function'){
      renderComponent(vnode,container)
  } else {
   console.log(vnode.tag)
  }
}

那么renderComponent怎么实现呢,其实很简单

const renderComponent = (vnode,container)=>{
    const _vnode = vnode.tag()
    renderDom(_vnode,container)
}

同理,组件能不能是对象呢,自然也是可以的,我们只需要在render函数中继续增加判断条件,然后调用不同的方法去渲染即可。

这一章我感觉书里讲的比较水,其实在我看来,在vue里,组件就是render函数,因为vue为了响应式会把模板转换成render函数,每次数据有更新的时候就自动运行。

虚拟dom只是render函数的一个参数而已,对于这个参数,我们也可以采用别的方式,比如一个纯字符串可不可以,json可不可以,jsx可不可以。

组件的本质就是ui的封装,我们需要在开发中把一块ui区域,或按照样式,或按照功能去封装起来,已达到代码分割或复用的目的。形式并不重要,其实有时候字符串反而更好,比如在vue里,你也可以这样定义

Vue.component('a',{
template:`<div></div>`
})

这才是组件的本质