详解wepy开发小程序踩过的坑(小结)


Posted in Javascript onMay 22, 2019

H5内嵌富文本编辑器

微信小程序没有支持的原生富文本组件,可以通过web-view内嵌H5实现富文本编辑功能,起初使用的是wangEditor富文本编辑器,因为项目使用的是七牛云存储,wangEditor在pc端上传是没有问题的,但在在移动端调用不了本地图片,于是换了个功能强大二次开发较强的富文本编辑器vue-quill-editor,更多请参考官方文档, 基于此对上传图片进行二次开发。

七牛云 + elementUi + vue-quill-editor上传图片和富文本

$ 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()方法向小程序发送数据

注意:官方描述--网页向小程序 postMessage 时,会在特定时机(小程序后退、组件销毁、分享)触发并收到消息

也就是说只有在小程序后退、组件销毁、分享时才会触发,若无效可以调换下顺序就可以了
内嵌的网页代码:

wx.miniProgram.navigateBack({delta: 1})
wx.miniProgram.postMessage({ data: '数据' })

小程序内代码:

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

总结一下:wepy开发最多的问题就是数据缓存,组件双向绑定最好使用twoWay: true来实现。

问题 原因 解决办法 描述
子组件接收不到参数 错误: 正确:
修改完布局后不刷新,必须要重新build 将component写到了page文件夹下导致 将component写到components文件夹下
使用flexbox,设置不换行显示失效 必须加上新的属性 加上white-space: nowrap; 很不解,white-space: nowrap;是设置文字不换行显示的
异步更新数据,不刷新 1.没有使用this.$apply(); 2.传入子组件时需要:prop.sync="data" 1.没有使用this.$apply(); 2.传入子组件时需要:prop.sync="data"
无法多次引用同一个组件 同一个组件多次引用需要在components中声明不同的id 不使用组件,完全靠数据来管理状态 完全靠数据来驱动的话,不知道对性能会不会有很大影响,待测试
给data中声明的属性赋值,如果该属性将传入子组件中,提示内存溢出 在子组件中申明的props的属性名与传入时的属性名不一致 将传入时的属性名和子组件中接收的属性名保持一致
新建page或component,提示not defined 重命名导致 将dist文件夹删除,运行wepy build,重新生成dist文件夹
微信授权多个权限问题
在真机上请求接口没反应,必须开启调试模式才行的问题 开发时开启的不校验域名配置,真机上运行除调试模式外需要域名配置 在微信开发平台配置请求域名
上传图片只能单个上传 不支持多张同时上传 循环上传
真机上本地图片不显示 写components中的组件引用图片路径的问题 图片路径要写使用这个组件的page的相对路径
使用wxParse后,使用autoprefixer打包报错 未知 将wxParse.wxss改为wxParse.scss
input多次设值不改变的问题 未知 使用bindinput事件return值重新设置
后台接受中文参数乱码 需要转码 使用encodeURI("参数")转码
checkbox设置大小 使用class设置transform: scale(0.6);
引用scss样式文件报错
input设置值之后不显示,必须获取焦点后才会显示,失焦后又会消失 设置了text-align: 'right' 在input外层包一层view,然后为view设置固定宽度,注意不能为100%

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JQuery 图片的展开和伸缩实例讲解
Apr 18 Javascript
JQuery表单验证插件EasyValidator用法分析
Nov 15 Javascript
javascript实现下雪效果【实例代码】
May 03 Javascript
JS闭包与延迟求值用法示例
Dec 22 Javascript
详谈angularjs中路由页面强制更新的问题
Apr 24 Javascript
jQuery手风琴的简单制作
May 12 jQuery
JavaScript实现的搜索及高亮显示功能示例
Aug 14 Javascript
在微信小程序里使用watch和computed的方法
Aug 02 Javascript
webstorm中配置Eslint的两种方式及差异比较详解
Oct 19 Javascript
layer提示框添加多个按钮选择的实例
Sep 12 Javascript
vue实现百度搜索功能
Dec 28 Javascript
JavaScript中while循环的基础使用教程
Aug 11 Javascript
vue项目中mock.js的使用及基本用法
May 22 #Javascript
JavaScript函数式编程(Functional Programming)组合函数(Composition)用法分析
May 22 #Javascript
vue以组件或者插件的形式实现throttle或者debounce
May 22 #Javascript
JavaScript函数式编程(Functional Programming)箭头函数(Arrow functions)用法分析
May 22 #Javascript
JavaScript函数式编程(Functional Programming)高阶函数(Higher order functions)用法分析
May 22 #Javascript
浅谈VUE防抖与节流的最佳解决方案(函数式组件)
May 22 #Javascript
详解在React-Native中持久化redux数据
May 22 #Javascript
You might like
PHP入门经历和学习过程分享
2014/04/11 PHP
PHP实现的连贯操作、链式操作实例
2014/07/08 PHP
php通过ksort()函数给关联数组按照键排序的方法
2015/03/18 PHP
JS 实现导航栏悬停效果(续)
2013/09/24 Javascript
js中的preventDefault与stopPropagation详解
2014/01/29 Javascript
使用jquery解析XML的方法
2014/09/05 Javascript
jQuery创建自定义的选择器用以选择高度大于100的超链接实例
2015/03/18 Javascript
JS实现两表格里数据来回转移的方法
2015/05/28 Javascript
基于BootStrap Metronic开发框架经验小结【九】实现Web页面内容的打印预览和保存操作
2016/05/12 Javascript
关于JS中setTimeout()无法调用带参函数问题的解决方法
2016/06/21 Javascript
jQuery插件ContextMenu自定义图标
2017/03/15 Javascript
JS中Attr的用法详解
2017/10/09 Javascript
vue.js2.0 实现better-scroll的滚动效果实例详解
2018/08/13 Javascript
原生JS实现自定义下拉单选选择框功能
2018/10/12 Javascript
原生JS 实现的input输入时表格过滤操作示例
2019/08/03 Javascript
JS document对象简单用法完整示例
2020/01/14 Javascript
element el-tree组件的动态加载、新增、更新节点的实现
2020/02/27 Javascript
Vue 3.0 全家桶抢先体验
2020/04/28 Javascript
JavaScript缺少insertAfter解决方案
2020/07/03 Javascript
解决vue动态下拉菜单 有数据未反应的问题
2020/08/06 Javascript
python中sets模块的用法实例
2014/09/30 Python
Python正则表达式完全指南
2017/05/25 Python
python 读取目录下csv文件并绘制曲线v111的方法
2018/07/06 Python
PyQt5 QListWidget选择多项并返回的实例
2019/06/17 Python
Django 实现图片上传和显示过程详解
2019/07/18 Python
Django集成celery发送异步邮件实例
2019/12/17 Python
Python彻底删除文件夹及其子文件方式
2019/12/23 Python
Tensorflow 使用pb文件保存(恢复)模型计算图和参数实例详解
2020/02/11 Python
HomeAway澳大利亚:预订你的度假屋,公寓、度假村、别墅等
2019/02/20 全球购物
J2ee常用的设计模式?说明工厂模式
2015/05/21 面试题
药学专业大学生自荐信
2013/09/28 职场文书
物流仓管员岗位职责
2013/12/04 职场文书
活动总结报告格式
2014/05/09 职场文书
学生安全责任书范本
2014/07/24 职场文书
班子四风对照检查材料思想汇报
2014/09/29 职场文书
人民检察院起诉书
2015/05/20 职场文书