Vue3:集成wangEditor富文本编辑器
集成wangEditor编辑器
·
效果
父组件ArticleText
<template>
<div id="ArticleText">
<el-affix :offset="0">
<div id="ArticleTextHead">
<div id="ArticleTextHeadBack">
<i class="el-icon-arrow-left"></i>
文章管理
</div>
<el-divider direction="vertical"></el-divider>
<div id="ArticleTextHeadTitle">
<el-input
placeholder="请输入内容"
v-model="articleTitle"
maxlength="100"
show-word-limit></el-input>
<div id="ArticleTextHeadTitleOperate">
<el-button type="info" plain>保存草稿</el-button>
<el-button type="danger" plain>发布文章</el-button>
<el-avatar size="medium" :src="circleUrl"></el-avatar>
</div>
</div>
</div>
</el-affix>
<div id="ArticleTextContent">
<TextEditor v-model="content"/>
</div>
</div>
</template>
<script>
import TextEditor from "@/components/TextEditor";
export default {
name: "ArticleText",
components: {TextEditor},
data() {
return {
articleTitle: "",
content: "",
circleUrl: "https://profile.csdnimg.cn/B/4/2/3_kaisarh"
}
},
}
</script>
<style lang="scss" scoped>
#ArticleText {
height: 100%;
width: 100%;
position: relative;
user-select: none;
display: flex;
flex-direction: column;
#ArticleTextHead {
height: 75px;
width: 100%;
//background-color: red;
display: flex;
align-items: center;
box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
z-index: 999;
background-color: white;
#ArticleTextHeadBack {
width: 150px;
font-weight: bold;
font-size: 24px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.el-divider {
height: 24px;
}
#ArticleTextHeadTitle {
display: flex;
align-items: center;
width: 90%;
//background-color: yellow;
position: relative;
.el-input {
flex: 1;
}
#ArticleTextHeadTitleOperate {
width: 250px;
margin: 0 30px;
display: flex;
justify-content: space-around;
align-items: center;
.el-avatar {
cursor: pointer;
}
}
}
}
#ArticleTextContent {
flex: 1;
margin-top: 10px;
width: 100%;
}
}
</style>
富文本编辑器子组件TextEditor
<template>
<div id="TextEditor">
<div id="TextEditorNav">
<div ref='toolbarContainer'></div>
</div>
<div id="TextEditorMain">
<div id="TextEditorMainCode">
<div ref='textContainer'></div>
</div>
<div id="TextEditorMainShow" v-html="articleHtml"></div>
</div>
</div>
</template>
<script>
import WangEditor from 'wangeditor';
import {textService, updateFile} from './../service/api/index'
import axios from "axios";
// 设置菜单
const menus = [
'head',
'bold',
'fontSize',
'fontName',
'italic',
'underline',
'strikeThrough',
'indent',
'lineHeight',
'foreColor',
'backColor',
'link',
'todo',
'justify',
'quote',
'emoticon',
'image',
'splitLine',
]
const LOCAL_BASE_URL = '/api';
export default {
name: "TextEditor",
data() {
return {
articleHtml: "",
editor: null
}
},
mounted() {
// 设置工具栏和编辑区分开
this.editor = new WangEditor(this.$refs.toolbarContainer, this.$refs.textContainer);
// 设置z-index
const editor = this.editor;
editor.config.zIndex = 1;
// 设置内容变化事件
editor.config.onchange = (newHtml) => {
this.onChange(newHtml)
};
// 设置placeholder
editor.config.placeholder = '请输入博文内容';
// 图片菜单配置
editor.config.menus = menus;
// 图片上传配置
editor.config.showLinkImg = false;
editor.config.showLinkImgAlt = false;
editor.config.showLinkImgHref = false;
// 自己实现图片上传
editor.config.customUploadImg = (resultFiles, insertImgFn) => {
this.updateImg(resultFiles[0], insertImgFn);
}
editor.create();
},
methods: {
onChange(newHtml) {
console.log(newHtml);
this.articleHtml = newHtml;
},
updateImg(image, insertImgFn) {
if (image) {
const file = new FormData()
file.append('image', image);
updateFile(file).then(res => {
if (res.status === 200) {
insertImgFn(res.result);
}
})
}
}
}
}
</script>
<style lang="scss" scoped>
#TextEditor {
height: 100%;
width: 100%;
position: relative;
display: flex;
flex-direction: column;
#TextEditorNav {
height: 40px;
width: 98%;
margin-left: 1%;
margin-right: 1%;
background-color: yellow;
}
#TextEditorMain {
flex: 1;
width: 100%;
margin-top: 10px;
margin-bottom: 10px;
display: flex;
justify-content: space-around;
#TextEditorMainCode,
#TextEditorMainShow {
box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
width: 48%;
height: 100%;
}
}
.toolbar {
border: 1px solid #ccc;
}
.text {
border: 1px solid #ccc;
min-height: 400px;
}
}
</style>
服务器端图片上传接口
router.post('/uploadImage', (req, res, next) => {
let form = new formidable.IncomingForm();
form.uploadDir = path.join(__dirname, '../public/uploads/images');
form.keepExtensions = true;
form.parse(req, function (err, fields, files) {
if (err) {
throw err;
}
if (files.image.path) {
let image_url = 'http://localhost:3000/uploads/images/' + path.basename(files.image.path);
res.json({
status: 200,
result: image_url
});
} else {
res.json({
status: 1,
result: '图片路径出现问题!'
});
}
});
})
更多推荐
已为社区贡献6条内容
所有评论(0)