Использование тинимсе в vue3

Справочная информация: существуют сценарии, в которых в проекте необходимо использовать форматированный текстовый редактор.В настоящее время существует много форматированных текстовых редакторов, и в этом случае используется форматированный текстовый редактор tinymce;

Решение. В vue3 используются два метода, каждый из которых имеет свои преимущества и недостатки:

① Использование официального метода внедрения, преимущества: простота в эксплуатации, недостатки: использование API-ключа для запроса js-файлов в облаке, медленная скорость загрузки, влияющая на работу пользователя;

②Использование локальных файлов для импорта, преимущества: быстрая загрузка, возможность переупаковки в компоненты редактора, недостатки: введение стилей и плагинов более проблематично, а некоторые методы настройки плагинов легко освоить;

Оглавление

1. Официальный метод предоставления Tinymce:

1. Установите tinymce-vue:

2. Подать заявку на API-ключ:

 3. Использовать в компоненте:

2. Используйте локальные файлы для импорта:

1. Установите tinymce и tinymce-vue

2. Обработайте путь к файлу:

 3. Перепакуйте компонент редактора и создайте новый TinymceEditor.vue:

4. Использование в компонентах:

5. Яма:


1. Официальный метод предоставления Tinymce:

В этом случае используется метод tinymce версии 5 (tinymce-vue версии 4).

 Официальная документация (версия 5): интеграция с Vue | Документы | TinyMCE

1. Установите tinymce-vue:

npm install --save "@tinymce/tinymce-vue@^4"

//或者

yarn add "@tinymce/tinymce-vue@^4"

2. Подать заявку на API-ключ:

 3. Использовать в компоненте:

<template>
    <div>
        <Editor :init="myTinyInit" api-key="你申请到的A P I key" v-model="content" />
    </div>
</template>

<script setup>
import {defineExpose, reactive, ref, defineEmits} from 'vue'
import Editor from '@tinymce/tinymce-vue';

const myTinyInit = ref({
    width:'100%', //编辑器宽度,在tinymce版本6中要将toolbar_mode设置为wrap才生效
    height:500, //编辑器高度
    branding: false, //不显示logo
    menubar: false, 
    resize: false, 
    toolbar_mode: 'wrap',
    skeletonScreen: true, //编辑器懒加载,但设置后好像不生效
    placeholder: 'Please enter notification content',
    plugins: ['lists link image table paste help wordcount'], //需要的插件,可参考官方文档引入自己需要的插件
    toolbar: 'undo redo | formatselect | bold italic forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image | help', //工具栏显示工具,可参考官方文档引入自己需要的工具
    fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 26px 36px 48px 56px',
    content_style: 'body, p{font-size: 14px;color:#606266}', //编辑器内的文本样式,也可以自定义 content.css 文件后引入
    //自定义图片上传方法(tinymce版本5)
    images_upload_handler:async (blobInfo, success, failure)=> {
        var formData = new FormData();
        formData.append('file', blobInfo.blob(), blobInfo.filename());
        const res = await tinymceImageUpload(formData); //tinymceImageUpload为封装的图片上传方法,可换成自己的方法
        if (res.code === 1) {
            success(`/image_manipulation/${res.data.filePath}`); //成功之后,返回图片路径,此处/image_manipulation/为图片路径前缀,具体情况根据后端返回的结果来
        } else {
            failure('Image upload failed due to a XHR Transport error. Code: ' + res.msg);
        }
    },
})

</script>

2. Используйте локальные файлы для импорта:

В этом случае используется метод tinymce версии 6 (tinymce-vue версии 5).

Официальная документация: Использование пакета TinyMCE с фреймворком Vue.js | Документация TinyMCE

1. Установите tinymce и tinymce-vue

npm install tinymce
npm install tinymce-vue
//or
yarn add tinymce
yarn add tinymce-vue

2. Обработайте путь к файлу:

① Создайте новую папку tinymce в общей папке (если это vue2, она будет в статической папке);

②Языковый пакет: интерфейс по умолчанию английский.Если вам нужно перейти на китайский интерфейс, вам необходимо загрузить китайский языковой пакет , создать новую папку langs в папке tinymce и поместить загруженный файл в папку langs;

③стиль скинов: создайте новую папку tinymce в общей папке (если это vue2, то она будет в статической папке), найдите скины в node_modules и скопируйте всю папку в /public/tinymce/;

 3. Перепакуйте компонент редактора и создайте новый TinymceEditor.vue:

<template>
    <div>
        <Editor v-model="content" :init="myTinyInit"></Editor>
    </div>
</template>

<script setup>
import {computed, defineEmits, defineProps, onMounted, reactive, ref, watch} from 'vue'
import tinymce from "tinymce/tinymce";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/icons/default/icons";
import "tinymce/themes/silver";
import "tinymce/models/dom/model";

//按需引入插件
import "tinymce/plugins/image";
import "tinymce/plugins/table";
import "tinymce/plugins/lists";
import "tinymce/plugins/link";
import "tinymce/plugins/help";
import "tinymce/plugins/wordcount";

import axios from "axios";
import {useStore} from "vuex";
import {ElNotification} from "element-plus";

const props = defineProps({
    modelValue: {
        type: String,
        default: ""
    },
    plugins: {
        type: [String, Array],
        default:'lists link image table help wordcount',
    },
    toolbar: {
        type: [String, Array],
        default: 'undo redo | formatselect | bold italic forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image | help',
    }
});
const emit = defineEmits(['input']);

const store = useStore();
const myTinyInit = reactive({
    width: '100%',
    height: 500,
    branding: false,
    menubar: false,
    resize: false,
    skin_url: "/tinymce/skins/ui/oxide", //手动引入
    content_css: '/tinymce/skins/content/default/content.css', //手动引入
    toolbar_mode: "wrap",
    plugins: props.plugins,
    toolbar: props.toolbar,
    //图片上传方法(注意!!:要使用 promise 对象中的 resolve 返回图片路径,否则会报错)
    images_upload_handler: (blobInfo) => new Promise((resolve, reject) => {
        let formData = new FormData();
        formData.append('file', blobInfo.blob(), blobInfo.filename());
        axios.post(`/api/backend/upload`, formData, {
            headers: ({
                'Content-Type': 'multipart/form-data',
                'Authorization': "Bearer " + store.state.user.accessToken
            })
        }).then(res => {
            if (res.data.code === 1) {
                resolve(`/image_manipulation${res.data.data.filePath}`)
            } else {
                ElNotification.warning(res.data.msg)
            }
        }).catch(error => {
            reject(error);
        })
    }),
});


const initContent = computed(() => {
    return props.modelValue
});

onMounted(() => {
    tinymce.init({});
})

const content = ref();
watch(initContent, (newVal) => {
    content.value = newVal;
}, {deep: true, immediate: true});

watch(content, (newVal) => {
    emit("input", newVal);
}, {deep: true});
</script>

<style scoped lang="scss">
</style>

4. Использование в компонентах:

<template>
   <div>
      <editor v-model="notificationForm.content" @input="(val)=> {notificationForm.content=val}"></editor>
      //@input方法需要自己定义,不然父组件可能获取不到editor的值
   </div>
</template>

<script setup>
import {reactive} from 'vue'
import Editor from '@/components/backend/TinymceEditor.vue';
const notificationForm = reactive({
    content: '',    
})
</script>

5. Яма:

①Введение файлов: Помимо необходимости локального хранения языковых пакетов и скинов, могут возникать ошибки при импорте файлов css или плагинов, просто импортируйте соответствующие файлы в соответствии с отчетами об ошибках;

②Пользовательский метод: вы не можете использовать упакованный запрос axios, вы должны использовать объект обещания (подробности см. в определении метода images_upload_handler);

рекомендация

отblog.csdn.net/weixin_57092157/article/details/130722805