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>

会说话的树
41 声望0 粉丝