vite项目中集成vditor文档编辑器

发布于:2025-08-07 ⋅ 阅读:(16) ⋅ 点赞:(0)

使用vditor

1 下载npm包

npm i vditor

2 新建一个编辑器组件,对vditor进行封装

注意哦这里有三个主题

let theme = ‘classic’   指的是编辑器的颜色

let contentTheme = ‘light’   指的是markdown文档的颜色

let codeTheme = ‘github’   指的是代码块的颜色

<template>
    <div class="vditor-container">
        <div ref="editorRef" class="vditor-editor"></div>
    </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import Vditor from 'vditor'
import 'vditor/dist/index.css'

const props = defineProps({
    modelValue: { type: String, default: '' },
    placeholder: { type: String, default: '请输入内容...' },
    height: { type: [Number, String], default: '100%' },
    theme: { type: String, default: 'classic' }, // 'classic' | 'dark'
    toolbar: { type: Array, default: () => [
            'headings', 'bold', 'italic', 'strike', 'link', '|',
            'list', 'ordered-list', 'check', 'outdent', 'indent', '|',
            'quote', 'line', 'code', 'inline-code', 'insert-before', 'insert-after', '|',
            'upload', 'table', '|', 'undo', 'redo', '|', 'edit-mode', 'both', 'preview', 'fullscreen'
        ]}
})

const emit = defineEmits(['update:modelValue', 'init', 'focus', 'blur'])

const editorRef = ref(null)
let vditorInstance = null

// 初始化 Vditor
const initVditor = () => {
    const systemTheme = localStorage.getItem('theme');
    let theme = 'classic'
    let contentTheme = 'light'
    let codeTheme = 'github'
    if(systemTheme === 'dark') {
        theme = 'dark'
        contentTheme = 'dark'
        //  github-dark nord
        codeTheme = 'github-dark'
    }
    vditorInstance = new Vditor(editorRef.value, {
        height: props.height,
        theme: theme,
        preview: {
            theme: {
                current: contentTheme
            },
            hljs: {
                defaultLang: 'html',
                style: codeTheme,
                lineNumber: true,
                langs: ["vue","mermaid", "echarts", "mindmap", "plantuml", "abc", "graphviz", "flowchart", "apache",
                    "js", "ts", "html","markmap",
                    // common
                    "properties", "apache", "bash", "c", "csharp", "cpp", "css", "coffeescript", "diff", "go", "xml", "http",
                    "json", "java", "javascript", "kotlin", "less", "lua", "makefile", "markdown", "nginx", "objectivec", "php",
                    "php-template", "perl", "plaintext", "python", "python-repl", "r", "ruby", "rust", "scss", "sql", "shell",
                    "swift", "ini", "typescript", "vbnet", "yaml",
                    "ada", "clojure", "dart", "erb", "fortran", "gradle", "haskell", "julia", "julia-repl", "lisp", "matlab",
                    "pgsql", "powershell", "sql_more", "stata", "cmake", "mathematica",
                    // ext
                    "solidity", "yul"
                ]
            },

        },
        placeholder: props.placeholder,
        toolbar: props.toolbar,
        cache: { enable: false }, // 禁用缓存
        after() {
            vditorInstance.setValue(props.modelValue)
            emit('init', vditorInstance)
        },
        input: (value) => {
            emit('update:modelValue', value)
        },
        focus: () => emit('focus'),
        blur: () => emit('blur')
    })
}

// 监听主题变化
watch(() => props.theme, (newTheme) => {
    if (vditorInstance) {
        vditorInstance.setTheme(newTheme)
    }
})

// 监听内容变化(外部修改)
watch(() => props.modelValue, (newVal) => {
    if (newVal !== vditorInstance?.getValue()) {
        vditorInstance.setValue(newVal)
    }
})

onMounted(() => {
    initVditor()
})

onBeforeUnmount(() => {
    if (vditorInstance) {
        vditorInstance.destroy()
        vditorInstance = null
    }
})

// 暴露方法给父组件
defineExpose({
    getVditor: () => vditorInstance,
    getValue: () => vditorInstance?.getValue(),
    setValue: (value) => vditorInstance?.setValue(value),
    focus: () => vditorInstance?.focus(),
    blur: () => vditorInstance?.blur()
})
</script>

<style scoped>
.vditor-container {
    width: 100%;
}
.vditor-editor {
    width: 100%;
}
</style>

3 使用编辑器

<template>
    <div>
        <h1>Vditor 编辑器示例</h1>

        <button @click="toggleTheme">切换主题</button>

        <button @click="getEditorContent">获取内容</button>

        <VditorEditor
            v-model="content"
            :theme="theme"
            :height="600"
            @init="onEditorInit"
        />
    </div>
</template>

<script setup>
import { ref } from 'vue'
import VditorEditor from "@/components/VditorEditor/VditorEditor.vue";

const content = ref('# Hello Markdown!\n\n试试输入 **Markdown** 语法。')
const theme = ref('classic') // 'classic' 或 'dark'
const editorInstance = ref(null)

const toggleTheme = () => {
    theme.value = theme.value === 'classic' ? 'dark' : 'classic'
}

const onEditorInit = (editor) => {
    editorInstance.value = editor
    console.log('编辑器初始化完成', editor)
}

const getEditorContent = () => {
    alert(content.value || '无内容')
}
</script>

这样你的项目就继承了代码编辑器喽


网站公告

今日签到

点亮在社区的每一天
去签到