1,edit页面
1.1 新建edit页面
1.2 从本地相册选择图片或使用相机拍照。
1.3 直接上传文件到云存储。
1.4 从富文本编辑器获取编辑器内容
editorContext.getContents(OBJECT)
首页富文本编辑器初始化完成时,在 onEditReady()方法中通过uni.createSelectorQuery()获取富文本编辑器的上下文( this.editorCtx):
//编辑器初始化完成时触发
onEditReady() {
uni.createSelectorQuery().in(this).select('.myEdit').fields({
size: true,
context: true
}, res => {
console.log(res)
this.editorCtx = res.context
}).exec()
},
打印出的内容:
1.5 data中定义文章数据结构
artObj: {
title: "",//标题
content: "",//内容
description: "",//80字描述
picurls: "",//图片
province: ""//省份地址
}
1.6 点击确认发布方法
点击确认按钮,首先获取富文本编辑器中的内容,然后赋值给artObj对象
具体代码:
//点击提交按钮
onSubmit() {
this.editorCtx.getContents({
success: res => {
console.log(res)
this.artObj.description = res.text.slice(0, 80);
this.artObj.content = res.html;
this.artObj.picurls = getImgSrc(res.html)
uni.showLoading({
title: "发布中..."
})
console.log(this.artObj)
//this.addData();
}
})
},
1.7 封装一个从html中获取image的方法
方法写在utils/tools.js中,然后使用进行引入。
//获取富文本内的图片url地址
export function getImgSrc(richtext, num = 3) {
let imgList = [];
richtext.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/g, (match, capture) => {
imgList.push(capture);
});
imgList = imgList.slice(0, num)
return imgList;
}
注明:num是获取图片的数量。
1.8 封装一个利用高德地图ip的api获取省份地址的方法
需要注册高德web服务api高德web服务api
IP定位
P定位是一套简单的HTTP接口,根据用户输入的IP地址,能够快速的帮用户定位IP的所在位置。
//获取高德地图ip的api接口,通过ip获取所在地址省市
function getIp() {
return new Promise((resolve, reject) => {
uni.request({
url: "https://restapi.amap.com/v3/ip?key=自己创建应用的对应key",
success: res => {
console.log("向高德地图发送网络请求,通过ip获取所在地址省市")
console.log(res)
let str = ""
//处理ip不是国内ip时,返回的地址为自定义的火星地址
typeof(res.data.province) == "string" ? str = res.data.province: str = "火星"
resolve(str)
let obj = {
province: str,
time: Date.now()
}
uni.setStorageSync("historyProvince", obj);
},
fail: err => {
reject(err)
}
})
})
}
两个重点:1,判断返回的省份地址数据类型如果是字符串,就赋值给str,如果不是字符串,省份地址用“火星”代替。
2,省份地址数据结构中加入当前日期信息,只允许在时间范围内发送网络请求(用此防止高频重复请求问题)。
//向外导出省份
export function getProvince() {
return new Promise((resolve, reject) => {
let historyProvince = uni.getStorageSync("historyProvince");
//判读是否在本地缓存中有地址
if (historyProvince) {
//判断超过1天时间 ,重新发起网络请求
if ((Date.now() - historyProvince.time) > 1000 * 10) {
getIp().then(res => {
console.log("重新网络请求")
resolve(res)
}).catch(err => {
reject(err)
})
} else {
console.log("直接从本地缓存中读取")
resolve(historyProvince.province);
}
} else { //缓存中没存地址 调用发送网络请求的方法(返回的一个promise对象)
getIp().then(res => {
console.log("第一次网络请求")
console.log(res)
resolve(res)
}).catch(err => {
reject(err)
})
}
})
}
业务逻辑:首先判断本地缓存中是否存在省份地址数据,如果存在,再判断本地缓存中的数据日期是否在1天内,如果超过1天了,重新发送网络请求,如果没有超过1天,直接从本地缓存读取数据(减少发送网络请求的频次);缓存中没存地址 调用发送网络请求的方法,请求数据(返回的一个promise对象)。
在onload中调用方法:
onLoad() {
//获取省份地址 从高德api 通过ip地址
getProvince().then(res => {
this.artObj.province = res
})
},
1.4 完整代码
<template>
<view class="edit">
<!-- 文章标题 -->
<view class="title">
<input type="text" v-model="artObj.title" placeholder="请输入完整的标题" placeholder-class="placeholderClass">
</view>
<!-- 文章内容 -->
<view class="content">
<editor class="myEdit" placeholder="写点什么吧~~" show-img-size show-img-toolbar show-img-resize @focus="onFocus"
@ready="onEditReady" @statuschange="onStatuschange"></editor>
</view>
<!-- 确认发布按钮 -->
<view class="btnGroup">
<u-button @click="onSubmit" type="primary" :disabled="!artObj.title.length" text="确认发表"></u-button>
</view>
<!-- 工具栏 富文本编辑器 -->
<view class="tools" v-if="toolShow">
<view class="item" @click="clickHead">
<text class="iconfont icon-zitibiaoti" :class="headShow ? 'active' : ''"></text>
</view>
<view class="item" @click="clickBold">
<text class="iconfont icon-zitijiacu" :class="boldShow ? 'active': ''"></text>
</view>
<view class="item" @click="clickItalic">
<text class="iconfont icon-zitixieti" :class="italicShow ? 'active' : ''"></text>
</view>
<view class="item" @click="clickDivider"><text class="iconfont icon-fengexian"></text> </view>
<view class="item" @click="clickInsertImage"><text class="iconfont icon-charutupian"></text> </view>
<view class="item" @click="editOk"><text class="iconfont icon-duigou_kuai"></text> </view>
</view>
</view>
</template>
<script>
import {
getImgSrc,
getProvince
} from "@/utils/tools.js"
const db = uniCloud.database()
export default {
data() {
return {
toolShow: false,
headShow: false,
boldShow: false,
italicShow: false,
artObj: {
title: "",
content: "",
description: "",
picurls: "",
province: ""
}
};
},
onLoad() {
//获取省份地址 从高德api 通过ip地址
getProvince().then(res => {
this.artObj.province = res
})
},
methods: {
//点击提交按钮
onSubmit() {
this.editorCtx.getContents({
success: res => {
console.log(res)
this.artObj.description = res.text.slice(0, 80);
this.artObj.content = res.html;
this.artObj.picurls = getImgSrc(res.html)
uni.showLoading({
title: "发布中..."
})
console.log(this.artObj)
this.addData();
}
})
},
//添加数据到云数据库quanzi_articles
addData() {
db.collection("quanzi_articles").add({
...this.artObj
}).then(res => {
uni.hideLoading();
uni.showToast({
title: "发布成功"
})
setTimeout(() => {
uni.reLaunch({
url: "/pages/index/index"
})
}, 800)
})
},
//富文本标签中的初始化
onEditReady() {
uni.createSelectorQuery().in(this).select('.myEdit').fields({
size: true,
context: true
}, res => {
console.log(res)
this.editorCtx = res.context
}).exec()
},
//检查样式改变的状态
checkStatus(name, detail, obj) {
if (detail.hasOwnProperty(name)) {
this[obj] = true;
} else {
this[obj] = false;
}
},
// 当样式发生改变的时候
onStatuschange(e) {
let detail = e.detail
this.checkStatus("header", detail, "headShow");
this.checkStatus("bold", detail, "boldShow");
this.checkStatus("italic", detail, "italicShow");
},
//添加图像
clickInsertImage() {
uni.chooseImage({
success: async res => {
uni.showLoading({
title: "上传中请稍后",
mask: true
})
for (let item of res.tempFiles) {
let suffix = item.path.substring(item.path.lastIndexOf("."));
let randomName = Date.now() + "" + String(Math.random()).substr(3, 6) + suffix
let res = await uniCloud.uploadFile({
filePath: item.path,
cloudPath: item.name || randomName
})
this.editorCtx.insertImage({
src: res.fileID
})
}
uni.hideLoading()
}
})
},
//点击工具条的确认
editOk() {
this.toolShow = false;
},
//加粗
clickBold() {
this.boldShow = !this.boldShow
this.editorCtx.format("bold")
},
//设置倾斜
clickItalic() {
this.italicShow = !this.italicShow;
this.editorCtx.format("italic")
},
//添加大标题
clickHead() {
this.headShow = !this.headShow
this.editorCtx.format("header", this.headShow ? 'H2' : false)
},
//添加分割线
clickDivider() {
this.editorCtx.insertDivider();
},
//离开焦点
onFocus() {
this.toolShow = true
},
}
}
</script>
<style lang="scss">
/deep/ .ql-blank::before {
font-style: normal;
color: #e0e0e0;
}
.edit {
padding: 30rpx;
.title {
input {
height: 120rpx;
font-size: 46rpx;
border-bottom: 1px solid #e4e4e4;
margin-bottom: 30rpx;
color: #000;
}
.placeholderClass {
color: #e0e0e0;
}
}
.content {
.myEdit {
height: calc(100vh - 500rpx);
margin-bottom: 30rpx;
}
}
.tools {
width: 100%;
height: 80rpx;
background: #fff;
border-top: 1rpx solid #f4f4f4;
position: fixed;
left: 0;
bottom: 0;
display: flex;
justify-content: space-around;
align-items: center;
.iconfont {
font-size: 36rpx;
color: #333;
&.active {
color: #0199FE
}
}
}
}
</style>
2,工具类tools.js
//获取富文本内的图片url地址
export function getImgSrc(richtext, num = 3) {
let imgList = [];
richtext.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/g, (match, capture) => {
imgList.push(capture);
});
imgList = imgList.slice(0, num)
return imgList;
}
//向外导出省份
export function getProvince() {
return new Promise((resolve, reject) => {
let historyProvince = uni.getStorageSync("historyProvince");
//判读是否在本地缓存中有地址
if (historyProvince) {
//判断超过1天时间 ,重新发起网络请求
if ((Date.now() - historyProvince.time) > 1000 * 10) {
getIp().then(res => {
console.log("重新网络请求")
resolve(res)
}).catch(err => {
reject(err)
})
} else {
console.log("直接从本地缓存中读取")
resolve(historyProvince.province);
}
} else { //缓存中没存地址 调用发送网络请求的方法(返回的一个promise对象)
getIp().then(res => {
console.log("第一次网络请求")
console.log(res)
resolve(res)
}).catch(err => {
reject(err)
})
}
})
}
//获取高德地图ip的api接口,通过ip获取所在地址省市
function getIp() {
return new Promise((resolve, reject) => {
uni.request({
url: "https://restapi.amap.com/v3/ip?key=2eae11112968b53f162a109960d4efd1",
success: res => {
console.log("向高德地图发送网络请求,通过ip获取所在地址省市")
console.log(res)
let str = ""
//处理ip不是国内ip时,返回的地址为自定义的火星地址
typeof(res.data.province) == "string" ? str = res.data.province: str = "火星"
resolve(str)
let obj = {
province: str,
time: Date.now()
}
uni.setStorageSync("historyProvince", obj);
},
fail: err => {
reject(err)
}
})
})
}
//获取昵称
export function giveName(item) {
return item.user_id[0].nickname || item.user_id[0].username || item.user_id[0].mobile || "请设置昵称"
}
//获取默认头像
export function giveAvatar(item) {
return item.user_id[0]?.avatar_file?.url ?? '../../static/images/user-default.jpg'
}
const db = uniCloud.database();
const utilsObj = uniCloud.importObject("utilsObj", {
customUI: true
});
//点赞操作数据库的方法
export async function likeFun(artid) {
let count = await db.collection("quanzi_like")
.where(`article_id=="${artid}" && user_id==$cloudEnv_uid`).count()
if (count.result.total) {
db.collection("quanzi_like").where(`article_id=="${artid}" && user_id==$cloudEnv_uid`)
.remove();
utilsObj.operation("quanzi_article", "like_count", artid, -1)
} else {
db.collection("quanzi_like").add({
article_id: artid
})
utilsObj.operation("quanzi_article", "like_count", artid, 1)
}
}
3,uniapp内置富文本编辑器edit组件的刨析
3.1 支持平台差异说明
3.2 属性
3.3 支持的标签
3.4 支持的内联样式
3.5 相关 api—editorContext
editor 组件对应的 editorContext 实例,可通过 uni.createSelectorQuery 获取
代码示例:
//编辑器初始化完成时触发
onEditReady() {
uni.createSelectorQuery().in(this).select('.myEdit').fields({
size: true,
context: true
}, res => {
console.log(res)
this.editorCtx = res.context
}).exec()
},
3.6 节点参数说明
4,edit页面效果
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/135738.html