wepy開發小程序踩過的坑

H5內嵌富文本編輯器

微信小程序沒有支持的原生富文本組件,能夠經過web-view內嵌H5實現富文本編輯功能,起初使用的是wangEditor富文本編輯器,由於項目使用的是七牛雲存儲,wangEditor在pc端上傳是沒有問題的,但在在移動端調用不了本地圖片,因而換了個功能強大二次開發較強的富文本編輯器vue-quill-editor,更多請參考官方文檔, 基於此對上傳圖片進行二次開發。css

七牛雲 + elementUi + vue-quill-editor上傳圖片和富文本html

$ npm install vue-quill-editor element-ui --save
複製代碼
<template>
  <div class="editor">
    <quill-editor
      v-model="content"
      ref="myQuillEditor"
      :options="editorOption"
      @focus="onEditorFocus($event)"
      @change="onEditorChange($event)">
      <!-- @blur="onEditorBlur($event)" -->
    </quill-editor>
    <!-- 文件上傳input 將它隱藏-->
    <el-upload
      class="upload-demo"
      :action="qnLocation"
      :before-upload='beforeUpload'
      :data="uploadData"
      :on-success='upScuccess'
      ref="upload"
      style="display:none">
      <el-button
        size="small"
        type="primary"
        id="imgInput"
        v-loading.fullscreen.lock="fullscreenLoading">
      </el-button>
    </el-upload>
    <div class="btn_box flex">
      <button class="flex-1 save_draft" @click="handleCancel">取消</button>
      <button class="flex-1 save_release" @click="handleSubmit" :disabled="!content">肯定</button>
    </div>
  </div>
</template>

<script>
import Quill from 'quill'
import api from '@/request/api'
import Cookies from 'js-cookie'

const DOMAIN = 'https://img.makeapoint.info/'

export default {
  name: 'qillEditor',
  computed: {
    editor() {
      return this.$refs.myQuillEditor.quill
    }
  },
  created () {
    this.$nextTick(() => {
      if (this.$route.query.content) {
        this.content = this.$route.query.content
        this.tempRichText = this.content
      }
      let token = this.$route.query.currentToken
      Cookies.set('currentToken_mini', token)
    })
  },
  mounted () {
    this.$refs.myQuillEditor.quill.getModule('toolbar').addHandler('image', this.imgHandler)
  },
  data () {
    return {
      qnLocation: 'https://up-z2.qbox.me',
      uploadData: {}, // 上傳參數
      fullscreenLoading: false,
      addRange: [],
      uploadType: '', // 上傳的文件類型
      content: '', // 提交的富文本內容
      tempRichText: '', // 臨時富文本內容
      editorOption: { // 自定義菜單
        placeholder: "請輸入遊記正文",
        modules: {
          toolbar: [
            // ['bold', 'italic', 'underline', 'strike'],
            // [{ 'header': 1 }, { 'header': 2 }],
            [{ 'list': 'ordered' }, { 'list': 'bullet' }],
            // [{ 'script': 'sub' }, { 'script': 'super' }],
            // [{ 'indent': '-1' }, { 'indent': '+1' }], // 縮進
            // [{ 'direction': 'rtl' }], // 反向
            // [{ 'size': ['small', false, 'large', 'huge'] }], // 字體大小
            // [{ 'header': [1, 2, 3, 4, 5, 6, false] }], // 標題
            // [{ 'font': [] }], // 字體
            [{ 'color': [] }, { 'background': [] }],
            [{ 'align': [] }],
            ['blockquote'],
            ['link', 'image'],
            ['clean']
          ]
        }
      }
    }
  },
  methods: {
    handleCancel () { // 回退至小程序
      window.wx.miniProgram.navigateBack({
        delta: 1
      })
      window.wx.miniProgram.postMessage({ // 向小程序發送數據
        data: this.tempRichText
      })
    },
    handleSubmit () { // 返回小程序並提交富文本內容
      window.wx.miniProgram.navigateBack({
        delta: 1
      })
      window.wx.miniProgram.postMessage({ // 向小程序發送數據
        data: this.content
      })
    },
    // 圖片上傳前得到數據token數據
    qnUpload (file) {
      this.fullscreenLoading = true
      const suffix = file.name.split('.')
      const ext = suffix.splice(suffix.length - 1, 1)[0]
      return api.upload().then(res => {
        this.uploadData = {
          key: `image/${suffix.join('.')}_${new Date().getTime()}.${ext}`,
          token: res.data.data
        }
      })
    },
    // 圖片上傳以前調取的函數
    beforeUpload (file) {
      return this.qnUpload(file)
    },
    // 圖片上傳成功回調插入到編輯器中
    upScuccess (e, file, fileList) {
      this.fullscreenLoading = false
      let url = ''
      url = DOMAIN + e.key
      if (url != null && url.length > 0) {  // 將文件上傳後的URL地址插入到編輯器文本中
        let value = url
        this.addRange = this.$refs.myQuillEditor.quill.getSelection()
        // 調用編輯器的 insertEmbed 方法,插入URL
        this.$refs.myQuillEditor.quill.insertEmbed(this.addRange !== null ? this.addRange.index : 0, this.uploadType, value, Quill.sources.USER)
      }
      this.$refs['upload'].clearFiles() // 插入成功後清除input的內容
    },
    // 點擊圖片icon觸發事件
    imgHandler(state) {
      this.addRange = this.$refs.myQuillEditor.quill.getSelection()
      if (state) {
        let fileInput = document.getElementById('imgInput')
        fileInput.click() // 加一個觸發事件
      }
      this.uploadType = 'image'
    },
    // 點擊視頻icon觸發事件
    // videoHandler(state) {
    //   this.addRange = this.$refs.myQuillEditor.quill.getSelection()
    //   if (state) {
    //     let fileInput = document.getElementById('imgInput')
    //     fileInput.click() // 加一個觸發事件
    //   }
    //   this.uploadType = 'video'
    // },
    // onEditorBlur(editor) {
    //   this.content = html
    // },
    // 編輯器得到光標
    onEditorFocus(editor) {
      editor.enable(true)
    },
    // 編輯器文本發生變化
    onEditorChange({ editor, html, text }) {
      this.content = html
    }
  }
}
</script>
複製代碼
<style lang="less">
.quill-editor {
  .ql-container {
    min-height: 50vh;
  }
}
.ql-editor img {
  width: 100%;
  height: 200px;
}
</style>

<style lang="less" scoped>
.editor {
  width: 100%;
  height: 100vh;
  .flex {
    display: flex;
  }
  .flex-1 {
    flex: 1;
  }
  .btn_box {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 50px;
    line-height: 50px;
    z-index: 999;
    background: #FAFAFA;
    box-shadow:0px 1px 0px 0px rgba(217,217,217,0.5);
    border-top: 1px solid #D9D9D9;
    text-align: center;
    button {
      font-size: 16px;
      line-height: 50px;
      margin: 0;
      padding: 0;
      border: 1px solid #D9D9D9;  //自定義邊框
      outline: none;
    }
    .save_draft{
      color: #B3B3B3;
      border-right: 1px solid #D9D9D9;
    }
    .save_release{
      color: #fff;
      border: 1px solid #00DBD2;
      background: #00DBD2
    }
  }
}
</style>
複製代碼

使用web-view組件傳遞數據的問題

小程序內嵌網頁向小程序回傳數據時,儘可能不要使用路由傳參,好比富文本內容會自動截取掉src等號以後的字符串,應使用wx.miniProgram.postMessage()方法向小程序發送數據vue

注意:官方描述--網頁向小程序 postMessage 時,會在特定時機(小程序後退、組件銷燬、分享)觸發並收到消息git

也就是說只有在小程序後退、組件銷燬、分享時纔會觸發,若無效能夠調換下順序就能夠了github

內嵌的網頁代碼:web

wx.miniProgram.navigateBack({delta: 1})
wx.miniProgram.postMessage({ data: '數據' })
複製代碼

小程序內代碼:shell

<web-view src="{{url}}" bindmessage="handleGetmsg"></web-view>
複製代碼
methods = {
    handleGetmsg (ev) {
      this.data = ev.detail.data[0]
      this.$apply()
    }
}
複製代碼

總結一下:wepy開發最多的問題就是數據緩存,組件雙向綁定最好使用twoWay: true來實現。npm

相關文章
相關標籤/搜索