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"
>
<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来实现。
问题
|
原因
|
解决办法
|
描述
|
子组件接收不到参数
|
错误:<component list="{{list}}">
|
正确:<component list="list">
|
|
修改完布局后不刷新,必须要重新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样式文件报错
|
<style>标签解析出错
|
在<style lang="scss">中注明使用类型
|
|
input设置值之后不显示,必须获取焦点后才会显示,失焦后又会消失
|
设置了text-align: 'right'
|
在input外层包一层view,然后为view设置固定宽度,注意不能为100%
|
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持亿速云。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。