一、安装
npm install summernote-vue jquery summernote bootstrap @popperjs/core
二、summernoteEditor.vue
< template> < div ref= "editorRef" > < / div>
< / template> < script setup>
import { ref, onMounted, onBeforeUnmount, watch} from 'vue' ;
import $ from 'jquery' ;
window. $ = window. jQuery = $;
import 'bootstrap/dist/css/bootstrap.min.css' ;
import 'bootstrap/dist/js/bootstrap.bundle.min.js' ;
import 'summernote/dist/summernote.min.css' ;
import 'summernote/dist/summernote.min.js' ;
import 'summernote/dist/lang/summernote-zh-CN.js' ; const props = defineProps ( { modelValue: { type: String, default : '' }
} ) ; const emit = defineEmits ( [ 'update:modelValue' , 'init' , 'change' ] ) ;
const editorRef = ref ( null ) ;
let summernoteInstance = null ;
const { proxy } = getCurrentInstance ( ) ;
onMounted ( ( ) => { const mergedOptions = { lang: 'zh-CN' , height: 800 , fontNames: [ '宋体' , '微软雅黑' , '楷体' , '黑体' , '隶书' , 'Arial' , 'Arial Black' , 'Comic Sans MS' , 'Courier New' , 'Helvetica Neue' , 'Helvetica' , 'Impact' , 'Lucida Grande' , 'Tahoma' , 'Times New Roman' , 'Verdana' ] , fontNamesIgnoreCheck: [ '宋体' , '微软雅黑' , '楷体' , '黑体' , '隶书' , 'Arial' , 'Arial Black' , 'Comic Sans MS' , 'Courier New' , 'Helvetica Neue' , 'Helvetica' , 'Impact' , 'Lucida Grande' , 'Tahoma' , 'Times New Roman' , 'Verdana' ] , fontSize: [ '8' , '9' , '10' , '11' , '12' , '14' , '16' , '18' , '24' , '36' , '48' , '60' , '72' , '90' ] , toolbar: [ [ 'style' , [ 'bold' , 'italic' , 'underline' , 'clear' ] ] , [ 'font' , [ 'fontname' ] ] , [ 'fontsize' , [ 'fontsize' ] ] , [ 'color' , [ 'color' ] ] , [ 'para' , [ 'ul' , 'ol' , 'paragraph' ] ] , [ 'table' , [ 'table' ] ] , [ 'insert' , [ 'link' , 'picture' , 'video' ] ] , [ 'view' , [ 'fullscreen' , 'codeview' , 'help' ] ] ] , callbacks: { onChange : ( contents ) => { emit ( 'update:modelValue' , contents) ; emit ( 'change' , contents) ; } , onImageUpload : ( files ) => { uploadImage ( files[ 0 ] ) ; } } , placeholder: '请输入内容...' } ; summernoteInstance = $ ( editorRef. value) . summernote ( mergedOptions) ; if ( props. modelValue) { summernoteInstance. summernote ( 'code' , props. modelValue) ; } emit ( 'init' , summernoteInstance) ;
} ) ;
watch ( ( ) => props. modelValue, ( newValue ) => { if ( summernoteInstance && newValue !== summernoteInstance. summernote ( 'code' ) ) { summernoteInstance. summernote ( 'code' , newValue) ; }
} ) ;
onBeforeUnmount ( ( ) => { if ( summernoteInstance) { summernoteInstance. summernote ( 'destroy' ) ; summernoteInstance = null ; }
} ) ;
const uploadImage = ( file ) => { proxy. $modal. loading ( "正在上传文件,请稍候..." ) ; const formData = new FormData ( ) ; formData. append ( 'file' , file) ; fetch ( import . meta. env. VITE_APP_BASE_API + "/common/upload" , { method: 'POST' , body: formData} ) . then ( response => response. json ( ) ) . then ( data => { if ( data. url) { const imgHtml = ` <img src=" ${ data. url} " alt="上传图片"> ` ; console. log ( imgHtml) console. log ( summernoteInstance) summernoteInstance. summernote ( 'code' , summernoteInstance. summernote ( "code" ) + imgHtml) ; proxy. $modal. closeLoading ( ) ; } else { alert ( '图片上传失败' ) ; } } ) . catch ( error => { console. error ( '上传错误:' , error) ; alert ( '网络错误,上传失败' ) ; } ) ;
} ;
< / script>
三、使用
< SummernoteEditor : modelValue= "form.content" / > import SummernoteEditor from '@/components/summernoteEditor.vue' ;