wangeditor是后台比较常用的一个富文本编辑器,官网链接:https://www.wangeditor.com/
注意:
兼容主流的 PC 浏览器,如 Chrome Firefox Safari Edge 等。
暂不支持移动端编辑(支持移动端查看)。
不再支持 IE 浏览器。
我的需求,能够在移动端编辑、查看,并且能够联动后台。
我在网上找了很多移动端的富文本编辑器,都不符合我的需求,最后使用了webview的方式去实现wagneditor4版本。
具体实现代码如下:
index.vue文件代码
<template>
<view class="initiateContract">
<div class="headerTip" :style="'margin-top:' + height + 'px;'">
<div class="title">
<div class="txt">{{ contractDetails.title }}</div>
<div class="status">
<u-tag v-if="contractDetails.flow_status === '1'" :text="contractDetails.flow_status_name" type="info" size="mini" plain></u-tag>
<u-tag v-if="contractDetails.flow_status === '2'" :text="contractDetails.flow_status_name" type="warning" size="mini" plain></u-tag>
<u-tag v-if="contractDetails.flow_status === '3'" :text="contractDetails.flow_status_name" type="warning" size="mini" plain></u-tag>
<u-tag v-if="contractDetails.flow_status === '5'" :text="contractDetails.flow_status_name" type="success" size="mini" plain></u-tag>
</div>
</div>
<div class="info">注意:合同签署区的代码英文,如company_sign、demand_sign、aunt_sign等英文代码请勿删除</div>
</div>
<view class="html-box">
<web-view :src="'../../../hybrid/html/viewContract/index.html?data=' + obj" @message="getMessage" ref="wv"></web-view>
</view>
<view class="footer" v-if="isKeyboard === false">
<view class="box">
<view class="item" v-if="contractDetails.flow_status == '1'" @click="saveContract">
<view class="btn">
<u-button type="primary" :key="1" :plain="true" text="保存合同"></u-button>
</view>
</view>
<view class="item">
<view class="btn">
<u-button type="primary" :key="2" text="分享预览"></u-button>
</view>
</view>
<view class="item" v-if="contractDetails.flow_status == '1'" @click="openConfirmSigning">
<view class="btn">
<u-button type="primary" :key="3" text="开始签约"></u-button>
</view>
</view>
<view class="item" v-if="contractDetails.flow_status !== '1'">
<view class="btn">
<u-button :disabled="true" :key="4" type="success" text="签约中"></u-button>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import cluesHttp from '@/api/client/index.js'
var wv
export default {
name: "electronContractEdit",
data() {
return {
dianzi_hetong_id: '',
form: {
id: '0',
hetong_id: '',
muban_id: '',
},
contractDetails: {},
contractContent: '',
currentWebview: null,
shareImgInfo: {},
isKeyboard: false,
contentHtml: '',
}
},
onLoad() {
const vm = this;
uni.$on('to-parent', (data) => {
switch( data.type ){
case '1':
uni.setClipboardData({
data: this.shareImgInfo.result.tips,
success: function () {
uni.showToast({
icon: 'none',
title: '链接已复制'
})
}
});
break;
case '2':
break;
}
});
// 获取上个页面传来的参数
const self = this
const eventChannel = this.getOpenerEventChannel();
eventChannel.on('getInitiateContractParams', function(res) {
_this.contractDetails = res
_this.dianzi_hetong_id = res.id
self.currentWebview = self.$scope.$getAppWebview().children()[0]
self.currentWebview.evalJS(`getParams(${JSON.stringify(res)})`)
})
},
onReady() {
// #ifdef APP-PLUS
var currentWebview = this.$scope.$getAppWebview()
setTimeout(function() {
wv = currentWebview.children()[0]
wv.setStyle({
top: uni.getStorageSync('navbarHeight') + 84,
bottom: 71,
width: uni.getSystemInfoSync['screenWidth']
})
}, 100);
// 键盘升起,防止遮挡编辑器内容
uni.onKeyboardHeightChange((res) => {
if(this.isKeyboard === true) {
this.isKeyboard = false
wv.setStyle({
top: uni.getStorageSync('navbarHeight') + 84,
bottom: 71,
width: uni.getSystemInfoSync['screenWidth']
})
} else {
this.isKeyboard = true
wv.setStyle({
top: uni.getStorageSync('navbarHeight') + 84,
bottom: res.height,
width: uni.getSystemInfoSync['screenWidth']
})
}
})
// #endif
},
methods: {
back() {
uni.navigateBack()
},
saveContract() {
const self = this;
self.currentWebview.evalJS("uniEvent('saveContract')"); //app向html发送数据
},
openConfirmSigning() {
let params = {
form: {
dianzi_hetong_id: this.dianzi_hetong_id,
}
}
uni.showModal({
title: '开始签约',
content: '发起签约后,合同内容不能再次修改,同时会消耗一份合同的使用量,是否开始签约?',
complete: (res) => {
if(res.confirm === true) {
cluesHttp.startElectronContractSigning(params).then(res => {
uni.showToast({
icon: 'none',
title: '签约成功'
})
})
}
}
})
},
getMessage(e) {
if(e.detail.data[0].msg === 'saveContract') { //保存合同
let params = {
form: {
title: this.contractDetails.title,
id: this.dianzi_hetong_id,
content: e.detail.data[0].content
}
}
cluesHttp.saveElectronContractDetail(params).then(res => {
uni.showToast({
icon: 'none',
title: '保存成功'
})
})
}
},
},
beforeDestroy() {
uni.$off('to-parent')
uni.offKeyboardHeightChange()
},
}
</script>
<style lang="scss" scoped>
.initiateContract {
.header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 20px 10px;
.left {
display: flex;
align-items: center;
justify-content: flex-start;
}
.title {
text-align: center;
}
.right {
height: 34px;
opacity: 0;
text-align: right;
display: flex;
align-items: center;
justify-content: flex-end;
}
.item {
// width: 30%;
}
}
.headerTip {
background-color: #ffedd1;
z-index: 999;
padding: 10px;
font-size: 12px;
.title {
color: #f9ae3d;
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 10px;
border-bottom: 1px solid #ececec;
}
.info {
word-break: break-all;
}
}
.footer {
position: fixed;
bottom: 0px;
left: 0px;
right: 0px;
z-index: 9999;
padding: 10px 0 20px;
background: #fff;
border-top: 1px solid #f3f3f3;
.box {
display: flex;
justify-content: space-around;
align-items: center;
.item {
.btn {
margin: 0 auto;
}
}
}
}
}
</style>
/hybrid/html/viewContract/index.html文件代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>查看合同</title>
<link rel="stylesheet" href="./css/index.css" />
<link rel="stylesheet" href="./css/wangeditor.css">
</head>
<body>
<div class="post-message-section">
<div class="container">
<!-- 工具栏 -->
<div id="toolbar-container" class="toolbar" style="display: none;"></div>
<!-- 编辑器 -->
<div id="text-container" class="text"></div>
</div>
</div>
<script src="../js/wangeditor.js"></script>
<script type="text/javascript">
var userAgent = navigator.userAgent;
if (/quickapp/i.test(userAgent)) {
// quickapp
document.write('<script type="text/javascript" src="https://quickapp/jssdk.webview.min.js"><\/script>');
}
if (!/toutiaomicroapp/i.test(userAgent)) {
document.querySelector('.post-message-section').style.visibility = 'visible';
}
</script>
<!-- uni 的 SDK -->
<script src="../js/uni-webview.js"></script>
<!-- <script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.1/index.js"></script> -->
<script type="text/javascript">
console.log('接收css参数', decodeURIComponent(location.href.split('data=')[1]))
let params = JSON.parse(decodeURIComponent(location.href.split('data=')[1]))
let dianziHetong = null
let html = ''
// 创建富文本编辑器
const E = window.wangEditor
const editor = new E('#toolbar-container', '#text-container')
editor.create()
window.getParams = (data) => {
console.log("webview内部:", data)
dianziHetong = data
console.log(dianziHetong.flow_status == '1')
let title = dianziHetong.title
let contractHtml = dianziHetong.content
let flow_status_name = dianziHetong.flow_status_name
let flow_status = dianziHetong.flow_status
if (flow_status === '1') {
document.getElementById('text-container').style.height = '100vh'
} else {
editor.disable()
}
editor.txt.html(contractHtml)
}
document.addEventListener('UniAppJSBridgeReady', function() {
// webview加载完成,显示页面
document.getElementsByClassName('post-message-section')[0].style.display = 'block'
// app主动与html通信,用于添加图片到canvas中
function addUniEvenPassthrough() {
window.uniEvent = function(info) {
console.log('app传来的数据', info)
switch (info) {
case 'saveContract':
uni.postMessage({
data: {
msg: 'saveContract',
content: editor.txt.html()
}
});
break;
}
}
}
addUniEvenPassthrough()
})
</script>
</body>
</html>
创建富文本编辑器用法:
<!-- 工具栏 -->
<div id="toolbar-container" class="toolbar" style="display: none;"></div>
<!-- 编辑器 -->
<div id="text-container" class="text"></div>
<script>
// 创建富文本编辑器
const E = window.wangEditor
const editor = new E('#toolbar-container', '#text-container')
//如果不想显示工具栏,可以将样式设置为display: none;
editor.create() //创建
editor.disable() //禁止编辑
editor.txt.html() //获取文本内容
</script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。