117 lines
3.0 KiB
Vue
117 lines
3.0 KiB
Vue
<template>
|
|
<div class="my-tinymce">
|
|
<Editor v-model="contentValue" :init="myInit" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import axios from 'axios'
|
|
import tinymce from 'tinymce/tinymce'
|
|
import '@/plugins/tinymce/importTinymce'
|
|
import Editor from '@tinymce/tinymce-vue'
|
|
import { initTiny } from '@/plugins/tinymce/tinymce'
|
|
import { onMounted, toRefs, ref, reactive, defineProps, defineEmits, watch } from 'vue'
|
|
|
|
const props = defineProps({
|
|
modelValue: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
// placeholder
|
|
placeholder: {
|
|
type: String,
|
|
default: 'Please enter content',
|
|
},
|
|
// Default style
|
|
style: {
|
|
type: Object,
|
|
default: () => {
|
|
return { width: '100%', heigth: '400' }
|
|
},
|
|
},
|
|
// image upload server address
|
|
imgUploadUrl: {
|
|
type: String,
|
|
default: '/api/v1/media',
|
|
},
|
|
batchId: {
|
|
type: String,
|
|
},
|
|
})
|
|
const emit = defineEmits(['update:modelValue'])
|
|
|
|
// Parameter custom initialization
|
|
const customer = (init) => {
|
|
// Allow the outside world to pass in height and placeholder
|
|
init.height = props.style.heigth
|
|
init.placeholder = props.placeholder
|
|
|
|
// Paste pictures and automatically process base64
|
|
init.urlconverter_callback = (url, node, _onSave, _name) => {
|
|
if (node === 'img' && url.startsWith('blob:')) {
|
|
tinymce.activeEditor && tinymce.activeEditor.uploadImages()
|
|
}
|
|
return url
|
|
}
|
|
// upload picture
|
|
init.images_upload_handler = (blobInfo, success, failure) => {
|
|
imgUploadFn(blobInfo, success, failure)
|
|
}
|
|
return init
|
|
}
|
|
// const myInit = ref(customer(initTiny(props.batchId)));
|
|
const state = reactive({
|
|
myInit: ref(customer(initTiny(props.batchId))),
|
|
contentValue: props.modelValue, // binding text
|
|
timeout: null,
|
|
})
|
|
|
|
onMounted(() => {
|
|
tinymce.init({})
|
|
})
|
|
|
|
// Listen for text changes and pass them to the outside world
|
|
watch(
|
|
() => state.contentValue,
|
|
() => {
|
|
debounce(() => {
|
|
emit('update:modelValue', state.contentValue)
|
|
})
|
|
}
|
|
)
|
|
// Listen to the default value. The first time a v-model is passed in from the outside world, it is assigned to contentValue.
|
|
watch(
|
|
() => props.modelValue,
|
|
(n) => {
|
|
if (n && n !== state.contentValue) {
|
|
state.contentValue = n
|
|
}
|
|
}
|
|
)
|
|
|
|
const debounce = (fn, wait = 400) => {
|
|
if (state.timeout !== null) {
|
|
clearTimeout(state.timeout)
|
|
}
|
|
state.timeout = setTimeout(fn, wait)
|
|
}
|
|
|
|
const imgUploadFn = async (blobInfo, success, failure) => {
|
|
// Can limit image size
|
|
// if (blobInfo.blob().size / 1024 / 1024 > 2) {
|
|
// failure('Upload failed, please control the image size within 2M')
|
|
// } else {}
|
|
const formData = new FormData()
|
|
formData.append('file', blobInfo.blob(), blobInfo.filename())
|
|
formData.append('batch_id', props.batchId)
|
|
const response = await axios.post('https://api.madomotor.ir'.props.imgUploadUrl, formData)
|
|
|
|
if (response && response.status == 200) {
|
|
return success(response.data.data.url)
|
|
}
|
|
return failure(`HTTP Error: ${response.status}`)
|
|
}
|
|
|
|
const { myInit, contentValue } = toRefs(state)
|
|
</script>
|