跳到主要内容
版本:2.12.0-SNAPSHOT

编辑器集成

此扩展点可以为文章提供新的独立编辑器。

类型定义

{
"editor:create"?: () => EditorProvider[] | Promise<EditorProvider[]>;
}
EditorProvider
export interface EditorProvider {
name: string;
displayName: string;
logo?: string;
component: Component;
rawType: string;
}

其中,component 可以是组件对象或组件名称,且此组件有以下实现要求:

  1. 组件必须包含以下 props:
    1. raw:string:用于接收原始内容。
    2. content:string:用于接收渲染后的内容。
  2. 组件必须包含以下 emit 事件:
    1. update:raw:用于更新原始内容。
    2. update:content:用于更新渲染后的内容。
    3. update:发送更新事件。

示例

此示例将实现一个简单的 Markdown 编辑器。

index.ts
import { definePlugin } from "@halo-dev/console-shared";
import { markRaw } from "vue";
import MarkdownEditor from "./components/markdown-editor.vue";

export default definePlugin({
extensionPoints: {
"editor:create": () => {
return [
{
name: "markdown",
displayName: "Markdown 编辑器",
component: markRaw(MarkdownEditor),
rawType: "markdown",
logo: "/plugins/markdown-editor/assets/logo.png",
},
];
},
},
});
./components/markdown-editor.vue
<script setup>
import { marked } from 'marked'
import { debounce } from 'lodash-es'
import { ref, computed } from 'vue'

const props = withDefaults(
defineProps<{
raw: string;
content: string;
}>(),
{
raw: "",
content: ""
}
);

const emit = defineEmits<{
(event: "update:raw", value: string): void;
(event: "update:content", value: string): void;
(event: "update", value: string): void;
}>();

const output = computed(() => marked(raw.value))

const update = debounce((e) => {
emit("update:raw", e.target.value)
emit("update:content", marked(e.target.value))

if(e.target.value !== raw.value) {
emit("update", e.target.value)
}
}, 100)
</script>

<template>
<div class="editor">
<textarea class="input" :value="raw" @input="update"></textarea>
<div class="output" v-html="output"></div>
</div>
</template>

<style>
body {
margin: 0;
}

.editor {
height: 100vh;
display: flex;
}

.input,
.output {
overflow: auto;
width: 50%;
height: 100%;
box-sizing: border-box;
padding: 0 20px;
}

.input {
border: none;
border-right: 1px solid #ccc;
resize: none;
outline: none;
background-color: #f6f6f6;
font-size: 14px;
font-family: 'Monaco', courier, monospace;
padding: 20px;
}

code {
color: #f66;
}
</style>

来源:https://vuejs.org/examples/#markdown

实现案例