Vue3框架设计思想

# 权衡的艺术

# 命令式和声明式

命令式:关注过程,详细的告诉计算机或者说浏览器,每一步需要做什么。

典型的命令式代码:

const div = document.getElementbyId("#box")
div.innnerText = "hello world"
div.addEventListener('click', () => alert('ok'))

声明式:关注结果,声明需要的结果,由框架执行具体内容。

<div @click="() => alert('ok')">hello world</div>

声明式的代码内部依旧是命令式的,只是这不需要使用者来关心。声明式是对命令式的封装,它的性能一定不会高于命令式。但是声明式的代码大大提高了可维护性,减少了使用者的心智负担。

# 虚拟DOM的性能

原生JavaScript的性能一定是最高的,但是为了保证这个高性能,需要花费巨大的心智负担。

虚拟DOM的心智负担小,性能不如原生但是也还可以接受,因为基于diff算法它只会更新必要的DOM

innerHTML的方式心智负担中等,但是性能最差。因为每次更新都会删除所有旧DOM然后创建新的,页面越大性能消耗就越大。

# 运行时和编译时

运行时:用户提供树形结构的对象,直接给框架使用。缺点是不能分析用户输入。

编译时:用户提供HTML模板,框架将模板编译为命令式代码,然后执行。

Vue是编译器 + 运行时框架,即用户可以直接提供树形结构,也可以提供模板,Vue都可以执行。无非就是需不需要先进行编译而已。Svelte是纯编译时框架,纯编译时框架必须将用户输入进行编译后才能运行,性能还有待商榷。

# 框架设计核心要素

# 良好的用户体验

使用Vue进行开发的时候,如果编写了错误的代码Vue一般都会在浏览器控制台输出一些警告和报错信息。并且这些报错信息并不是JS层面的信息,而是框架本身提供的,能帮助用户快速定位问题所在的信息。

这是提升用户体验直观重要的一环。

# 代码体积和Tree-Shaking

为了提升用户体验,需要编写大量的错误提示代码,但是Vue的打包产物并没有因为这些提示代码而体积巨大。主要是采用了类似

if(__DEV__) {
    warn('提示信息')
}

错误提示信息只会在开发阶段出现。生产环境下,__DEV__被置为false,内部代码永远不会执行,Tree-Shaking会擦除掉这段代码。

Tree-Shaking的依赖于ESM的静态结构。主要判断依据是代码是否有副作用,即是否会对外部产生影响

正是这种代码编写方式和Tree-Shaking,才让Vue拥有良好的提示功能的同时还能控制打包产物体积。

# 声明式UI框架

# 灵活的使用方式

Vue的使用方式是声明式的,用户无需关系具体的过程即可得到需要的结果。

使用Vue时既可以提供虚拟DOM也可以直接使用模板,使用虚拟DOM时,渲染器会直接执行。

//虚拟DOM就是利用JS对象对真实DOM的一种描述
const vnode = {
    tag: 'div',
    props: {
        onClick: () => console.log('Hello Vue')
    },
    children: 'click me'
}

//渲染器
function renderer(vnode, container) {
    //1.创建元素
    let el = document.createElement(vnode.tag)
    //2.遍历元素属性
    for(let key in vnode.props) {
        if(/^on/.test(key)) {
            let event = key.substring(2).toLowerCase()
            el.addEventListener(event, vnode.props[key])
        }
    }
    //3.遍历子元素
    if(typeof vnode.children === 'string') {
        el.appendChild(document.createTextNode(vnode.children))
    }else (Array.isArray(vnode.children)){
        vnode.children.forEach(child => renderer(child, el))
    }
    //4.挂载
    container.appendChild(el)
}

如果是使用模板的话,编译器会将模板编译成虚拟DOM之后再调用渲染器渲染真实DOM

# 组件的本质

组件本质就是一系列真实DOM元素的封装。

上次更新:: 2023/5/14 14:19:23