Vue3 的设计思路

0. vue是如何将模板渲染到页面的

假设我们有如下模板

<div id="foo" :class="cls"></div>

vue的编译器会把这段代码编译成渲染函数:

render() {
    // return h('div', {id: "foo", class: cls})
    return {
        tag: 'div',
        props: {
            id: 'foo',
            class: cls
        },
        patchFlags: 1 // 假设数字1代表class是动态的
    }
}

然后渲染器再把渲染函数返回的虚拟DOM渲染为真实的DOM。

function renderer(vnode, container) {
    const el = document.createElement(vnode.tag);
    for (const key in vnode.props) {
        if (/^on/.test(key)) {
            // 以on开头说明它是事件
            el.addEventListener(
                key.substring(2).toLowerCase(),
                vnode.props[key]
            )
        }
    }
​
    if (typeof vnode.children === 'string') {
        el.appendChild(document.createTextNode(vnode.children))
    }
    else if (Array.is(vnode.children)) {
        vnode.children.forEach(child => renderer(child, el));
    }
​
    container.appendChild(el);
}

编辑器与渲染器是vuejs的核心组成部分,下面开始逐渐深入讲解。

1. 声明式的描述UI

vue是一个声明式的UI框架,即用户再使用vue开发页面时是声明式的描述UI的。

模板声明式描述UI

<div class="cls"><span>hello world</span></div>

js对象声明式描述UI

const title = {
    tag: 'h1',
    props: {
        class: 'title',
        onclick: handler
    },
    children: [
        {
            tag: 'span'
        }
    ]
}

js对象即虚拟DOM。虚拟DOM描述UI更加灵活,但模板更加直观。

小知识点: h函数是一个辅助创建虚拟dom的工具函数,render函数中调用h函数生成了一个虚拟dom对象。

2. 初识渲染器

渲染器的作用: 就是把虚拟DOM渲染成真实DOM。

h('div', 'htllo')   ===> 渲染器 ===>  真实DOM

举例:

// 虚拟DOM
const vnode = {
    tag: 'div', // 描述标签名称
    props: { // 描述标签的属性事件等内容
        class: 'cls',
        onClick: () => alert('hello') 
    },
    children: [  // 描述子节点
        'click me'
    ]
}

该虚拟节点通过上文的renderer函数,渲染为真实的DOM。

renderer(vnode, document.body); // body 为真实DOM元素,作为虚拟DOM挂载点。

renderer实现思路

  • 创建元素

  • 为元素添加属性和事件

  • 处理children

  • 挂载到真实DOM节点

渲染器的工作原理很简单,就是利用一些DOM操作API来完成渲染工作。

组件的本质

vue组件就是一组DOM元素的封装。可以定义一个函数来代表组件,函数的返回值就代表组件要渲染的内容。

const MyComponent = () => {
    return {
        tag: 'div',
        props: {
            onClick: () => alert('hello')
        },
        children: [
            'click me'
        ]
    }
}

组件的返回值也是一个虚拟dom,他代表了组件要渲染的内容。

用虚拟DOM描述组件,利用对象中的tag值

cpnst vnode = {
    tag: MyComponent
}

渲染器为了能渲染组件,需要做出修改:

function renderer(vnode, container) {
    if (typeof vnode.tag === 'string') {
        // 虚拟dom是标签元素
        mountElement(vnode, container);
    }
    else if (typeof vnode.tag === 'function') {
        // 说明vnode描述的是组件
        mountComponent(vnode, container)
    }
}

function mountComponent(vnode, container) {
    const subtree = vnode.tag()
    renderer(subtree, container)
}
​

也可以用对象描述组件,渲染函数只需修改 typeof vnode.tag === ‘object’。

模板的工作原理

文章开头已经介绍了模板渲染到页面的原理,核心是编译器和渲染器配合完成。

针对一个vue组件(.vue文件就是一个组件)

<template>
    <div @click="handler">
        click me
    </div>
</template>
​
<script>
export default {
    data() {}
    methods: {
        handler: () => {}
    }
}    
</script>

编译器会把模板内容编译成渲染函数并添加到script标签块的组件对象上

// 最中浏览器里运行的代码如下
<script>
export default {
    data() {}
    methods: {
        handler: () => {}
    },
    render() {
        return h('div', {onClick: handler}, 'click me')
    }
}    
</script>

由此也能看出,vuejs是一个编译时+运行时的框架。

备注:结合《VUE.js设计与实现》深入学习vuejs,记录学习过程。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
vue3 动态表单组件的设计思路可以分为以下几个步骤: 1. 定义数据结构:首先确定表单需要收集的数据类型和字段,比如文本输入、下拉选择、单选、多选等等。可以使用对象或数组的方式来表示表单的数据结构,并为每个字段指定相应的属性(例如字段名称、类型、默认值、选项等)。 2. 构建表单组件:创建一个包含所有表单字段的组件,并根据数据结构动态生成表单元素。可以使用`v-for`指令循环渲染表单字段,并根据字段类型选择合适的表单元素组件进行渲染。 3. 实现数据绑定:为每个表单元素添加相应的`v-model`指令,将用户输入的值与表单组件的数据进行双向绑定。这样可以实时更新表单组件中的数据,并且用户输入的值也会反映在相应的表单字段上。 4. 处理提交事件:在表单组件中添加一个提交按钮或者监听表单的提交事件,在用户点击提交按钮或者提交表单时,通过方法或事件处理函数收集表单数据并进行相应的处理,比如发送给后端进行保存或进一步处理。 5. 提供扩展性:考虑到动态表单可能会有不同的需求,可以通过添加插槽或者额外的属性来提供扩展性。比如可以为表单组件添加一个插槽,用于自定义表单的布局或者添加额外的表单字段。 通过以上的设计思路,可以实现一个灵活、可复用的动态表单组件,使表单的设计和渲染更加简洁和高效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值