Taro把一些小程序的原生组件给抽成了插件
包括但不限于: editor/page-container
,所以直接在代码中写的话是不会被渲染出来的,得经过下面的操作才可以。
<template>
<view class="editor-box">
<view
v-if="showTabBar"
class="editor-box-header"
>
<view
class="operate-box"
@tap="_addImage"
>
<text class="iconfont icon-image" />
view>
<view
class="operate-box"
@tap="_format('italic')"
>
<text class="iconfont icon-italic" />
view>
<view
class="operate-box"
@tap="_format('bold')"
>
<text class="iconfont icon-bold" />
view>
<view
class="operate-box"
@tap="_format('header', 'h1')"
>
<text class="iconfont icon-h1" />
view>
<view
class="operate-box"
@tap="_format('header', 'h2')"
>
<text class="iconfont icon-h2" />
view>
<view
class="operate-box"
@tap="_format('header', 'h3')"
>
<text class="iconfont icon-h3" />
view>
<view
class="operate-box"
@tap="_format('align', 'left')"
>
<text class="iconfont icon-alignLeft" />
view>
<view
class="operate-box"
@tap="_format('align', 'right')"
>
<text class="iconfont icon-alignRight" />
view>
<view
class="operate-box"
@tap="_format('list', 'ordered')"
>
<text class="iconfont icon-orderedList" />
view>
<view
class="operate-box"
@tap="_format('list', 'bullet')"
>
<text class="iconfont icon-unorderedList" />
view>
<view
class="operate-box"
@tap="_undo"
>
<text class="iconfont icon-undo" />
view>
view>
<view class="editor-box-content">
<Editor
id="editor"
class="fz-28 editor"
:name="name"
:value="editorValue"
:placeholder="placeholder"
:showImgResize="true"
:show-img-toolbar="true"
:show-img-resize="true"
@Blur="blur"
@Ready="_onEditorReady"
@Input="_onInputting"
/>
view>
view>
template>
<script>
import Taro from '@tarojs/taro';
import { Editor } from '@tarojs/components';
import request from '@/apis/public';
import './HgEditor.less';
export default {
name: 'HgEditor',
components: { Editor },
props: {
/** 是否显示工具栏 */
showTabBar: {
type: Boolean,
value: true
},
placeholder: {
type: String,
value: '请输入图文详情'
},
name: {
type: String,
value: ''
},
editorValue: {
type: String,
value: ''
}
},
data () {
return {
editorCtx: null
};
},
methods: {
blur () {
this.editorCtx.blur();
},
_onEditorReady () {
Taro.createSelectorQuery().select('#editor').context(res => {
this.editorCtx = res.context;
const that = this;
setTimeout(() => {
if (that.editorValue) {
res.context.setContents({
html: that.editorValue
});
} else {
res.context.setContents({
html: ''
});
}
that.editorCtx.blur();
Taro.pageScrollTo({
scrollTop: 0,
duration: 0
});
}, 100);
}).exec();
},
// 插入图片
_addImage (event) {
Taro.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album'],
success: (res) => {
Taro.showLoading({
title: '上传中',
mask: true
});
this._uploadImage(res.tempFilePaths[0]);
}
});
},
_uploadImage (tempFilePath) {
request.uploadFileCommon('/common/img', tempFilePath, 'imgs', this.wxToken)
.then(res => {
if (res.result_code === 1) {
this.editorCtx.insertImage({
src: res.data[0]
});
} else {
Taro.showToast({
icon: 'error',
title: '上传失败',
mask: true
});
}
Taro.hideLoading();
})
.catch(e => {
Taro.showToast({
title: '上传失败',
icon: 'none',
duration: 1000 // 持续的时间
});
Taro.hideLoading();
});
},
_format (type, val) {
this.editorCtx.format(type, val);
},
// 撤销
_undo () {
this.editorCtx.undo();
},
// 监控输入
_onInputting (e) {
const html = e.detail.html;
// const text = e.detail.text;
this.$emit('input', html);
}
}
};
script>
/* components/hg-editor/hg-editor.wxss */
@import "./iconfont.less";
.editor-box {
width: 100%;
padding: 0;
box-sizing: border-box;
background-color: #fff;
background: #F7F7F7;
}
.editor-box-header,
.editor-box-content {
width: 100%;
}
.editor-box-header {
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: space-between;
padding: 20rpx 20rpx;
box-sizing: border-box;
border-bottom: 2rpx solid #E6E6E6;
background-color: #F6F6F6;
}
.editor-box-header>.operate-box {
width: 40rpx;
height: 40rpx;
overflow: hidden;
color: gray;
}
.editor-box-content {
padding: 20rpx;
box-sizing: border-box;
background: #F7F7F7;
.editor {
height: auto;
margin-top: 0;
}
}
@font-face {
font-family: 'iconfont'; /* Project id 2549449 */
src: url('//at.alicdn.com/t/font_2549449_hxmflg4qsr6.woff2?t=1621002720450') format('woff2'),
url('//at.alicdn.com/t/font_2549449_hxmflg4qsr6.woff?t=1621002720450') format('woff'),
url('//at.alicdn.com/t/font_2549449_hxmflg4qsr6.ttf?t=1621002720450') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 38rpx;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-undo:before {
content: "\e609";
}
.icon-hr:before {
content: "\e60a";
}
.icon-h3:before {
content: "\e60b";
}
.icon-quote:before {
content: "\e60c";
}
.icon-bold:before {
content: "\e60e";
}
.icon-orderedList:before {
content: "\e612";
}
.icon-h2:before {
content: "\e61a";
}
.icon-italic:before {
content: "\e61c";
}
.icon-unorderedList:before {
content: "\e620";
}
.icon-alignLeft:before {
content: "\e621";
}
.icon-alignRight:before {
content: "\e622";
}
.icon-h1:before {
content: "\e623";
}
.icon-image:before {
content: "\e629";
}
<template>
<view class="form-item no-border">
<text class="label">
{{ label }}
text>
<view class="ql-container">
<HgEditor
ref="hgEditor"
:showTabBar="true"
:editorValue="value"
:placeholder="placeholder"
:name="prop"
@input="handleInput"
/>
view>
view>
template>
<script>
import HgEditor from '../HgEditor.vue';
import './editorField.less';
export default {
name: 'EditorField',
components: { HgEditor },
props: {
value: [String, Number],
prop: String,
label: String,
placeholder: String,
type: {
type: String,
default: 'text'
},
uploadImageURL: {
type: String,
value: ''
},
maxlength: {
type: Number,
default: 30
},
disabled: {
type: Boolean,
default: false
}
},
methods: {
handleInput (content) {
this.$emit('fieldChange', this.prop, content);
},
initEditor () {
this.$refs.hgEditor._onEditorReady();
}
}
};
script>
.form-item {
position: relative;
min-height: 167rpx;
padding-top: 60rpx;
padding-bottom: 23rpx;
box-sizing: border-box;
border-bottom: 1rpx solid #F0F0F0;
&.no-border {
border: none !important;
}
.label {
font-size: 30rpx;
font-family: PingFangSC-Medium;
font-weight: 500;
color: #333333;
}
.sub-label {
margin-left: 10rpx;
font-size: 22rpx;
font-family: PingFang SC;
font-weight: 400;
color: #CCCCCC;
}
.input-text {
margin-top: 28rpx;
font-size: 28rpx;
}
.textarea {
width: 100%;
height: 286px;
margin-top: 34rpx;
padding: 35rpx 30rpx;
box-sizing: border-box;
font-size: 28rpx;
background: #F5F6F8;
border-radius: 20rpx;
}
.counter {
position: absolute;
bottom: 30rpx;
right: 35rpx;
font-size: 22rpx;
font-family: PingFang SC;
font-weight: 400;
color: #CCCCCC;
}
.placeholder-class {
font-size: 28rpx;
font-family: PingFangSC-Regular;
font-weight: 400;
color: #CCCCCC;
}
.picker {
position: relative;
.arrow {
width: 15rpx;
height: 26rpx;
position: absolute;
right: 0;
bottom: 14rpx;
}
}
.upload-container {
margin-top: 30rpx;
flex-wrap: wrap;
.ui_uploader_item {
position: relative;
width: 196rpx;
height: 196rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
border-radius: 10rpx;
.ui_uploader_item_icon {
position: absolute;
right: -20rpx;
top: -20rpx;
background: #fff;
border-radius: 50%;
}
image {
width: 196rpx;
height: 196rpx;
}
}
.ui_uploader {
position: relative;
margin: 20rpx 0;
margin-top: 0;
margin-right: 20rpx;
width: 196rpx;
height: 196rpx;
box-sizing: border-box;
background: #F7F7F7;
border-radius: 10rpx;
image {
width: 57rpx;
height: 57rpx;
}
}
}
.ql-container {
height: auto;
margin-top: 34rpx;
border-radius: 20rpx;
}
}
<template>
<EditorField
ref="editorField"
:value="formData.content"
prop="content"
label="商品详情"
placeholder="请输入商品详情"
@fieldChange="fieldChangeHandle"
/>
template>
<script>
export default {
data () {
return {
formData: {
id: '',
content: ''
}
};
},
methods: {
fieldChangeHandle (field, val) {
this.formData[field] = val;
}
}
}
script>