Vuejs设计与实现7-组件实现原理
创始人
2024-05-04 00:06:36

九、组件实现原理

渲染组件

一个组件内部必须要使用 render 进行渲染,且返回虚拟 DOM

这是一个最简组件实例

const MyComponent = {// 组件名称,可选name: "MyComponent",// 组件的渲染函数,其返回值必须为虚拟 DOMrender() {// 返回虚拟 DOMreturn {type: "div",children: `我是文本内容`,};},
};

渲染器中的 mountComponent 函数完成组件的渲染

function mountComponent(vnode, container, anchor) {// 通过 vnode 获取组件的选项对象,即 vnode.typeconst componentOptions = vnode.type;// 获取组件的渲染函数 renderconst { render } = componentOptions;// 执行渲染函数,获取组件要渲染的内容,即 render 函数返回的虚拟const subTree = render();// 最后调用 patch 函数来挂载组件所描述的内容,即 subTreepatch(null, subTree, container, anchor);
}

组件更新

组件初始化步骤:

  1. 取得 data 函数后用 reactive 将其变成响应式的
  2. render 函数内将 this 指向 state,并将 state 作为第一个参数传入 render 函数

将渲染任务包装到一个副作用函数 effect 里面,即可实现响应式更新数据

若要使每次响应式数据修改后,effect 仅执行一次,则需要引入调度器概念
这是书中给出的最简调度器实例

即先把 effect 放入微任务队列,等执行栈清空再调出来执行

// 任务缓存队列,set可以自动去重
const queue = new Set();
// 一个标志,代表是否正在刷新任务队列
let isFlushing = false;
// 创建一个立即 resolve 的 Promise 实例
const p = Promise.resolve();
// 调度器的主要函数,用来将一个任务添加到缓冲队列中,并开始刷新队列
function queueJob(job) {// 将 job 添加到任务队列 queue 中queue.add(job);// 如果还没有开始刷新队列,则刷新之if (!isFlushing) {// 将该标志设置为 true 以避免重复刷新isFlushing = true;// 在微任务中刷新缓冲队列p.then(() => {try {// 执行任务队列中的任务queue.forEach((job) => job());} finally {// 重置状态isFlushing = false;queue.clear = 0;}});}
}

父子组件

这是一个简单的父子组件代码

// 子组件
// 父组件
const vnode = {type: MyComponent,props: {title: 'A Big Title'}
}

父组件更新导致子组件更新(被动更新)过程:

  1. 父组件自更新
  2. 渲染器检查 subTree 发现存在 vnode,则调用 patchComponent 实现子组件更新

setup 函数

setup 函数为配合组合式 API 所引入的

他有如下两种返回值形式

// 返回函数
const comp = {setup() {return () => {return {type: "div",children: "give up for vuejs",};};},
};// 返回对象
const comp = {setup() {const count = ref(0);return {count,};},render() {return {type: "div",children: `count is ${this.count}`,};},
};

setup 接收两个参数,分别是 props 以及 setupContext

setupContext 包含以下四个主要对象

  1. slots 插槽
  2. emit 自定义事件
  3. attrs 自定义属性
  4. expose 暴露

emit 实现

只需要实现一个 emit 函数并将其添加到 setupContext 对象中


相关内容

热门资讯

美股收盘:三大指数集体收涨 纳... 财联社12月20日讯(编辑 夏军雄)美东时间周五,在甲骨文和英伟达走强的带动下,人工智能(AI)概念...
贵阳有轨电车T2线主体硬件基本... 转自:贵州日报 本报讯(记者 冷赛楠)近日,“天眼问政”栏目收到网友留言:贵阳有轨电车T2线从比亚迪...
大山“用水三变” 转自:贵州日报 “以前靠山上小水源灌田,纯靠天吃饭。现在水龙头就在边上,要浇地直接打开就行。”69岁...
危房抢险施工公告 转自:贵州日报 贵阳市云岩区鸿雁巷17、19、20号及弯弓街6号住户:为消除贵阳市云岩区鸿雁巷17、...
“请3休8”带旺元旦假期云南旅...   本报讯 首席记者李思凡报道 “请3休8”带旺元旦游。12月19日,飞猪发布的数据显示,2026年...