summernote-vue3
v1.1.2
Published
Summernote WYSIWYG editor for Vue 3 + TypeScript
Maintainers
Readme
summernote-vue3
Vue 3 + TypeScript rewrite of Summernote as a standalone component library.
- No jQuery
- No Bootstrap runtime dependency
- Lite-style UI with
note-*class names v-modelHTML binding +invokeAPI- Built-in Markdown mode (HTML <-> Markdown, live preview)
Install
npm install summernote-vue3 vueimport { createApp } from 'vue';
import { Summernote } from 'summernote-vue3';
import 'summernote-vue3/style.css';
createApp({
components: { Summernote },
}).mount('#app');Usage
<script setup lang="ts">
import { ref } from 'vue';
import { Summernote } from 'summernote-vue3';
import 'summernote-vue3/style.css';
const html = ref('<p>Hello</p>');
</script>
<template>
<Summernote
v-model="html"
lang="zh-CN"
:options="{ height: 300, placeholder: 'Write...' }"
@image-upload="(files) => console.log(files)"
/>
</template>Props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| modelValue | string | '' | HTML content (v-model) |
| options | DeepPartial<SummernoteOptions> | defaults | Toolbar, popover, keymap, markdown, etc. |
| lang | string | 'en-US' | Built-in: en-US, zh-CN |
| disabled | boolean | false | Disable editing |
| placeholder | string | undefined | Placeholder text |
Events
Mapped from classic Summernote callbacks:
init, change, focus, blur, enter, keydown, keyup, paste, scroll, imageUpload, imageUploadError, imageLinkInsert, changeCodeview, changeMarkdown, dialogShown, disable, destroy
Exposed API
const editor = ref();
editor.value.code(); // get HTML
editor.value.code('<p>Hi</p>'); // set HTML
editor.value.invoke('editor.bold');
editor.value.focus();
editor.value.reset();
editor.value.enable();
editor.value.disable();Markdown
Toolbar includes a Markdown button (alongside Code view). Click it to switch to a split pane: Markdown source on the left, live HTML preview on the right. Press Esc or toggle again to return to the WYSIWYG editor.
While in Markdown mode:
- HTML is converted to Markdown via Turndown
- Edits sync back to HTML via marked (debounced) and update
v-model @change-markdownemits the current Markdown source string
<template>
<Summernote
v-model="html"
:options="{ height: 300 }"
@change-markdown="(md) => console.log(md)"
/>
</template>Toggle via API
editor.value.invoke('markdown.toggle');
editor.value.invoke('markdown.isActivated'); // boolean
editor.value.invoke('markdown.sync'); // current MD sourceConversion helpers
Standalone converters are also exported for use outside the editor:
import { htmlToMarkdown, markdownToHtml } from 'summernote-vue3';
const md = htmlToMarkdown('<h1>Hello</h1><p>world</p>');
// => "# Hello\n\nworld"
const html = markdownToHtml('# Hello\n\nworld');
// => "<h1>Hello</h1>\n<p>world</p>\n"Options
Pass options.markdown to forward settings to Turndown / marked:
:options="{
height: 300,
markdown: {
turndown: { headingStyle: 'atx', codeBlockStyle: 'fenced' },
marked: { gfm: true, breaks: false },
},
}"To hide the Markdown button, customize the toolbar and omit 'markdown':
:options="{
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['para', ['ul', 'ol', 'paragraph']],
['view', ['fullscreen', 'codeview', 'help']], // no markdown
],
}"Options vs classic Summernote
Most options from classic $.summernote are supported (toolbar, popover, airMode, height, keyMap, fontNames, colors, historyLimit, codeview filters, etc.).
Differences:
| Classic jQuery | summernote-vue3 |
| --- | --- |
| $('#el').summernote(opts) | <Summernote v-model :options /> |
| $('#el').summernote('code') | ref.code() / v-model |
| $('#el').summernote('bold') | ref.invoke('editor.bold') |
| callbacks.onChange | @change / v-model |
| $.summernote.plugins | registerPlugin(name, factory) |
| bs3/bs4/bs5 skins | lite skin only |
| (none) | Markdown mode (markdown.toggle) |
Plugins
import { registerPlugin } from 'summernote-vue3';
registerPlugin('hello', class Hello {
constructor(private context: any) {}
shouldInitialize() { return true; }
initialize() {
this.context.memo('button.hello', () => {
// custom button factory if needed
});
}
destroy() {}
});Development
npm install
npm run dev # demo at http://localhost:5173
npm run build # library build
npm testLegacy jQuery source is kept under legacy/ for reference.
License
MIT
