Vue API
@frame-flex/vue 包提供 Vue 3 组件和 Composables。
RichTextEditor 组件
主编辑器组件,使用 TipTap 和 ProseMirror 构建。
Props
typescript
interface Props {
// v-model 绑定的内容
modelValue?: JSONContent;
// 是否可编辑
editable?: boolean;
}modelValue
- 类型:
JSONContent - 默认值:
undefined - 描述: 编辑器内容(TipTap JSON 格式)
示例:
vue
<script setup>
const content = ref({
type: 'doc',
content: [
{
type: 'paragraph',
content: [{ type: 'text', text: 'Hello' }]
}
]
});
</script>
<template>
<RichTextEditor v-model="content" />
</template>editable
- 类型:
boolean - 默认值:
true - 描述: 是否允许编辑
示例:
vue
<template>
<RichTextEditor v-model="content" :editable="false" />
</template>Events
update:modelValue
当内容更新时触发。
typescript
(content: JSONContent) => void示例:
vue
<template>
<RichTextEditor
v-model="content"
@update:modelValue="handleUpdate"
/>
</template>
<script setup>
function handleUpdate(newContent) {
console.log('内容更新:', newContent);
}
</script>update
内容更新事件(同 update:modelValue)。
typescript
(content: JSONContent) => voidSlots
RichTextEditor 组件当前不提供插槽,但你可以通过 useEditor 完全自定义编辑器。
useEditor
编辑器管理 Composable。
类型定义
typescript
interface UseEditorReturn {
// 编辑器实例(shallowRef)
editor: ShallowRef<Editor | null>;
// 创建编辑器
createEditor: (options?: EditorOptions) => Editor;
// 销毁编辑器
destroyEditor: () => void;
}
function useEditor(): UseEditorReturn;使用方法
vue
<script setup lang="ts">
import { onMounted, onBeforeUnmount } from 'vue';
import { useEditor } from '@frame-flex/vue';
const { editor, createEditor, destroyEditor } = useEditor();
onMounted(() => {
createEditor({
content: '<p>Hello World</p>',
editable: true,
onUpdate: (content) => {
console.log('更新:', content);
}
});
});
onBeforeUnmount(() => {
destroyEditor();
});
// 使用编辑器实例
function getHTML() {
return editor.value?.getHTML();
}
</script>EditorOptions
typescript
interface EditorOptions {
// 初始内容
content?: string | JSONContent;
// 是否可编辑
editable?: boolean;
// 自动聚焦
autofocus?: boolean | 'start' | 'end' | 'all';
// 内容更新回调
onUpdate?: (content: JSONContent) => void;
// 选区更新回调
onSelectionUpdate?: () => void;
// 焦点回调
onFocus?: () => void;
// 失焦回调
onBlur?: () => void;
}扩展
VueMathExtension
Vue 数学公式扩展(带 NodeView)。
typescript
import { VueMathInline, VueMathBlock } from '@frame-flex/vue';特性:
- 行内公式和块级公式
- KaTeX 渲染
- Vue 组件编辑界面
使用:
vue
<script setup>
import { useEditor } from '@frame-flex/vue';
import { VueMathInline, VueMathBlock } from '@frame-flex/vue';
const { createEditor } = useEditor();
onMounted(() => {
createEditor({
extensions: [VueMathInline, VueMathBlock]
});
});
</script>VueCodeBlockExtension
Vue 代码块扩展(带 NodeView)。
typescript
import { VueCodeBlockExtension } from '@frame-flex/vue';特性:
- 多语言支持
- 语法高亮(lowlight)
- Vue 组件编辑界面
- 语言选择器
NodeView 组件
MathComponent
数学公式 NodeView 组件。
Props:
- 继承自
nodeViewProps
功能:
- KaTeX 渲染
- 双击编辑
- LaTeX 输入
CodeBlockComponent
代码块 NodeView 组件。
Props:
- 继承自
nodeViewProps
功能:
- 语法高亮
- 语言选择
- 复制代码按钮
MediaComponents
媒体文件 NodeView 组件集。
- ImageComponent: 图片组件
- VideoComponent: 视频组件
- AudioComponent: 音频组件
类型定义
JSONContent
typescript
interface JSONContent {
type: string;
attrs?: Record<string, any>;
content?: JSONContent[];
marks?: Array<{
type: string;
attrs?: Record<string, any>;
}>;
text?: string;
}Editor
typescript
import type { Editor } from '@tiptap/core';
// TipTap Editor 实例
const editor: Editor | null = useEditor().editor.value;样式
导入样式
typescript
import '@frame-flex/vue/styles';或在 CSS 中:
css
@import '@frame-flex/vue/styles';自定义样式
使用 CSS 变量覆盖默认样式:
css
:root {
--editor-bg: #ffffff;
--editor-text: #1a202c;
--editor-border: #e2e8f0;
}完整示例
vue
<template>
<div class="app">
<RichTextEditor
v-model="content"
:editable="editable"
@update="handleUpdate"
/>
<div class="actions">
<button @click="toggleEditable">
{{ editable ? '锁定' : '解锁' }}
</button>
<button @click="getContent">获取内容</button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { RichTextEditor, useEditor } from '@frame-flex/vue';
import type { JSONContent } from '@frame-flex/core';
import '@frame-flex/vue/styles';
const content = ref<JSONContent>({
type: 'doc',
content: []
});
const editable = ref(true);
const { editor } = useEditor();
function handleUpdate(newContent: JSONContent) {
console.log('内容更新:', newContent);
}
function toggleEditable() {
editable.value = !editable.value;
}
function getContent() {
if (editor.value) {
console.log('HTML:', editor.value.getHTML());
console.log('JSON:', editor.value.getJSON());
console.log('Text:', editor.value.getText());
}
}
</script>
<style scoped>
.app {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.actions {
margin-top: 20px;
display: flex;
gap: 10px;
}
button {
padding: 10px 20px;
background: #3b82f6;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
}
</style>下一步
- Core API - 核心包 API 参考
- Exporters API - 导出工具 API 参考
- Vue 示例 - 完整的 Vue 使用示例