微信小程序实战项目之富文本编辑器实现

2022-10-07 16:55:27
目录
前言1. 实现效果2. 创建发布页面,实现基本布局3. 实现编辑区操作栏的功能3.1. 实现文本加粗、斜体、文本下划线、左对齐、居中对齐、右对齐3.2. 实现撤销、恢复、插入图片、删除操作4. 参考总结

前言

这是我参加掘金启航计划的第三篇文章,这次总结的是实现一个简单的富文本编辑器,相信阅读文章后,观众老爷们,能够实现富文本编辑器,在微信小程序中发布自己的文章,希望观众老爷们多多支持!

1.>

实现的效果如下图:

实现的功能点如下:

    文本加粗、斜体、下划线,对齐方式撤销、恢复、插入图片、删除功能。

    2.>

    首先创建发布页面 article,在 app.json 中通过配置生成页面即可。

    "pages": [
            "pages/article/article"
        ]

    在 article.wxml 中,书写结构:

    <view>
      <!-- 文章类型 -->
      <view>
        <picker bindchange="bindPickerChange" model:value="{{index}}" range="{{array}}">
          <view class="picker">
            文章类型:{{objectArray[index].name}}
          </view>
        </picker>
      </view>
      <!-- 文章标题 -->
      <view>
        <input name="title" class="title" placeholder="请输入文章标题" maxlength="18" model:value="{{title}}"></input>
      </view>
      <!-- 编辑区 -->
      <view class="container">
        <view class="page-body">
          <view class='wrapper'>
            <!-- 操作栏 -->
            <view class='toolbar' bindtap="format">
               <i class="iconfont icon-zitijiacu"></i>
              <i class="iconfont icon-zitixieti"></i>
              <i class="iconfont icon-zitixiahuaxian"></i>
              <i class="iconfont icon-zuoduiqi"></i>
              <i class="iconfont icon-juzhongduiqi"></i>
              <i class="iconfont icon-youduiqi"></i>
              <i class="iconfont icon-undo"></i>
              <i class="iconfont icon-redo"></i> 
              <i class="iconfont icon-charutupian"></i>
              <i class="iconfont icon-shanchu"></i>
    
            </view>
            <!-- 文章内容区,富文本编辑器 -->
            <editor id="editor" class="ql-container" placeholder="{{placeholder}}"  showImgSize showImgToolbar showImgResize>
            </editor>
            <!-- 发布按钮 -->
            <view class="button" bindtap="formSubmit">发布</view>
          </view>
        </view>
      </view>
    </view>

    在 article.wxss,书写基本的样式:

    page{
        width: 740rpx;
        margin: 0 auto;
        background-color: #f9f9f9;
    
    }
    
    .title {
      border: 1rpx solid #f2f2f2;
      margin: 10rpx;
      height: 70rpx;
      line-height: 70rpx;
      border-radius: 10rpx;
    }
    
    .picker{
      padding: 10rpx;
    }
    
    .wrapper {
      padding: 5px;
    }
    
    .iconfont {
      display: inline-block;
      padding: 8px 8px;
      width: 24px;
      height: 24px;
      cursor: pointer;
      font-size: 20px;
    }
    
    .toolbar {
      box-sizing: border-box;
      border-bottom: 0;
      font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
    }
    
    .ql-container {
      box-sizing: border-box;
      padding: 12px 15px;
      width: 100%;
      min-height: 30vh;
      height: auto;
      background: #fff;
      margin-top: 20px;
      font-size: 16px;
      line-height: 1.5;
      border: 1rpx solid #f2f2f2;
      border-radius: 15rpx;
    }
    
    .button{
      width: 360rpx;
      height: 80rpx;
      line-height: 80rpx;
      text-align: center;
      margin: auto;
      margin-top: 50rpx;
      border-radius: 8rpx;
      font-size: 32rpx;
      color: white;
      background-color: #497749!important;
    }

    这时我们会发现中间的操作栏图标不显示,我们需要在 article.wxss 中头部引入 iconfont.wxss 字体图标。 iconfont.wxss 文件获取地址

    @import "./assets/iconfont.wxss";

    3.>

    本文只实现操作栏的功能,实现富文本编辑,其他文章类型的选择,请自行实现,不难哦!

    首先,我们需要获取富文本编辑器实例 EditorContext,通过 wx.createSelectorQuery 获取,我们在页面 Page 函数中,创建 onEditorReady 函数,用于获取该实例:

        onEditorReady() {
            const that = this
            wx.createSelectorQuery().select('#editor').context(function (res) {
                that.editorCtx = res.context
            }).exec()
        }

    然后将该方法绑定到富文本编辑器的 bindready 属性上,随着富文本编辑器初始化完成后触发,从而获取实例。

    <editor id="editor" 
    class="ql-container" 
    placeholder="{{placeholder}}"  
    showImgSize 
    showImgToolbar 
    showImgResize 
    bindstatuschange="onStatusChange" 
    read-only="{{readOnly}}" 
    bindready="onEditorReady">

    3.1.>

    我们如何修改文本的样式呢?

      通过 EditorContext 实例提供的API:EditorContext.format(string name, string value),进行样式修改。name:CSS属性;value:值。

      通过查阅微信小程序开发文档可知,实现上述功能,我们需要的 namevalue的值为:

      那么我们如何通过点击按钮,来修改文本样式呢?

        首先我们在图标 <i> 标签上绑定namevalue 属性,填上图标所对应上图的 namevalue,无 value 的不填即可。然后在父标签上绑定事件 format,通过该事件函数,使用 EditorContext.format API 进行样式修改。
                <view class='toolbar' bindtap="format">
                  <i class="iconfont icon-zitijiacu  data-name="bold"></i>
                  <i class="iconfont icon-zitixieti data-name="italic"></i>
                  <i class="iconfont icon-zitixiahuaxian  data-name="underline"></i>
                  <i class="iconfont icon-zuoduiqi  data-name="align" data-value="left"></i>
                  <i class="iconfont icon-juzhongduiqi  data-name="align" data-value="center"></i>
                  <i class="iconfont icon-youduiqi data-name="align" data-value="right"></i>
                </view>

        Page 函数中的 format 函数:

            format(e) {
                let {
                    name,
                    value
                } = e.target.dataset
                if (!name) return
                this.editorCtx.format(name, value)
            },

        问题:当我们点击图标时,改变了文本样式,但是图标的样式没有改变,无法提示我们文本现在的样式状态,那该怎么解决呢?

          这时候我们就需要动态改变字体图标的样式了,比如点击图标后,改变颜色。

          通过查阅 editor 微信小程序开发相关文档后,bindstatuschange 属性绑定的方法,会在当你通过 Context 方法改变编辑器内样式时触发,会返回选区已设置的样式。

          那么我们可以在 data 中,添加 formats 对象,存储点击后的样式属性。然后在点击图标按钮时,通过 bindstatuschange 绑定的方法,得到已设置的样式存储到 formats 中;在模板渲染时,在<i> 的 class 属性上,添加 {{formats.align === 'right' ? 'ql-active' : ''}}(如文本向右),当你点击了这个图标,那么 formats 中就有这个属性了,那么就添加我们的动态类名 ql-active 改变图标颜色。

          具体实现

            对 editor 标签属性 bindstatuschange 绑定方法 onStatusChange
            <editor id="editor" 
            class="ql-container" 
            placeholder="{{placeholder}}"  
            showImgSize showImgToolbar showImgResize  
            bindstatuschange="onStatusChange" 
            read-only="{{readOnly}}" 
            bindready="onEditorReady">
                onStatusChange(e) {
                    const formats = e.detail
                    this.setData({
                        formats
                    })
                }
              在图标 <i> 标签上,添加{{formats.align === 'right' ? 'ql-active' : ''}}
                        <i class="iconfont icon-zitijiacu {{formats.bold ? 'ql-active' : ''}}" data-name="bold"></i>
                        <i class="iconfont icon-zitixieti {{formats.italic ? 'ql-active' : ''}}" data-name="italic"></i>
                        <i class="iconfont icon-zitixiahuaxian {{formats.underline ? 'ql-active' : ''}}" data-name="underline"></i>
                        <i class="iconfont icon-zuoduiqi {{formats.align === 'left' ? 'ql-active' : ''}}" data-name="align" data-value="left"></i>
                        <i class="iconfont icon-juzhongduiqi {{formats.align === 'center' ? 'ql-active' : ''}}" data-name="align" data-value="center"></i>
                        <i class="iconfont icon-youduiqi {{formats.align === 'right' ? 'ql-active' : ''}}" data-name="align" data-value="right"></i>
                在 article.wxss 添加 ql-active 类
                .ql-active {
                  color: #497749;
                }

                3.2.>

                首先在 <i> 标签上绑定相应的事件:

                          <i class="iconfont icon-undo" bindtap="undo"></i>
                          <i class="iconfont icon-redo" bindtap="redo"></i> 
                          <i class="iconfont icon-charutupian" bindtap="insertImage"></i>
                          <i class="iconfont icon-shanchu" bindtap="clear"></i>

                撤销 undo

                调用 EditorContext API 即可

                    undo() {
                        this.editorCtx.undo()
                    }

                恢复 redo

                同理

                    redo() {
                        this.editorCtx.redo()
                    }

                插入图片 insertImage

                同理

                    insertImage() {
                        const that = this
                        wx.chooseImage({
                            count: 1,
                            success: function (res) {
                                wx.showLoading({
                                    title: '正在上传图片',
                                })
                                wx.cloud.uploadFile({
                                    cloudPath: `news/upload/${time.formatTime(new Date)}/${Math.floor(Math.random() * 100000000)}.png`, // 上传至云端的路径
                                    filePath: res.tempFilePaths[0], 
                                    success: cover => {
                                        that.editorCtx.insertImage({
                                            src: cover.fileID,
                                            data: {
                                                id: cover.fileID,
                                                role: 'god'
                                            },
                                            success: function () {
                                                wx.hideLoading()
                                            }
                                        })
                                    }
                                })
                            }
                        })
                    }

                清空 clear

                同理

                    clear() {
                        this.editorCtx.clear({
                            success: function (res) {
                                console.log("clear success")
                            }
                        })
                    }

                4.>

                editor | 微信开放文档 (qq.com)

                总结

                到此这篇关于微信小程序实战项目之富文本编辑器实现的文章就介绍到这了,更多相关微信小程序实现富文本编辑器内容请搜索易采站长站以前的文章或继续浏览下面的相关文章希望大家以后多多支持易采站长站!