uniapp 微信小程序 编写文章等 editor 编辑器编写富文本

javascript 复制代码
<template>
	<view class="aboutMy ">
		<view class="bx boxsizing">

			<view class="flex jsb ac ">
				<view class=" bigttll">
					<text class="bigtt_bi" style="color:red;margin-right:10rpx;">*</text> 文章封面
				</view>
				<view class=" textareaUpImg boxsizing ml20">
					<view class="up_imgss">
						<view class="up_imgs ">
							<view class="ul flex flexwrap">
								<view class="lis" v-for="(item,index) in upimg_list" :key="index">
									<view class="liss" v-if="item!=''">
										<view class="li">
											<image class="upok w100h100" :src="item" mode="aspectFill"
												@click="previewImages(index)">
											</image>
										</view>
										<view class="delete" v-if="item!=''" @click="ddeletephotos(index)">
											<u-icon name="close-circle-fill" color="#EE4133" size="30"></u-icon>
										</view>
									</view>
								</view>
								<view class="lis" v-if="upimg_list.length<1">
									<view class="li">
										<view class="up flex jc ac flexwrap w100h100" @click="uupphotos(index)">
											<u-icon name="camera" color="#CCCCCC" size="46"></u-icon>
											<view class="upimg_text" style=" ">
												上传图片
											</view>
										</view>
									</view>
								</view>
							</view>
						</view>
					</view>
				</view>
			</view>

			<view class="flex jsb ac ">
				<view class=" bigttll">
					<text class="bigtt_bi" style="color:red;margin-right:10rpx;">*</text> 文章标题
				</view>
				<view class=" textarea1 boxsizing ml20">
					<input class=""  v-model="title" placeholder="请输入文章标题" />
				</view>
			</view>






			<view class="flex jsb ac mt20">
				<view class=" bigttll">
					<text class="bigtt_bi" style="color:red;margin-right:10rpx;">*</text> 发布地址
				</view>
				<view class=" textarea1 boxsizing ml20 flex jsb ac" @click="chooseAdderss">
					<input class=""  disabled v-model="address" placeholder="请选择发布地址" />
					<u-icon name="arrow-right" color="#999" size="16"></u-icon>
				</view>
			</view>


			<view class="flex jsb ac mt20">
				<view class=" bigttll">
					<text class="bigtt_bi" style="color:red;margin-right:10rpx;">*</text> 文章标签
				</view>
				<view class=" textarea1 boxsizing ml20 flex jsb ac" @click="show=true">
					<input class=""  disabled v-model="tag" placeholder="请选择文章标签" />
					<u-icon name="arrow-right" color="#999" size="16"></u-icon>
				</view>
			</view>

			<view class="flex jsb ac mt20">
				<view class=" bigttll">
					<text class="bigtt_bi" style="color:red;margin-right:10rpx;opacity: 0;">*</text> 
					文章附件
				</view>
				<view class=" textarea1 boxsizing ml20 flex jsb ac" @click="choosetypeupfile">
					<view class="">
						{{articleFile?'附件已上传':'请上传附件'}}
					</view>
					<u-icon name="arrow-right" color="#999" size="16"></u-icon>
				</view>
			</view>

			<view class="flex  ac mt20" v-if="articleFile">
				<view class=" bigttll">
					<text class="bigtt_bi" style="color:red;margin-right:10rpx;">*</text> 附件是否显示
				</view>
				<view class="ml20 flex jc ac">
					<u-switch v-model="showfile" @change="change"></u-switch>
					<view class="ml20">
						{{showfile?'显示':'不显示'}}
					</view>
				</view>
			</view>

			<view class="flex jsb ac mt20">
				<view class=" bigttll">
					<text class="bigtt_bi" style="color:red;margin-right:10rpx;">*</text> 文章内容
				</view>
			</view>
			<view class="inp boxsizing">
				<view class="contentBox">
					<!-- 富文本编辑器 -->
					<view class='wrapper'>
						<view class='toolbar' @tap="format">
							<view :class="formats.bold ? 'ql-active' : ''" class="iconfont icon-zitijiacu"
								data-name="bold">
							</view>
							<view :class="formats.italic ? 'ql-active' : ''" class="iconfont icon-zitixieti"
								data-name="italic">
							</view>
							<view :class="formats.underline ? 'ql-active' : ''" class="iconfont icon-zitixiahuaxian"
								data-name="underline"></view>
							<view :class="formats.strike ? 'ql-active' : ''" class="iconfont icon-zitishanchuxian"
								data-name="strike"></view>
							<!-- #ifndef MP-BAIDU -->
							<view :class="formats.align === 'left' ? 'ql-active' : ''" class="iconfont icon-zuoduiqi"
								data-name="align" data-value="left"></view>
							<!-- #endif -->
							<view :class="formats.align === 'center' ? 'ql-active' : ''"
								class="iconfont icon-juzhongduiqi" data-name="align" data-value="center"></view>
							<view :class="formats.align === 'right' ? 'ql-active' : ''" class="iconfont icon-youduiqi"
								data-name="align" data-value="right"></view>
							<view :class="formats.align === 'justify' ? 'ql-active' : ''"
								class="iconfont icon-zuoyouduiqi" data-name="align" data-value="justify"></view>
							<!-- #ifndef MP-BAIDU -->
							<view :class="formats.lineHeight ? 'ql-active' : ''" class="iconfont icon-line-height"
								data-name="lineHeight" data-value="2"></view>
							<view :class="formats.letterSpacing ? 'ql-active' : ''"
								class="iconfont icon-Character-Spacing" data-name="letterSpacing" data-value="2em">
							</view>
							<view :class="formats.marginTop ? 'ql-active' : ''"
								class="iconfont icon-722bianjiqi_duanqianju" data-name="marginTop" data-value="20px">
							</view>
							<view :class="formats.marginBottom ? 'ql-active' : ''"
								class="iconfont icon-723bianjiqi_duanhouju" data-name="marginBottom" data-value="20px">
							</view>
							<!-- #endif -->
						
							<view class="iconfont icon-clearedformat" @tap="removeFormat"></view>
						
							<!-- #ifndef MP-BAIDU -->
							<view :class="formats.fontFamily ? 'ql-active' : ''" class="iconfont icon-font"
								data-name="fontFamily" data-value="Pacifico"></view>
							<view :class="formats.fontSize === '24px' ? 'ql-active' : ''" class="iconfont icon-fontsize"
								data-name="fontSize" data-value="24px"></view>
							<!-- #endif -->
							<view :class="formats.color === '#0000ff' ? 'ql-active' : ''"
								class="iconfont icon-text_color" data-name="color" data-value="#0000ff"></view>
							<view :class="formats.backgroundColor === '#00ff00' ? 'ql-active' : ''"
								class="iconfont icon-fontbgcolor" data-name="backgroundColor" data-value="#00ff00">
							</view>
							<view class="iconfont icon-date" @tap="insertDate"></view>
							<view class="iconfont icon--checklist" data-name="list" data-value="check"></view>
							<view :class="formats.list === 'ordered' ? 'ql-active' : ''"
								class="iconfont icon-youxupailie" data-name="list" data-value="ordered"></view>
							<view :class="formats.list === 'bullet' ? 'ql-active' : ''" class="iconfont icon-wuxupailie"
								data-name="list" data-value="bullet"></view>
						
							<view class="iconfont icon-undo" @tap="undo"></view>
							<view class="iconfont icon-redo" @tap="redo"></view>
						
							<view class="iconfont icon-outdent" data-name="indent" data-value="-1"></view>
							<view class="iconfont icon-indent" data-name="indent" data-value="+1"></view>
							<view class="iconfont icon-fengexian" @tap="insertDivider"></view>
							<view class="iconfont icon-charutupian" @tap="insertImage"></view>
							<view :class="formats.header === 1 ? 'ql-active' : ''" class="iconfont icon-format-header-1"
								data-name="header" :data-value="1"></view>
							<view :class="formats.script === 'sub' ? 'ql-active' : ''" class="iconfont icon-zitixiabiao"
								data-name="script" data-value="sub"></view>
							<view :class="formats.script === 'super' ? 'ql-active' : ''"
								class="iconfont icon-zitishangbiao" data-name="script" data-value="super"></view>
						
							<view class="iconfont icon-shanchu" @tap="clear"></view>
						
							<view :class="formats.direction === 'rtl' ? 'ql-active' : ''"
								class="iconfont icon-direction-rtl" data-name="direction" data-value="rtl"></view>
						</view>
						
						<view class="toolsLine">
						
						</view>
						
						<view class="editor-wrapper">
							<editor id="editor" class="ql-container" placeholder="开始输入..." show-img-size
								show-img-toolbar show-img-resize @statuschange="onStatusChange" @input="editorInput"
								:read-only="readOnly" @ready="onEditorReady">
							</editor>
						</view>
					
					</view>
				</view>


			</view>
			<view class="plank"></view>


		</view>

		<view class="buts flex jsb">
			<view class="left flex flexwrap jc ac" @click.stop="releasell(1)">
				<image class="_icon" src="/static/cun.png" mode="aspectFit"></image>
				<view class="" style="white-space: nowrap;">
					存草稿
				</view>
			</view>
			<view class="but flex jc ac" @click.stop="releasell(0)">
				发布
			</view>
		</view>

		<u-picker :show="show" :columns="columns" @confirm="confirm" @cancel="cancel"></u-picker>
		<u-picker :show="showType" :columns="upfiletype" keyName="title" @confirm="typeconfirm"
			@cancel="typecancel"></u-picker>
	</view>

</template>

<script>
	import tools from "@/tools/index.js";
	export default {
		onLoad(opt) {
			//这是走的编辑或者存草稿的回显
			if (JSON.stringify(opt) != "{}") {
				this.authorgetDetail(opt.id)
				this.id = opt.id;
			}
			//初始化
			this.getTaglist()
		},
		onReady(opt) {
			// console.log(opt,"这是opt");

		},
		data() {
			return {
				id: '',
				show: false,
				about_index: null, //下拉的选择框
				columns: [ //标签列表
					[]
				],
				upimg_list: [],
				value: '',
				content: '', //富文本编辑器内容(富文本形式)
				readOnly: false,
				formats: {},
				tag: '', //选择的标签
				address: '', //选择的地址
				title: '', //文章标题
				articleFile: '', //文章附件文件
				chooseupfiletype: '', //文件类型
				showType: false,
				upfiletype: [
					[{
							type: 1,
							title: '图片',
						},
						{
							type: 2,
							title: '视频',
						},
						{
							type: 3,
							title: '文件',
						}
					]
				],
				showfile: false,
				Article: {} //文章详情
			};
		},
		methods: {
			async authorgetDetail(id) {
				let {
					data,
					code,
					msg
				} = await tools.$api.authorCenter.AuthorArticleDetail({
					id: id
				})
				if (code == 1) {
					console.log(data);
					this.Article = data;
					this.upimg_list[0] = this.Article.image;
					this.title = this.Article.title;
					this.address = this.Article.address;
					this.tag = this.Article.tag;
					this.articleFile = this.Article.file;
					this.showfile = this.Article.show_file == 1 ? true : false;
					this.content = this.Article.content;
				} else {
					this.$publicfun.showToast(msg)
				}
			},
			//是否显示附件
			change(e) {
				console.log('change', e);
			},
			//获取文本标签
			async getTaglist() {
				let {
					data,
					code,
					msg
				} = await tools.$api.authorCenter.taglist();
				if (code == 1) {
					this.columns[0] = data;
				} else {
					this.$publicfun.showToast(msg)
				}
			},
			//打开文件
			fundownloadFile() {
				console.log(this.articleFile);
				uni.downloadFile({
					url: this.articleFile,
					success: function(res) {
						console.log(res, '打开成功');
						var filePath = res.tempFilePath;
						uni.openDocument({
							filePath: filePath,
							showMenu: true,
							success: function(res) {
								console.log('打开文档成功');
								uni.hideLoading()
							},
						});
					},
					complete: function(r) {
						console.log(r);
						uni.hideLoading()
					}
				});
			},
			choosetypeupfile() {
				let that = this;
				if (this.articleFile) {
					uni.showModal({
						title: "提示",
						content: '附件已上传,是否重新上传?',
						success(res) {
							if (res.confirm) {
								that.showType = true;
							}
						}
					})
					return
				}
				this.showType = true;
			},
			//选择标签关闭
			typeconfirm(e) {
				let that = this;
				this.showType = false;
				that.chooseupfiletype = e.value[0].type;
				this.upfile(e.value[0].type)
			},
			typecancel(e) {
				this.showType = false;
			},
			//上传图片
			async upfile(type) {
				let that = this;
				let res = await this.$publicfun.chooseFile()
				tools.$api.indexs.upload_img(res.tempFiles[0].path).then(ress => {
					if (ress.code == 1) {
						
						that.articleFile = ress.data.fullurl;
					}
					console.log(ress, '上传文件');
				})
			},
			//选择标签关闭
			confirm(e) {
				this.tag = e.value[0];
				this.show = false;
			},
			cancel(e) {
				this.show = false;
			},
			//选择地址
			chooseAdderss() {
				let that = this;
				uni.chooseLocation({
					success(res) {
						tools.$api.indexs.getaddress({
							longitude: res.longitude,
							latitude: res.latitude
						}).then(ress => {
							that.address = ress.data;
							// console.log(ress,'地址信息');
						})
					}
				})
			},
			//富文本输入内容
			//发布文章
			releasell(type) {
				const that = this;
				//修改文章
				if (this.id) {
					tools.$api.authorCenter.AuthorEditArticle({
						draft: type,
						content: that.content,
						show_file: that.showfile ? 1 : 0,
						file: that.$publicfun.removeDomainFromUrl(that.articleFile),
						file_type: that.chooseupfiletype,
						address: that.address,
						image: that.$publicfun.removeDomainFromUrl(that.upimg_list[0]),
						title: that.title,
						tag: that.tag,
						article_id: that.id
					}).then(res => {
						if (res.code == 1) {
							uni.navigateBack()
							this.$publicfun.showToast(res.msg)
						} else {
							this.$publicfun.showToast(res.msg)
						}
					})
				} else { //发布文章
					tools.$api.authorCenter.AuthorReleaseArticle({
						draft: type,
						content: that.content,
						show_file: that.showfile ? 1 : 0,
						file: that.$publicfun.removeDomainFromUrl(that.articleFile),
						file_type: that.chooseupfiletype,
						address: that.address,
						image: that.$publicfun.removeDomainFromUrl(that.upimg_list[0]),
						title: that.title,
						tag: that.tag
					}).then(res => {
						if (res.code == 1) {
							uni.navigateBack()
							this.$publicfun.showToast(res.msg)
						} else {
							this.$publicfun.showToast(res.msg)
						}
					})
				}
			},
			async uupphotos(i) {
				let url = await this.$publicfun.upImage(6)
				if (url.tempFilePaths.length > 1) {
					url.tempFilePaths.forEach(item => {
						tools.$api.indexs.upload_img(item).then(res => {
							this.upimg_list.push(res.data.fullurl)
							if (this.upimg_list.length > 6) {
								this.upimg_list = this.upimg_list.splice(0, 6)
								this.$publicfun.showToast('只能上传六张图片')
							}
						})
					})
				} else {
					tools.$api.indexs.upload_img(url.tempFilePaths[0]).then(res => {
						this.upimg_list.push(res.data.fullurl)
					})
				}
			},
			previewImages(i) {
				this.$publicfun.previewImage({
					arr: this.upimg_list,
					i: i
				})
			},
			ddeletephotos(i) {
				this.upimg_list.splice(i, 1)
			},

			//以下是editor 富文本编辑器的方法
			//监听富文本编辑器的输入
			editorInput(e) {
				console.log('this.content', this.content);
				this.content = e.detail.html;
			},
			readOnlyChange() {
				this.readOnly = !this.readOnly
			},
			onEditorReady() {
				let that = this;
				//初始化要有延迟
				setTimeout(() => {
					uni.createSelectorQuery().select('#editor').context((res) => {
						this.editorCtx = res.context
						if (that.id) {
							console.log(that.Article, '文章内容');
							that.editorCtx.setContents({
								html: that.Article.content,
								success: result => {
									console.log('初始化内容成功 ', result)
								},
								fail: err => {
									console.log('初始化内容失败 ', err)
								}
							})
						}
					}).exec()
				}, 300)
			},
			undo() {
				this.editorCtx.undo()
			},
			redo() {
				this.editorCtx.redo()
			},
			format(e) {
				let {
					name,
					value
				} = e.target.dataset
				if (!name) return
				// console.log('format', name, value)
				this.editorCtx.format(name, value)
			},
			onStatusChange(e) {
				const formats = e.detail
				this.formats = formats
			},
			insertDivider() {
				this.editorCtx.insertDivider({
					success: function() {
						console.log('insert divider success')
					}
				})
			},
			clear() {
				uni.showModal({
					title: '清空编辑器',
					content: '确定清空编辑器全部内容?',
					success: res => {
						if (res.confirm) {
							this.editorCtx.clear({
								success: function(res) {
									console.log("clear success")
								}
							})
						}
					}
				})
			},
			removeFormat() {
				this.editorCtx.removeFormat()
			},
			insertDate() {
				const date = new Date()
				const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
				this.editorCtx.insertText({
					text: formatDate
				})
			},
			async getImgSrc(tempSrc) {
				let that = this;
				//let imgSrc = await HadImgList([tempSrc])
				//hadImgList是我自己封装的同步上传文件的方法,这个自行搞定
				//同步上传图片并拿到cdn的地址回显
				// console.log(tempSrc);
				// // return
				// // let url = await this.$publicfun.upImage(1)
				let res = await tools.$api.indexs.upload_img(tempSrc);
				console.log(res, '接口数据');
				// return
				that.editorCtx.insertImage({
					//插入图片的地址
					src: res.data.fullurl,
					alt: '图像',
					success: function() {
						console.log('insert image success')
					}
				})

			},
			insertImage() {
				uni.chooseImage({
					count: 1,
					success: (res) => {
						this.getImgSrc(res.tempFilePaths[0])
					}
				})
			}
		},
	}
</script>
<style>
	page {
		background: #fff;
	}
</style>
<style lang="scss" scoped>
	@import "/static/editor.css";
	@import "/static/editor-icon.css";

	.bigttll {
		white-space: nowrap;
		font-weight: 0 !important;
		font-size: 28rpx;
		color: #3D3D3D;
	}

	.mt20 {
		margin-top: 30rpx;
	}

	.ml20 {

		margin-left: 20rpx;

	}

	.textarea1 {
		width: 520rpx;
		padding: 30rpx;
		box-sizing: border-box;
		border-radius: 14rpx;
		font-size: 26rpx;
		color: #232323;
		background: #F9F9F9;
		border-radius: 18rpx 18rpx 18rpx 18rpx;
	}

	.textareaUpImg {
		width: 520rpx;
	}

	.plank {
		width: 100%;
		height: 200rpx;
	}

	.editor-wrapper {
		max-height: auto;
		// background: #fff;
	}

	.iconfont {
		flex: 0 0 10%;
		display: flex;
		align-items: center;
		justify-content: center;
		margin-bottom: 20rpx;
	}

	.toolsLine {
		width: 100%;
		height: 1rpx;
		background: #999;
		margin-top: 30rpx;
		margin-bottom: 30rpx;
	}

	.toolbar {
		box-sizing: border-box;
		border-bottom: 0;
		font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
		display: flex;
		flex-wrap: wrap;

	}

	.ql-container {
		box-sizing: border-box;
		font-size: 28rpx;
		line-height: 1.5;
		height: 100%;
	}

	.ql-active {
		color: #06c;
	}

	.aboutMy {

		.up_imgss {
			padding: 26rpx 0rpx 0rpx 0rpx;
			box-sizing: border-box;
			// background: #FFFFFF;
			border-radius: 12rpx;
			// margin-top: 20rpx;
		}

		.up_imgs {
			.ul {}

			.lis {

				// width: 150rpx;
				// height: 130rpx;
				width: 200rpx;
				height: 200rpx;
				margin-right: 20rpx;
				margin-bottom: 30rpx;
				position: relative;
				// padding: 50rpx;



				.liss {
					width: 100%;
					height: 100%;
				}
			}

			.delete {
				position: absolute;
				top: 5rpx;
				right: 0rpx;
			}

			.li {
				width: 100%;
				height: 100%;
				margin-bottom: 26rpx;
				color: #0D2D18;
				border-radius: 12rpx 12rpx 12rpx 12rpx;

				.up {
					padding: 30rpx;
					box-sizing: border-box;
					background: #F9F9F9;
					border-radius: 12rpx 12rpx 12rpx 12rpx;

					.upimg_text {
						width: 100%;
						font-size: 20rpx;
						color: #B9BABC;
						text-align: center;
					}
				}


				.upok {
					border-radius: 12rpx 12rpx 12rpx 12rpx;
				}


			}

			.ul {
				.information {
					font-size: 28rpx;
					color: #3D3D3D;
					text-align: center;
				}

				.lis:nth-child(3n+3) {
					margin-right: 0rpx !important;
				}
			}
		}

		.bx {
			padding: 0rpx 30rpx 0 30rpx;
			box-sizing: border-box;

			.da_big_tts {
				height: 24px;
			}

			.da_big_tt {
				font-weight: bold;
				font-size: 36rpx;
				color: #000000;
				position: relative;

			}
		}

		.title {
			.yuan {
				width: 14rpx;
				height: 36rpx;
				border-radius: 1150rpx 1150rpx 1150rpx 1150rpx;
				margin-right: 14rpx;
				background-color: #1D9673;
			}
		}

		.inp {
			height: auto;
			padding: 30rpx;
			// background: #FFFFFF;
			background: #F6F7FB;
			border-radius: 16rpx 16rpx 16rpx 16rpx;
			margin-top: 30rpx;

			.num {
				font-size: 24rpx;
				color: #999999;
			}

			/deep/.u-textarea {
				background: #F6F7FB !important;
				padding: 0rpx;
			}
		}

		.photo_ul {
			margin-top: 20rpx;
			background: #FFFFFF;
			padding: 26rpx;

			.photo_li {
				width: 194rpx;
				height: 194rpx;
				position: relative;
				margin-right: 28rpx;
				margin-bottom: 24rpx;

				.img {
					border-radius: 16rpx 16rpx 16rpx 16rpx;
				}

				.title {
					height: 44rpx;
					position: absolute;
					bottom: 0;
					left: 0;
					background: rgba(35, 35, 35, 0.2);
					border-radius: 0rpx 0rpx 16rpx 16rpx;
					text-align: center;
					font-size: 28rpx;
					color: #FFFFFF;
					// z-index: 1;
				}


				.back {
					position: absolute;
					padding: 48rpx 30rpx;
					background: #F6F7FB;
					border-radius: 16rpx 16rpx 16rpx 16rpx;
					text-align: center;
				}

				.text {
					font-size: 28rpx;
					color: #BABBBF;
				}

				.upphoto {
					position: absolute;
				}

				.index {
					position: absolute;
					left: 5rpx;
					bottom: 0rpx;
					width: 30rpx;
					height: 28rpx;
					background: rgba(35, 35, 35, 0.2);
					border-radius: 0rpx 14rpx 0rpx 14rpx;
					font-size: 20rpx;
					color: #FFFFFF;
				}
			}

			.photo_li:nth-child(3n+3) {
				margin-right: 0rpx !important;
			}
		}

		.buts {
			width: 100%;
			padding: 30rpx 30rpx 30rpx 30rpx;
			box-sizing: border-box;
			position: fixed;
			bottom: 0rpx;
			margin: auto;
			background: #fff;

			// height: 88rpx;
			.left {
				width: 80rpx;
				font-size: 24rpx;
				color: #232323;
				margin-right: 72rpx;

				._icon {
					width: 48rpx;
					height: 48rpx;
				}
			}


			.but {
				width: 100%;
				height: 102rpx;
				background: #2563EB;
				border-radius: 1246rpx 1246rpx 1246rpx 1246rpx;
				font-size: 30rpx;
				color: #FFFFFF;
				// margin-top: 100rpx;

			}
		}

	}
</style>
相关推荐
礼貌而已1 小时前
vue3+ts+uniapp 微信小程序(第一篇)—— 微信小程序定位授权,位置信息权限授权
微信小程序·小程序·uni-app
modaoshi519913 小时前
uniapp 页面铺满屏幕
前端·javascript·uni-app
顽疲3 小时前
java 小红书源码 1:1还原 uniapp
java·开发语言·uni-app
说私域3 小时前
数字经济时代下的创新探索与实践:以“开源AI智能名片2+1链动模式S2B2C商城小程序源码”为核心
人工智能·小程序·开源
ForteScarlet4 小时前
Jetbrains 官方微信小程序插件已上线!
前端·ide·微信小程序·小程序
_Legend_King4 小时前
uniapp省市区懒加载封装
前端·javascript·uni-app
炫爱小七4 小时前
uniapp 地图(map)加载大量自定义坐标卡顿优化
uni-app
竣子好逑4 小时前
uniapp 微信小程序 金额展示套餐
微信小程序·小程序·uni-app
厘子 车6 小时前
小程序如何引入腾讯位置服务
前端·微信小程序·小程序