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 对象中


相关内容

热门资讯

卓翼科技跌2.05%,成交额4... 4月15日,卓翼科技(维权)盘中下跌2.05%,截至13:48,报7.17元/股,成交4868.70...
孙姓股民向ST章鼓发起索赔 刘...   受损股民可至Hehson股民维权平台登记该公司维权:http://wq.finance.sina...
欧盟对华柠檬酸发起第三次反倾销... 2026年4月14日,欧盟委员会发布公告,应欧盟企业N.V. Citrique Belge S.A....
中国消博会:全球消费新趋势展示... 巴西247新闻网4月13日文章,原题:中国重视发展体验经济,在海南举办大型消费品博览会 随着第六届中...
我国网络视听用户规模10.99... 转自:新华社  4月15日在成都开幕的第13届中国网络视听大会上,《中国网络视听发展研究报告(202...