vue中使用富文本编辑器(wangEditor)
wangEditor官网地址:https://www.wangeditor.com/
使用示例
<template>
<div class="app-container">
<div class="box">
<div class="editor-tool">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
mode="default"
/>
<Editor
style="height: 300px; overflow-y: hidden;"
v-model="valueHtml"
:defaultConfig="editorConfig"
mode="default"
@onCreated="handleCreated"
/>
</div>
<div class="btn"><el-button type="primary" @click="isOpen = true">编辑器内容</el-button></div>
<Demo v-model:myValue="isOpen" v-model:content="valueHtml"/>
</div>
</div>
</template>
<script lang="ts" setup>
import { onBeforeUnmount, ref, shallowRef} from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { uploadImage } from "@/api/cabinet/index.js";
import { getToken } from '@/utils/auth'
import Demo from '@/components/Demo.vue'
import '@wangeditor/editor/dist/css/style.css' // 引入 css
const editorRef = shallowRef()
const valueHtml = ref(null) //富文本里面内容,传给后端
const toolbarConfig = {} //工具栏配置
const editorConfig = { //内容区域配置
placeholder: '请输入内容',
MENU_CONF: {}
}
const isOpen = ref(false) //弹窗是否打开
const url = 'http://192.168.31.74:9080/opc-cloud-dev'
const handleCreated = (editor) => {
editorRef.value = editor // 记录 editor 实例,重要!
}
type InsertFnType = (url: string, alt: string, href: string) => void
editorConfig.MENU_CONF["uploadImage"] = { //文件上传
// server: "/dev-api/file/picUp/upFile",
// headers: {
// Authorization: `Bearer ${getToken()}`,
// },
async customUpload(file: File, insertFn: InsertFnType) { // TS 语法-自定义文件上传,用来自己写逻辑调后端接口
// file 即选中的文件
// 自己实现上传,并得到图片 url alt href
// 最后插入图片
const formData = new FormData()
formData.append('file', file)
uploadImage(formData).then((response) => {
insertFn(url+response.data.url, 'xxxx', url+response.data.url)
});
}
};
</script>
<style lang="scss" scoped>
.app-container{
height: calc(100vh - 50px);
background: #EFF3F3;
padding: 24px;
.box {
width: 100%;
height: 100%;
background-color: #fff;
padding: 20px;
.editor-tool{
z-index: 999;
width: 100%;
height: auto;
border: 1px solid #ccc;
margin-bottom: 30px;
}
.btn {
width: 100%;
display: flex;
justify-content: center;
}
}
}
</style>
<template>
<el-dialog
v-model="isShow"
title="Tips"
width="1300px"
>
<span>{{ isShow }}</span>
<div class="view" v-html="dialogContent"></div>
<el-button @click="handleQuery">确定</el-button>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref, defineProps, computed, defineEmits, inject } from 'vue'
interface Props {
myValue: boolean
content: any
}
const props = withDefaults(defineProps<Props>(), {
myValue: true,
content: null
})
const emits = defineEmits(['update:myValue'])
const isShow = computed({
get: () => props.myValue,
set: (value: any) => {
emits('update:myValue', value)
}
})
const dialogContent = computed({
get: () => props.content,
set: (value: any) => {}
})
const handleQuery = async () => {
console.log('编辑器内容', dialogContent.value);
}
</script>
<style lang="scss" scoped></style>