创建与挂载
useMsfeEditor() 返回浅引用 editor 和组件宿主 host。在模板中渲染 VueNodeViewHost,组件视图便能保留当前应用的 provide/inject 上下文。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { useMsfeEditor, VueNodeViewHost } from '@quirekit/msfe-vue'
import { StarterKit } from '@quirekit/msfe-starter-kit'
const parent = shallowRef<HTMLElement | null>(null)
const { editor, host } = useMsfeEditor(parent, () => ({
markdown: '## 写作开始',
mode: 'live',
extensions: [StarterKit],
}))
</script>
<template>
<div ref="parent" />
<VueNodeViewHost :host="host" />
</template>
hook 在挂载后创建实例,在卸载时清理编辑器与组件宿主。不要另外创建独立 Vue app 来渲染节点。
options.onError 既接收运行时错误,也接收 createMsfeEditor() 创建失败的原始异常。
创建失败时 editor.value 保持 undefined,组件宿主会释放;宿主可展示错误提示和原文,
修正配置后再明确重新挂载。未提供 onError 时,创建异常继续交给 Vue 的错误处理机制。
配置 factory 自身抛出的异常仍由 Vue 处理。hook 不自动重试,也不在运行错误后重建文档。
更新内容和模式
初始化 options 不会被深度监听。挂载后的变化使用 setMode()、setReadOnly()、applyChanges() 或 replaceDocument()。不要以全文 v-model 的方式在每次输入后回写编辑器。
将编辑器状态接入 Vue
在 setup() 中使用 useMsfeState(),无需自己编写 watch(editor)、初始化快照或取消订阅:
import { useMsfeState } from '@quirekit/msfe-vue'
const state = useMsfeState(editor) // 可直接传给 MdProse 的 state
const cursor = useMsfeState(editor, {
select: state => state.selection.main.head,
})
editor 可为实例、ref 或 getter(例如 () => props.editor)。返回只读的浅引用;创建前、
创建失败、实例被清空或销毁时为 undefined,模板可用 v-if="state" 等待可用状态。
Vue 作用域结束或切换实例会自动清理订阅;借用实例时不会替调用方销毁编辑器。
内部连接 MSFE 的 subscribeState(),只观察已接受的 CodeMirror 状态。快照引用同步更新,
不复制状态、重新解析或序列化全文,也不会向编辑器回写。未调用这个 hook 的组件不增加订阅。
select 和可选的 equal 沿用核心订阅合同:选择器必须纯且有界,每次已接受的更新求值一次,
仅当结果变化时通知 Vue;默认用 Object.is 比较。返回新对象时可提供比较函数,例如
equal: (a, b) => a.from === b.from && a.to === b.to。
selector 在创建 hook 时确定;它只依赖传入的不可变状态,不自动追踪其中读取的其他 Vue ref。
需要与语言等响应式信息组合时,在返回值之外使用 computed()。完整状态供阅读器使用,
工具栏等小型控件优先选择需要的字段。纯选区变化是否能复用阅读内容仍由 MdProse 判断。
Nuxt 与服务端渲染
编辑器依赖浏览器 DOM。在 Nuxt 中使用客户端组件或 ClientOnly 隔离编辑器挂载;文档说明和导航仍可服务端渲染。占位区域预留合理高度,避免页面在加载时跳动。
自定义组件
使用 VueNodeViewRenderer() 替换源码节点的 UI,或使用 VueComponentViewRenderer() 渲染搜索面板等通用控件。完整字段修改流程见自定义节点。
业务 Provider 与 NodeView
应用可以通过 provide 注入语言、权限或业务服务,NodeView 和 ComponentView 通过同一 Host 继续读取。示例 shared/locale.ts 就演示了本地化注入。不要把服务实例或响应式 UI 对象写到 Markdown 字段中。
需要重新配置整个扩展集合时,先保存源码和需要保留的宿主状态,再明确重建实例。options factory 是创建入口,不是深度响应式配置器;修改 props 并不等于扩展热插拔。
Nuxt 项目检查
- 客户端组件中创建 DOM 编辑器,服务端只渲染占位和说明。
- 避免同时打包多份 Vue、CodeMirror state/view;链接工作区源码时在打包器中 dedupe 对应包。
- 自定义组件的依赖必须存在于消费应用,不能依赖文档站私有 alias。
- 路由离开前处理未保存状态;卸载本身只能负责资源清理,不能代替可靠保存。