因项目要求,关于vue.js中的前端加入富文本框,原本使用的是vue-quill-editor富文本框,但因客户要求,需要可以加入表格的功能,但是vue-quill-editor中缺少这些,所以最后选择了wangeditor
1.vue中安装wangeditor
npm install wangeditor --save
2.自定义wangeditor组件
新建wangEditor.vue文件,具体代码如下
<template>
<div>
<div id="websiteEditorElem"
style="height:300px;background: #ffffff;"></div>
</div>
</template>
<script>
import E from 'wangeditor'
export default {
name: "wangEditor",
props:{
content:"" //获取从父组件中传过来的值,主要用于修改的时候获取值,并加入到富文本框中
},
data(){
return{
phoneEditor: '',
name: '',
}
},
methods:{
},
mounted () {
this.phoneEditor = new E('#websiteEditorElem')
// 上传图片到服务器,base64形式
this.phoneEditor.config.uploadImgShowBase64 = true
// // 隐藏网络图片
this.phoneEditor.config.showLinkImg = false;
this.phoneEditor.config.debug=true;
//图片上传接口
this.phoneEditor.config.uploadImgServer = '' // 上传图片的接口地址
this.phoneEditor.config.uploadFileName = 'image' // formdata中的name属性,比如现在是将图片image加入到formdate,后台从image中接收到图片数据
this.phoneEditor.config.uploadImgHeaders = {
token: sessionStorage.getItem("token") // 设置请求头
}
this.phoneEditor.config.uploadImgHooks = {
customInsert: function (insertImg, result, editor) {
console.log("成功",result);
before: function (xhr, editor, files) {
// 图片上传之前触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,files 是选择的图片文件
// 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传
// return {
// prevent: true,
// msg: '放弃上传'
// }
},
success: function (xhr, editor, result) {
// 图片上传并返回结果,图片插入成功之后触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
},
fail: function (xhr, editor, result) {
// 图片上传并返回结果,但图片插入错误时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
},
error: function (xhr, editor) {
// 图片上传出错时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
},
timeout: function (xhr, editor) {
// 图片上传超时时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
},
// 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
// (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
customInsert: function (insertImg, result, editor) {
// 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
// insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
// 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
var url = result.url
insertImg(url)
// result 必须是一个 JSON 格式字符串!!!否则报错
}
}
}
// 创建一个富文本编辑器
this.phoneEditor.create()
// 修改的时候,需要富文本内容回显,则需要加入以下代码
// this.phoneEditor.txt.html(this.content)
this.phoneEditor.config.onchange = (html) => {
this.info_ = html // 绑定当前逐渐地值
this.$emit('change', this.info_) // 将内容同步到父组件中
}
},
}
</script>
<style scoped>
</style>
注意事项:
3.图片上传之后
有两种方式获取后端传过来的值,如果上传成功之后,后端返回的参数是以{errno:0, data: […]} 这种格式,那么可以使用上述代码中的success,fail,before,timeout配置。如果不是以{errno:0, data: […]} 这种格式进行数据返回的话,那么需要用customInsert配置,通过var url = result.url, insertImg(url)将图片加入到富文本框中,但是result 必须是一个 JSON 格式字符串!!!否则报错,其中里面的数据可以自己定义。
4. 上述代码中使用的是this.phoneEditor.config
这个跟wangeditor版本有关,版本不同,有的版本使用的是this.phoneEditor.customConfig,如果有问题的话可以看具体的保存信息。
5.将内容同步到父组件中:
5.1通过
this.phoneEditor.config.onchange = (html) => {
this.info_ = html // 绑定当前逐渐地值
this.$emit('change', this.info_)
} // 将内容同步到父组件中
5.2 而父组件中的获取方法是
<wang-editor @change="getUrl1" :content="content_21" ></wang-editor>
@change="getUrl1"获取子组件中的数据,具体方法如下:
getUrl1(path){
this.content_21=path;
},
将子组件的数据加入到this.content_21中
6.修改内容时
需要富文本框中的数据回显,在子组件中加入
props:{
content:"" //获取从父组件中传过来的值,主要用于修改的时候获取值,并加入到富文本框中
},
将从父组件中获取到的数据加入到子组件富文本框中
this.phoneEditor.txt.html(this.content)
7.从父组件中调用子组件时
里面的数据只有在第一次调用时是加载的,再继续使用时是不会加载的,这个需要在父组件中加入v-if,当v-if的值为false时,是将组件销毁,当v-if的值为true时,则重新加载组件,那么这样就能解决子组件加载一次的问题,以及时增加功能,子组件的数据自动清空
父组件:
这里以修改为例
<template>
<!--关于我们-->
<div>
<el-row style="left: 40px">
<el-button @click="update" style="background-color: #42b983;color: white;left: 120px" icon="el-icon-edit-outline">编辑</el-button>
</el-row>
<el-form :modal="form" ref="aboutUs">
<el-form-item label="aboutUs:" prop="about us" :label-width="formLabelWidth">
<!--富文本框数据在页面中展示-->
<div class="ql-editor" v-html="content"></div>
</el-form-item>
</el-form>
<!--编辑-->
<el-dialog title="编辑" :visible.sync="dialogApp1" v-if="dialogApp1">
<el-form :model="form1" ref="contractUs">
<el-form-item label="aboutUs:" prop="about us" :label-width="formLabelWidth">
<!--组件-->
<wang-editor1 @change="getUrl1" :content="content_21" ></wang-editor1>
</el-form-item>
<el-form-item>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogApp1=false">取消</el-button>
<el-button @click="edit" style="background-color: #409EFF;color: white">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {list,add} from '@/api/aboutUs'
import { Message } from "element-ui";
import {upload} from '@/api/image'
import wangEditor1 from '@/views/aboutUs/wangEditor1'
export default {
name: "index",
components:{
wangEditor1
},
data() {
return {
content: "", // 内容
content_21:"",
dialogApp1:false,
formLabelWidth:'120px',
form:{
companyAbout:'',
},
form1:{
companyAbout:'',
}
}
},
methods:{
getUrl1(path){
this.content_21=path;//获取子组件中的数据
},
listAboutUs(){//查询富文本框中的内容
list().then(res=>{
if(res.data.code=="0000"){
this.form.companyAbout=res.data.data.companyAbout;
this.content_21=res.data.data.companyAbout;
this.content=res.data.data.companyAbout;
}else{
Message.error(res.data.message);
}
})
},
update(){//修改
this.dialogApp1=true;
},
edit(){
let data={
"companyAbout":this.content_21
}
add(data).then(res=>{
if(res.data.code=="0000"){
Message.success(res.data.message);
this.listAboutUs();
this.dialogApp1=false;
}else{
Message.error(res.data.message);
}
})
}
},
created() {
this.listAboutUs();
}
}
</script>
<style>
.ivu-upload {
display: none;
}
/* table 样式,没有这个样式的话,那么在页面中展示富文本框表格时,因缺少样式而缺少表格边框*/
table {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
}
table td,
table th {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 3px 5px;
}
table th {
border-bottom: 2px solid #ccc;
text-align: center;
}
/* blockquote 样式 */
blockquote {
display: block;
border-left: 8px solid #d0e5f2;
padding: 5px 10px;
margin: 10px 0;
line-height: 1.4;
font-size: 100%;
background-color: #f1f1f1;
}
/* code 样式 */
code {
display: inline-block;
*display: inline;
*zoom: 1;
background-color: #f1f1f1;
border-radius: 3px;
padding: 3px 5px;
margin: 0 3px;
}
pre code {
display: block;
}
/* ul ol 样式 */
ul, ol {
margin: 10px 0 10px 20px;
}
</style>
8.展示效果