一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
原理
自定义渲染器(Renderer),可以用来自己重新定义开发渲染逻辑,它能把Vdom渲染成Web的真实Dom,将获取到的vnode对象转换到特定平台的特定操作比如:在web平台下能够将vdom渲染为真实Dom对象。我们通过下面创建canvas画布为大家一 一解析。
解析
我们建一个canvas画布,通过它来进行一些列的操作
- 我们创建一个渲染器,需要给它提供节点和属性的操作
const { createRenderer } = Vue
给它提供节点的操作,这里创建一个nodeOps对象,方便存储
const nodeOps = {}
const renderer = createRenderer(nodeOps);
创建canvas画图工具
- 创建保存画布和上下文,上下文:
ctx
,画布:canvas
let ctx;
let canvas;
- 拓展mount挂载,创建一个画布元素,创建一个创建画布的方法并传入App参数,这个参数最终将通过
renderer.createApp
创建并渲染。
function createCanvasApp(App) {
const app = renderer.createApp(App);
const mount = app.mount
app.mount = function(selector) {
canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.querySelector(selector).appendChild(canvas);
ctx = canvas.getContext('2d');
mount(canvas);
}
return app
}
我们通过设置挂载方法mount给它添加一个属性方法,在内为其创建一个画布并设置画布的大小宽高上下文等,并将它添加到html内,最后返回出去
3.创建app实例,挂载到实例上
createCanvasApp({}).mount('#app')
此时,已经可以看到canvas,但是会报一个错误,因为我们上面的组件是空的,vue想要创建一个comment元素导致的,最后我们把这个这段写好的代码封装成一个组件bar-chart
- 添加模板
在挂载实例中将
bar-chart
引入,并给它一个参数chartData这是它的最终成型主要参数,包括颜色color
,大小count
,还有名称Title
<script type="text/x-template" id="chart">
<bar-chart :data="[{ title: "⻘铜", count: 200, color: "brown" }]"></bar-chart>
</script>
<div id="app"></div>
节点操作实现
- 保存canvas实例和上下文
let ctx, canvas
- nodeOps详解
- 在内定义creteElement方法(创建Dom方法),创建元素时由于没有需要创建的Dom元素,所以只需要返回当前元素的数据对象{tag}
const nodeOps = {
createElement: (tag, isSVG, is) => {
return {tag}
},
}
重写insert逻辑
因为在我们的canvasApp中不存在实际dom插入操作,这里我们只需要将元素只见的父子关系保存一下即可。
const nodeOps = {
insert: (child, parent, anchor) => {
child.parent = parent
if (!parent.childs) {
parent.childs = [child]
} else {
parent.childs.push(child)
}
if (parent.nodeType === 1) {
draw(child)
}
}
}
只有canvas有nodeType,所以这里(parent.nodeType === 1
)就开始绘制知道内容到canvas
最后
这里是通过一个简单的实例来进行实现和分析,请掘友们多提意见,每一次进步都是成长!