一、安裝
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' ;