虽然在大多数网络应用中,我们可能都会渲染到DOM。但是现在通过 Vue3 的 Custom Renderer 特性,我们可以自己制作渲染器把 Vue 组件渲染到其它平台。
@vue/runtime-core
Vue3 本身是高度模块化的,它提供了程序包 @vue/runtime-core 来帮助我们构建自己的 Vue 的渲染器。@vue/runtime-dom 则向我们展示了如何实现一个 DOM 渲染器。
在下面的代码中,简单列举了实现一个自定义渲染器所需的函数
import { createRenderer } from '@vue/runtime-core'
const { render, createApp } = createRenderer({
patchProp,
insert,
remove,
createElement,
// ...
})
// `render` is the low-level API
// `createApp` returns an app instance with configurable context shared
// by the entire app tree.
export { render, createApp }
export * from '@vue/runtime-core'
createRenderer
createRenderer 就是用来创建自定义渲染器的函数,在它的返回值中:
- render 函数只是一个低级别的 API,我们一般不会手动使用它。
- createApp 函数则是我们用来创建整个应用的工具,运行它会返回一个提供应用上下文的应用实例,应用实例挂载的整个组件树共享同一个上下文。你可以在 createApp 之后链式调用其它方法,这些方法可以在 应用 API 中找到。
createRenderer 函数的接受一个对象作为参数,它可以定义很多方法构建整个渲染器,在 runtime-dom/src/nodeOps.ts 中有官方的实现可以作为参考。下面会介绍其中常用的几个方法:
patchProp
function patchProp (el, key, prevValue, nextValue)
patchProp 在组件属性被修改时调用,主要让你针对不同属性,给 el 进行不同的操作。更多细节可以参考 runtime-dom/src/patchProp.ts 的实现。
insert
function insert (child, parent, anchor)
用于给参数 parent 插入子组件 child。
remove
function remove (child)
移除组件 child,值得注意的是参数里没有提供它的父组件。
createElement
function createElement (tag, isSVG, is, props)
创建组件映射的元素,在 runtime-dom 中就是返回的 HTMLElement 实例。
PixiJS
在去年看到 Vue3 的新特性 Custom Renderer 的时候,我就为它编写了一个程序,结合 PixiJS 实现一个运行在浏览器 Canvas 中的扫雷游戏。
PixiJS 是一个 HTML5 的引擎,使用 2D WebGL 渲染器。我们可以用 JavaScript 或者其他 HTML5 技术来显示媒体,创建动画或管理交互式图像,从而制作一个游戏或应用。
它拥有语义化的,简洁的 API 接口并且加入了一些非常有用的特性。比如支持纹理贴图集和为 sprite(交互式图像)提供了一个简单的动画系统。它也提供了一个完备的场景图,你可以在 sprite 图层里面创建另一个 sprite,当然也可以让 sprite 响应你的鼠标或触摸事件。
Pixi 的 API 事实上比起久经沙场又老旧的 Macromedia/Adobe Flash API 要精致,其他的同类渲染框架(比如 CreateJS、Starling、Sparrow 和 Apple’s SpriteKit)也在使用类似的API。Pixi API 的优势在于它是通用的,而它不只是一个游戏引擎。这是一个优势,甚至用它可以写成你自己的游戏引擎。
扫雷游戏代码
由于 Windows 10 系统没有自带的扫雷游戏,所以我选用了 Minesweeper Arbiter 作为参考,它是国际扫雷网承认的扫雷软件之一。我的代码放在我的 Github 仓库 davepkxxx/vue3-pixi-minesweeper 中,可以克隆下来运行它看看效果。
git clone https://github.com/davepkxxx/vue3-pixi-minesweeper
npm install
npm run dev