乐趣区

关于uniapp:uniapp开发app使用wangeditor富文本编辑器进行编辑查看

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>
退出移动版