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

九、组件实现原理

渲染组件

一个组件内部必须要使用 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 对象中


相关内容

热门资讯

景顺长城优质成长股票C净值上涨... 景顺长城优质成长股票型证券投资基金(简称:景顺长城优质成长股票C,代码021500)公布7月15日最...
中邮健康文娱灵活配置混合C净值... 中邮健康文娱灵活配置混合型证券投资基金(简称:中邮健康文娱灵活配置混合C,代码022252)公布7月...
富国中证港股通互联网ETF净值... 富国中证港股通互联网交易型开放式指数证券投资基金(简称:富国中证港股通互联网ETF,代码159792...
永赢科技驱动C净值上涨3.47... 永赢科技驱动混合型证券投资基金(简称:永赢科技驱动C,代码008920)公布7月15日最新净值,上涨...
信澳匠心严选一年持有期混合A净... 信澳匠心严选一年持有期混合型证券投资基金(简称:信澳匠心严选一年持有期混合A,代码016372)公布...
华商智能生活灵活配置混合C净值... 华商智能生活灵活配置混合型证券投资基金(简称:华商智能生活灵活配置混合C,代码015385)公布7月...
华商卓越成长一年持有混合A净值... 华商卓越成长一年持有期混合型证券投资基金(简称:华商卓越成长一年持有混合A,代码014350)公布7...
平安品质优选混合C净值上涨5.... 平安品质优选混合型证券投资基金(简称:平安品质优选混合C,代码014461)公布7月15日最新净值,...
以色列国防军宣布一系列高级军官... 每经AI快讯,7月16日,以色列国防军总参谋长扎米尔宣布了一系列有关以军总参谋部调整和高级军官任命的...
博时优质精选混合C净值上涨3.... 博时优质精选混合型证券投资基金(简称:博时优质精选混合C,代码015903)公布7月15日最新净值,...