Utilisation de tinymce dans vue3

Contexte : Il existe des scénarios dans lesquels un éditeur de texte enrichi doit être utilisé dans le projet. Il existe actuellement de nombreux éditeurs de texte enrichi, et l'éditeur de texte enrichi Tinymce est utilisé dans ce cas ;

Solution : Il existe deux méthodes utilisées dans vue3, mais chacune a des avantages et des inconvénients :

① Utilisez la méthode officielle pour présenter, avantages : opération simple ; inconvénients : utilisez une clé API pour demander le fichier js dans le cloud, la vitesse de chargement est lente, ce qui affecte l'expérience utilisateur ;

②Utilisation de fichiers locaux pour importer, avantages : chargement rapide, possibilité de reconditionner les composants de l'éditeur ; inconvénients : l'introduction de styles et de plug-ins est plus gênante, et certaines méthodes de personnalisation de plug-in sont faciles à utiliser ;

Table des matières

1. Méthode de fourniture officielle de Tinymce :

1. Installez Tinymce-vue :

2. Demander une clé API :

 3. Utilisation dans le composant :

2. Utilisez des fichiers locaux pour importer :

1. Installez tinymce et tinymce-vue

2. Traitez le chemin du fichier :

 3. Reconditionnez le composant de l'éditeur et créez un nouveau TinymceEditor.vue :

4. Utilisation dans les composants :

5. Fosse :


1. Méthode de fourniture officielle de Tinymce :

Dans ce cas, la méthode de tinymce version 5 (tinymce-vue version 4) est utilisée

 Documentation officielle (version 5) : Intégration de Vue | Docs | TinyMCE

1. Installez Tinymce-vue :

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

//或者

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

2. Demander une clé API :

 3. Utilisation dans le composant :

<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. Utilisez des fichiers locaux pour importer :

Dans ce cas, la méthode de tinymce version 6 (tinymce-vue version 5) est utilisée

Documentation officielle : Utilisation du package TinyMCE avec le framework Vue.js | Documentation TinyMCE

1. Installez tinymce et tinymce-vue

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

2. Traitez le chemin du fichier :

① Créez un nouveau dossier tinymce sous le dossier public (si c'est vue2, ce sera dans le dossier statique);

②Pack de langue : l'interface par défaut est l'anglais. Si vous devez passer à l'interface chinoise, vous devez télécharger un pack de langue chinoise , créer un nouveau dossier langs sous le dossier tinymce et placer le fichier téléchargé dans le dossier langs ;

③Style Skins : créez un nouveau dossier tinymce sous le dossier public (s'il s'agit de vue2, il se trouvera dans le dossier statique), recherchez les skins dans node_modules et copiez l'intégralité du dossier dans /public/tinymce/ ;

 3. Reconditionnez le composant de l'éditeur et créez un nouveau 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. Utilisation dans les composants :

<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. Fosse :

①Introduction de fichiers : outre la nécessité de stocker localement les modules linguistiques et les habillages, des erreurs peuvent survenir lors de l'importation de fichiers css ou de plug-in, il suffit d'importer les fichiers correspondants en fonction de l'état de l'erreur ;

②Méthode personnalisée : vous ne pouvez pas utiliser la requête axios packagée, vous devez utiliser l'objet promesse (voir la définition de la méthode images_upload_handler pour plus de détails) ;

Je suppose que tu aimes

Origine blog.csdn.net/weixin_57092157/article/details/130722805
conseillé
Classement