wangeditor v5 在vue中的使用

wangeditor的使用

下载依赖  cnpm i @wangeditor/editor @wangeditor/editor-for-vue -D

基础使用

<div style="border: 1px solid #ccc;">
	
   <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editor"
        :defaultConfig="toolbarConfig"
        :mode="mode"
    />
    
    <Editor
        style="height: 500px; overflow-y: hidden;"
        v-model="html"
        :defaultConfig="editorConfig"
        :mode="mode"
        @onCreated="onCreated"
    />
div>
<script>
    import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
    import "@wangeditor/editor/dist/css/style.css"
    export default {
        name: 'HomeView',

        data() {
            return{
                editor: null,
                html: '

hello

'
, // toolbarConfig 里面配置的是一些菜单的显示和隐藏功能,或者一些自定义功能的菜单展示 toolbarConfig: { excludeKeys: ['uploadVideo', 'group-video'] // 表示菜单中不展示上传视频的菜单, group-video 表示上传视频的按钮就没有了 }, // 配置的是一些自定义的功能或者上传图片,视频功能 editorConfig: { placeholder: '请输入内容...', // 设置一些其他的操作,比如上传图片,自定义一些行高,字体,icon等等 }, mode: 'default', // or 'simple' } }, methods: { onCreated(editor) { this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错 } }, mounted() { setTimeout(() => { // 获取菜单的key来自定义显示哪些菜单 console.log(this.editor.getAllMenuKeys()) // 得到的是菜单的key的数组 }, 300) }, beforeDestroy() { const editor = this.editor if (editor == null) return editor.destroy() // 组件销毁时,及时销毁编辑器 }, components: { Editor, Toolbar } } </script>

到此就成了一个最基础的富文本了

接下来就做一些配置上的工作

链接: https://www.wangeditor.com/v5/menu-config.html

配置链接

// 自定义校验链接
const customCheckLinkFn = (text, url) => {
	if (!url) {
		this.$message.warning("链接不能为空");
		return
	}
	if (url.indexOf('http') !== 0) {
		this.$message.warning("链接必须以 http/https 开头");
		return;
	}
	return true

	// 返回值有三种选择:
	// 1. 返回 true ,说明检查通过,编辑器将正常插入链接
	// 2. 返回一个字符串,说明检查未通过,编辑器会阻止插入。会 alert 出错误信息(即返回的字符串)
	// 3. 返回 undefined(即没有任何返回),说明检查未通过,编辑器会阻止插入。但不会提示任何信息
}

// 自定义转换链接 url
const customParseLinkUrl = (url) => {
		if (url.indexOf('http') !== 0) {
			return `http://${url}`
		}
		return url
	}
	// 插入链接的校验
	insertLink: {
	    checkLink: customCheckLinkFn, // 也支持 async 函数
	    parseLinkUrl: customParseLinkUrl // 也支持 async 函数
	},

	// 修改链接的校验
	editLink: {
	    checkLink: customCheckLinkFn, // 也支持 async 函数
	    parseLinkUrl: customParseLinkUrl, // 也支持 async 函数
	},

配置图片的插入

// 自定义校验图片
const customCheckImageFn = (src, alt, url) => {
    if (!src) {
        this.$message.warning("图片网址不能为空");
        return
    }

    if (src.indexOf('http') !== 0) {
        this.$message.warning("图片地址必须以 http/https 开头");
        return '图片地址必须以 http/https 开头'
    }
    if(url.indexOf('http') !== 0) {
        this.$message.warning("图片链接必须以 http/https 开头");
        return '图片链接必须以 http/https 开头'
    }
    return true

    // 返回值有三种选择:
    // 1. 返回 true ,说明检查通过,编辑器将正常插入图片
    // 2. 返回一个字符串,说明检查未通过,编辑器会阻止插入。会 alert 出错误信息(即返回的字符串)
    // 3. 返回 undefined(即没有任何返回),说明检查未通过,编辑器会阻止插入。但不会提示任何信息
}

// 转换图片链接
const customParseImageSrc = (src) => {
    if (src.indexOf('http') !== 0) {
        return `http://${src}`
    }
    return src
}

// 插入网络图片的校验
insertImage: {
    //  插入图片之后的回调
    onInsertedImage(imageNode) {
        if (imageNode == null) return

        const { src, alt, url, href } = imageNode
        console.log('inserted image', src, alt, url, href)
    },

    // 校验图片链接
    checkImage: customCheckImageFn, // 也支持 async 函数

    // 转换图片链接
    parseImageSrc: customParseImageSrc, // 也支持 async 函数
},

// 编辑网络图片的校验
editImage: {
    // 更新图片之后的回调
    onUpdatedImage(imageNode = null) {
        if (imageNode == null) return

        const { src, alt, url } = imageNode
        console.log('updated image', src, alt, url)
    },

    // 校验图片链接
    checkImage: customCheckImageFn, // 也支持 async 函数

    // 转换图片链接
    parseImageSrc: customParseImageSrc, // 也支持 async 函数
},

配置图片的上传

// 图片的上传
uploadImage: {
    async customUpload(file, insertFn) {
        let formData = new FormData();
        formData.append("file", file);
        const configs = {
            // 上传请求头
            headers:{'Content-Type': 'multipart/form-data'},

            // 上传进度
            onUploadProgress: progressEvent => {
                let percent = (progressEvent.loaded / progressEvent.total * 100 | 0);
                console.log(percent)
            }
        };
        const res = await that.$axios.post("/api/uploadFile", formData, configs);
        const { data, success } = res.data;
        if(success) {
            const alt = (data.split("/")[data.split("/").length - 1]).substring(36);
            insertFn(data, alt, data);  // insertFn 参数1:路径; 参数2:alt值; 参数三:路径
        }else{
            that.$message.warning(data);
        }
    }
},

配置视频的插入

 // 自定义校验视频
const customCheckVideoFn = (src) => {
    if (!src) {
        return
    }
    if (src.indexOf('http') !== 0) {
        this.$message.warning("视频地址必须以 http/https 开头");
        return '视频地址必须以 http/https 开头'
    }
    return true

    // 返回值有三种选择:
    // 1. 返回 true ,说明检查通过,编辑器将正常插入视频
    // 2. 返回一个字符串,说明检查未通过,编辑器会阻止插入。会 alert 出错误信息(即返回的字符串)
    // 3. 返回 undefined(即没有任何返回),说明检查未通过,编辑器会阻止插入。但不会提示任何信息
}

// 自定义转换视频
const customParseVideoSrc = (src) => {
    if (src.includes('.bilibili.com')) {
        // 转换 bilibili url 为 iframe (仅作为示例,不保证代码正确和完整)
        const arr = location.pathname.split('/')
        const vid = arr[arr.length - 1]
        return ``
    }
    return src
}

// 插入视频校验
insertVideo: {
    // 插入视频之后的回调
    onInsertedVideo(videoNode = null) {
        if (videoNode == null) return

        const { src } = videoNode
        console.log('inserted video', src)
    },
    // 校验视频链接
    checkVideo: customCheckVideoFn, // 也支持 async 函数
    // 转换视频链接
    parseVideoSrc: customParseVideoSrc, // 也支持 async 函数
},

配置视频的上传

// 视频上传
   uploadVideo: {
       async customUpload(file, insertFn) {
           let formData = new FormData();
           formData.append("file", file);
           const configs = {
               // 上传请求头
               headers:{'Content-Type': 'multipart/form-data'},`在这里插入代码片`

               // 上传进度
               onUploadProgress: progressEvent => {
                   let percent = (progressEvent.loaded / progressEvent.total * 100 | 0);
                   console.log(percent)
               }
           };
           const res = await that.$axios.post("/api/uploadFile", formData, configs);
           const { data, success } = res.data;
           if(success) {
               insertFn(data);
           }else{
               that.$message.warning(data);
           }
       }
   }

完整代码

<template>
    <div class="home">
        <div style="border: 1px solid #ccc;">
            <Toolbar
                style="border-bottom: 1px solid #ccc"
                :editor="editor"
                :defaultConfig="toolbarConfig"
                :mode="mode"
            />
            <Editor
                style="height: 500px; overflow-y: hidden;"
                v-model="html"
                :defaultConfig="editorConfig"
                :mode="mode"
                @onCreated="onCreated"
                @onChange="onChange"
            />
        </div>

        <el-button type="primary" @click="result">结果</el-button>
    </div>
</template>

<script>
    import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
    import "@wangeditor/editor/dist/css/style.css"
    export default {
        name: 'HomeView',

        data() {

            // 自定义校验链接
            const customCheckLinkFn = (text, url) => {
                if (!url) {
                    this.$message.warning("链接不能为空");
                    return
                }
                if (url.indexOf('http') !== 0) {
                    this.$message.warning("链接必须以 http/https 开头");
                    return;
                }
                return true

                // 返回值有三种选择:
                // 1. 返回 true ,说明检查通过,编辑器将正常插入链接
                // 2. 返回一个字符串,说明检查未通过,编辑器会阻止插入。会 alert 出错误信息(即返回的字符串)
                // 3. 返回 undefined(即没有任何返回),说明检查未通过,编辑器会阻止插入。但不会提示任何信息
            }

            // 自定义转换链接 url
            const customParseLinkUrl = (url) => {
                if (url.indexOf('http') !== 0) {
                    return `http://${url}`
                }
                return url
            }


            // 自定义校验图片
            const customCheckImageFn = (src, alt, url) => {
                if (!src) {
                    this.$message.warning("图片网址不能为空");
                    return
                }

                if (src.indexOf('http') !== 0) {
                    this.$message.warning("图片地址必须以 http/https 开头");
                    return '图片地址必须以 http/https 开头'
                }
                if(url.indexOf('http') !== 0) {
                    this.$message.warning("图片链接必须以 http/https 开头");
                    return '图片链接必须以 http/https 开头'
                }
                return true

                // 返回值有三种选择:
                // 1. 返回 true ,说明检查通过,编辑器将正常插入图片
                // 2. 返回一个字符串,说明检查未通过,编辑器会阻止插入。会 alert 出错误信息(即返回的字符串)
                // 3. 返回 undefined(即没有任何返回),说明检查未通过,编辑器会阻止插入。但不会提示任何信息
            }

            // 转换图片链接
            const customParseImageSrc = (src) => {
                if (src.indexOf('http') !== 0) {
                    return `http://${src}`
                }
                return src
            }

            // 自定义校验视频
            const customCheckVideoFn = (src) => {
                if (!src) {
                    return
                }
                if (src.indexOf('http') !== 0) {
                    this.$message.warning("视频地址必须以 http/https 开头");
                    return '视频地址必须以 http/https 开头'
                }
                return true

                // 返回值有三种选择:
                // 1. 返回 true ,说明检查通过,编辑器将正常插入视频
                // 2. 返回一个字符串,说明检查未通过,编辑器会阻止插入。会 alert 出错误信息(即返回的字符串)
                // 3. 返回 undefined(即没有任何返回),说明检查未通过,编辑器会阻止插入。但不会提示任何信息
            }

            // 自定义转换视频
            const customParseVideoSrc = (src) => {
                if (src.includes('.bilibili.com')) {
                    // 转换 bilibili url 为 iframe (仅作为示例,不保证代码正确和完整)
                    const arr = location.pathname.split('/')
                    const vid = arr[arr.length - 1]
                    return ``
                }
                return src
            }

            const that = this;
            return{
                editor: null,
                html: '

hello

'
, toolbarConfig: { }, editorConfig: { placeholder: '请输入内容...', MENU_CONF: { // 插入链接的校验 insertLink: { checkLink: customCheckLinkFn, // 也支持 async 函数 parseLinkUrl: customParseLinkUrl // 也支持 async 函数 }, // 修改链接的校验 editLink: { checkLink: customCheckLinkFn, // 也支持 async 函数 parseLinkUrl: customParseLinkUrl, // 也支持 async 函数 }, // 插入网络图片的校验 insertImage: { // 插入图片之后的回调 onInsertedImage(imageNode) { if (imageNode == null) return const { src, alt, url, href } = imageNode console.log('inserted image', src, alt, url, href) }, // 校验图片链接 checkImage: customCheckImageFn, // 也支持 async 函数 // 转换图片链接 parseImageSrc: customParseImageSrc, // 也支持 async 函数 }, // 编辑网络图片的校验 editImage: { // 更新图片之后的回调 onUpdatedImage(imageNode = null) { if (imageNode == null) return const { src, alt, url } = imageNode console.log('updated image', src, alt, url) }, // 校验图片链接 checkImage: customCheckImageFn, // 也支持 async 函数 // 转换图片链接 parseImageSrc: customParseImageSrc, // 也支持 async 函数 }, // 图片的上传 uploadImage: { async customUpload(file, insertFn) { let formData = new FormData(); formData.append("file", file); const configs = { // 上传请求头 headers:{'Content-Type': 'multipart/form-data'}, // 上传进度 onUploadProgress: progressEvent => { let percent = (progressEvent.loaded / progressEvent.total * 100 | 0); console.log(percent) } }; const res = await that.$axios.post("/api/uploadFile", formData, configs); const { data, success } = res.data; if(success) { const alt = (data.split("/")[data.split("/").length - 1]).substring(36); insertFn(data, alt, data); // insertFn 参数1:路径; 参数2:alt值; 参数三:路径 }else{ that.$message.warning(data); } } }, // 插入视频校验 insertVideo: { // 插入视频之后的回调 onInsertedVideo(videoNode = null) { if (videoNode == null) return const { src } = videoNode console.log('inserted video', src) }, // 校验视频链接 checkVideo: customCheckVideoFn, // 也支持 async 函数 // 转换视频链接 parseVideoSrc: customParseVideoSrc, // 也支持 async 函数 }, // 视频上传 uploadVideo: { async customUpload(file, insertFn) { let formData = new FormData(); formData.append("file", file); const configs = { // 上传请求头 headers:{'Content-Type': 'multipart/form-data'}, // 上传进度 onUploadProgress: progressEvent => { let percent = (progressEvent.loaded / progressEvent.total * 100 | 0); console.log(percent) } }; const res = await that.$axios.post("/api/uploadFile", formData, configs); const { data, success } = res.data; if(success) { insertFn(data); }else{ that.$message.warning(data); } } } } }, mode: 'default', // or 'simple' } }, methods: { onCreated(editor) { this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错 }, result() { console.log(this.html); }, onChange(val) { console.log(val.getHtml()) } }, beforeDestroy() { const editor = this.editor if (editor == null) return editor.destroy() // 组件销毁时,及时销毁编辑器 }, mounted() { setTimeout(()=>{ }, 1000); }, components: { Editor, Toolbar } } </script>
 注:使用视频插入的时候需要在index.html页面中加上 <meta name=referrer content=no-referrer>  标签

你可能感兴趣的:(vue.js,javascript,前端)