• Vue组件的本质和手写通过render渲染函数渲染组件


    1.组件的本质

    组件就是一组 DOM 元素的封装,本质就是一个对象

    (mounted函数中打印一下组件即可看到打印的是一个对象)

    如何利用javascript对象来描述一个组件?

    1. const MyComponent = {
    2. render() {
    3. return {
    4. tag: 'div',
    5. props: {
    6. onClick: () => alert('hello')
    7. },
    8. children: 'click Me'
    9. }
    10. }
    11. }
    12. const vnode = {
    13. tag: MyComponent
    14. }

    如何修改渲染器的内容?渲染函数时写的只是针对虚拟节点不是针对组件(即传入一个对象)

    2.手写组件渲染函数

    虚拟节点为字符串时:手写Vue渲染器render函数-CSDN博客

    重点:和普通字符串tag不同的时,判断vnode.tag是一个组件时,通过组件的render函数获取组件对象的虚拟节点

    1. <div id="app">div>
    2. <script>
    3. // 手写render函数组件对象渲染到页面
    4. /*重点:
    5. 使用vnode.tag作为创建的dom标签el(判断vnode.tag是一个组件时,通过组件的render函数获取组件对象的虚拟节点)
    6. */
    7. /**
    8. * @vnode 虚拟 DOM 对象
    9. * @container 一个真实 DOM 元素,作为挂载点,渲染器会把虚拟 DOM 渲染到该挂载点
    10. */
    11. function render(vnode, container) {
    12. // 通过判断vode的tag为对象则为组件渲染
    13. if(typeof vnode.tag === "string"){
    14. mount(vnode, container);
    15. }else if(typeof vnode.tag === "object"){
    16. let comVnode = vnode.tag.render();
    17. mount(comVnode, container);
    18. }else{
    19. // ...其他操作
    20. }
    21. }
    22. // tag为字符串时的渲染函数
    23. function mount(vnode, container) {
    24. // 使用vnode.tag作为创建的dom标签el
    25. let el = document.createElement(vnode.tag);
    26. // 遍历vnode.props,将属性 事件添加到DOM上(事件即给元素添加监听事件;)
    27. for (let key in vnode.props) {
    28. // 判断如果为事件则将其设置到el中
    29. if ((/^(on)/).test(key)) {
    30. el.addEventListener(key.substr(2).toLowerCase(), vnode.props[key]);
    31. }
    32. }
    33. // 处理 children(字符串和数组)
    34. if (typeof vnode.children === "string") {
    35. el.appendChild(document.createTextNode(vnode.children));
    36. } else if (Array.isArray(vnode.children)) { //是数组进行遍历并递归调用render方法
    37. vnode.children.forEach(child => {
    38. render(child, el);
    39. });
    40. }
    41. // 将元素添加到挂载节点container下
    42. container.appendChild(el);
    43. }
    44. // render函数测试
    45. const container = document.getElementById('app')
    46. // 仿组件结构(可以通过render方法获取组件的虚拟节点对象数据)
    47. const MyComponent = {
    48. render() {
    49. return {
    50. tag: 'div',
    51. props: {},
    52. children: [
    53. {
    54. tag: 'p',
    55. props: {},
    56. children: '我是一个p标签'
    57. },
    58. {
    59. tag: 'button',
    60. props: {
    61. onClick: () => alert('hi vue')
    62. },
    63. children: '按钮'
    64. }
    65. ]
    66. }
    67. }
    68. }
    69. const vnode = {
    70. tag: MyComponent
    71. }
    72. render(vnode, container)

  • 相关阅读:
    Python自动化测试selenium指定截图文件名方法
    Go语言入门心法(六): HTTP面向客户端|服务端编程
    全栈性能测试教程之性能测试相关知识(二) Jmeter的应用
    华为OD机试 - 模拟目录管理功能(Java & JS & Python & C)
    潘多拉 IOT 开发板学习(HAL 库)—— 实验2 蜂鸣器实验(学习笔记)
    Python每日一练 04
    Flink之状态TTL机制
    数据机房中智能小母线与列头柜方案的对比与分析
    阿里云人脸识别对比
    2023年中国饲料酸化剂产量、需求量及市场规模分析[图]
  • 原文地址:https://blog.csdn.net/qq_34569497/article/details/134056977