vue3设计思路

64 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 12 天,点击查看活动详情

Vue是如何设计UI的

HTML类似的声明式描述UI减少学习成本,增加开发效率

vue中templete模板

  1. 与html标签一致
  2. 属性描述,层级都与html一致 <div id ='iddd'><span></span></div>
  3. 动态属性用 v-bind或者:表示 如:<div :id="dynamicId"></div>
  4. 使用@或者v-on来描述事件

js描述UI

js描述UI更灵活。 eg

const title = {
    tag:`h${lever}`
}

用templete描述则需要穷举。

常见的h函数就是用js来描述UI的。

<templete>
    <div id={'foo'} class = {'bar'}></div>
</templete>

templete会被编译成为render函数。里面内容编译成对象即虚拟dom

等价于

export default {
    render() {
        /**
        * @param  type:string 标签的类型
        * @param  props:object  所有属性的对象
        * @param  children:array children的数组
          @return object 返回值就是虚拟dom
        **/
        return h( 'div', { id: 'foo', class: 'bar' }, [ /* children */ ])
   }
}

等价于

最终上线两种方式都会编译成为虚拟dom 即

render({
    tag:'div',
    props: { id: 'foo', class: 'bar' },
    children: []
}, container)

细心的同学会发现h函数实际上就是虚拟dom的简写。

那么我们发现虚拟dom前面有render函数。那么render又是什么呢

渲染器与编译器

render函数即渲染器。上面我们看到无论是h函数还是templete模板最终都会编译成文虚拟dom。 而render函数 则是将虚拟dom 渲染成为(document.crenteElement('div'))这种浏览器识别的内容

如何实现render

const vNode = {
    tag:'div',
    props: { id: 'foo', class: 'bar' },
    children: []
}

render(vNode, document.body)

实现render 大致

  1. 根据tag 来crenteElement, 遍历props 添加到element上面。
  2. 判断children 如果sttring 则createTextNode 否则遍历children递归循环步骤1,2

组件如何渲染呢

组件实际上也是

tag:'MyComponent'

function组件

const MyComponent = function(){
  return {
      tag: 'div',
      props:{
         onClick: () => alert('hellow')
      },
      children: 'clickMe'
  }
}

本质是一个方法返回虚拟dom, 渲染时候只需要调用方法获取虚拟dom循环上面1,2步骤 即

    vNode.tag()

类组件

const  MyComponent = {
    render() {
        return {
          tag: 'div',
          props:{
             onClick: () => alert('hellow')
          },
          children: 'clickMe'
        }
    }
  
}

类组件本质是返回一个对象 即

{render: render function }

所以渲染只需要调用对象中的render方法

    vNode.tag.render()

最终实现render 实现render 大致 判断vNode.tag

  • 如果为字符串

    1. 根据tag 来crenteElement, 遍历props 添加到element上面。
    2. 判断children 如果sttring 则createTextNode 否则遍历children递归循环步骤1,2
  • 如果为方法

    调用方法

       const functionNode = vNode.tag()
       render(functionNode, container)
       
    
  • 如果为object

    const functionNode = vNode.tag.render()
    render(functionNode, container)
    

总结: 组件本质是一组DOM元素的封装,templete模板会编译成为render渲染函数,h实际是简化获取虚拟dom的。

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 12 天,点击查看活动详情