在 Vue 中接入
适用于Vue 3.5及以上。先按快速开始准备包依赖,将其中的basic.ts放在组件旁边。@skynote/editor不依赖Vue,本页只是宿主集成示例,不是另一个已发布的Vue组件包。
完整组件
创建VueCanvasExample.vue,与basic.ts放在同一目录,然后在自己的页面中导入并使用该组件。
vue
<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, useTemplateRef } from 'vue';
import type { SkyNoteEditor } from '@skynote/editor';
const host = useTemplateRef<HTMLElement>('host');
const message = ref('正在加载画布…');
let editor: SkyNoteEditor<HTMLElement> | undefined;
let disposed = false;
onMounted(async () => {
try {
// 浏览器模块只在客户端加载;切换页面后到达的模块不再创建实例。
const { mountExample } = await import('./basic');
if (disposed) return;
editor = mountExample(host.value!);
message.value = '';
} catch {
if (!disposed) message.value = '画布加载失败,请刷新重试。';
}
});
onBeforeUnmount(() => {
disposed = true;
editor?.destroy();
});
</script>
<template>
<section class="vue-canvas-example" aria-label="Vue接入示例">
<div ref="host" data-canvas-host class="vue-canvas-host" />
<p v-if="message" role="status">{{ message }}</p>
</section>
</template>
<style scoped>
.vue-canvas-example {
position: relative;
height: 420px;
overflow: hidden;
background: var(--sn-canvas);
}
.vue-canvas-host {
position: absolute;
inset: 0;
outline: none;
}
p {
position: absolute;
inset: 0;
display: grid;
place-items: center;
color: var(--sn-text-muted);
}
</style>下面运行同一份组件源码:
正在加载画布…
生命周期与异步取消
onMounted之后才导入浏览器运行时并挂载。加载期间离开页面时,disposed阻止晚到模块创建编辑器;创建成功的实例在onBeforeUnmount销毁。SDK实例使用普通变量,不进入深度响应式代理。
如果需要供模板控制按钮状态,单独保存canUndo等简单状态;订阅历史、选区或文档事件时,同时保存并调用解绑函数。不要为了刷新工具栏而在每次拖动时导出整份文档。
SSR、尺寸和焦点
import type可以在服务端参与类型检查;浏览器运行时通过客户端生命周期动态导入。- 容器需要明确高度,示例为420px。实际布局可改为填满父容器,但父容器本身也必须有确定尺寸。
- 首次在隐藏标签页中挂载时,先等待容器可见,再创建或适配视口。
- 工具栏点击不要抢走画布焦点;可用键盘Tab访问按钮,同时给图标按钮提供无障碍名称。
示例使用文档站颜色变量。嵌入自己的应用时,可定义--sn-canvas和--sn-text-muted,或替换为自己的宿主Token。这些变量控制组件外壳,不自动改变画布主题。