目录
13. H5中高德地图实现uni.chooseLcation
1.pages.json
官网地址:https://uniapp.dcloud.io/collocation/pages?id=%e9%85%8d%e7%bd%ae%e9%a1%b9%e5%88%97%e8%a1%a8
pages.json是对uniapp进行全局配置,决定了页面文件的路径,窗口样式,原生导航栏,底部原生tabbar等,类似于微信小程序中的app.json的页面管理部分
globalStyle - 对整个项目的全局配置 - 配置导航栏的信息
tabBar对底部tab的配置
pages对单个页面的配置,可以配置是否显示顶部导航栏等
pages.json - 单独配置某个页面的导航栏显示
1.设置基本导航栏
(1)基本配置
pages: [{
"path": "pages/tabbar/tabbar-3/tabbar-3",
"style": {
"titleNView": {
"titleColor": "#ffffff",
"titleText": "详情",
"backgroundColor": "#186ff2"
},
"navigationStyle": "default"
}
}],
(2)动态修改配置
onLoad(){
//设置顶部导航栏的文本文字
uni.setNavigationBarTitle({
title: '消息'
})
//设置导航栏样式
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#196ff2'
});
}
2.配置文件,设置某个文件不显示顶部导航栏
{
"path": "pages/addressBook/myInfoDetail", //个人通讯录详情
"style": {
"app-plus": {
"titleNView": false
}
}
},
3.导航栏左边部分显示文字或图标
’
pages的配置:
{
"path": "pages/noticyManage/detail", //通知管理详情
"style": {
"titleNView": {
"titleColor": "#ffffff",
"titleText": "",
"backgroundColor": "#186ff2",
"buttons": [{
"text": "···",
"fontSize": "24",
"redDot": false
}]
}
}
},
页面监听触发
onNavigationBarButtonTap(e) {
console.log(e)
if(e.text == '添加'){
//跳转到添加页面
uni.navigateTo({
url: '/pages/showFoods/addFoods'
})
}
},
types在官网的配置文档 - uni-app官网
可以进行自定义按钮 -
设置导航栏左边部分
下面是一个例子,基本满足普通项目需求的配置
{
"pages": [{ //页面路径和窗口的表现
"path": "pages/component/index", //配置路径
"style": {
"navigationBarTitleText": "组件"
}
}, {
"path": "pages/API/index",
"style": {
"navigationBarTitleText": "接口"
}
}, {
"path": "pages/component/view/index",
"style": {
"navigationBarTitleText": "view"
}
}],
"condition": { //模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项)
"list": [{
"name": "test", //模式名称
"path": "pages/component/view/index" //启动页面,必选
}]
},
"globalStyle": { //页面的默认样式
"navigationBarTextStyle": "black", //导航栏标题颜色及状态栏前景色(white/black)
"navigationBarTitleText": "演示", //导航栏文字内容
"navigationBarBackgroundColor": "#F8F8F8", //导航栏背景色
"backgroundColor": "#F8F8F8", //下拉显示窗口背景色
"usingComponents":{ //引用小程序组件
"collapse-tree-item":"/components/collapse-tree-item"
},
"renderingMode": "seperated", // 仅微信小程序,webrtc 无法正常时尝试强制关闭同层渲染
"pageOrientation": "portrait"//横屏配置,全局屏幕旋转设置(仅 APP/微信/QQ小程序),支持 auto / portrait / landscape
},
"tabBar": { //底部tab的表现
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"height": "50px",
"fontSize": "10px",
"iconWidth": "24px",
"spacing": "3px",
"list": [{
"pagePath": "pages/component/index",
"iconPath": "static/image/icon_component.png",
"selectedIconPath": "static/image/icon_component_HL.png",
"text": "组件"
}, {
"pagePath": "pages/API/index",
"iconPath": "static/image/icon_API.png",
"selectedIconPath": "static/image/icon_API_HL.png",
"text": "接口"
}],
"midButton": {
"width": "80px",
"height": "50px",
"text": "文字",
"iconPath": "static/image/midButton_iconPath.png",
"iconWidth": "24px",
"backgroundImage": "static/image/midButton_backgroundImage.png"
}
},
"easycom": { //组件自动引入规则
"autoscan": true, //是否自动扫描组件
"custom": {//自定义扫描规则
"uni-(.*)": "@/components/uni-$1.vue"
}
}
}
2.跳转,传参与接收
1.链接跳转
官网 - uni-app官网
传参 地址?参数名=参数值&参数名=参数值
<navigator url="navigate/navigate?title=navigate" hover-class="navigator-hover"> <button type="default">跳转到新页面</button> </navigator>
属性:open-type 可以选择跳转方式
2.点击等事件触发跳转
官网 - uni-app官网
注意:跳转的路径为非tabbar的页面路径
uni.navigateTo({
url: 'test?id=1&name=uniapp'
});
3.接收
在生命周期中接收
onLoad: function (option) { //option为object类型,会序列化上个页面传递的参数
console.log(option.id); //打印出上个页面传递的参数。
console.log(option.name); //打印出上个页面传递的参数。
}
3.解决跨域问题
跨域问题和vue的解决利用代理一样,只是uniapp配置的地方不同
"h5" : {
"optimization" : {
"treeShaking" : {
"enable" : false
}
},
"devServer" : {
"disableHostCheck" : true,
"port" : "8081",
"proxy" : {
"" : {
// "target" : "http://20.4.5.35", //生产环境
"target" : "http://192.168.1.107:8083",
// "target" : "http://211.92.134.56:8282",
"changeOrigin" : true
}
}
},
"domain" : "www.test.test"
}
4.利用原生实现上传附件
5.富文本上传视频等和回显
富文本其实uniapp也是有自己的组件,但是值得悲伤的是,uniapp自带的组件在app是不支持视频上传和解析(rich-text)的(uni-app官网),其实也有很多现有的封装好的组件不满足需求
因此这里借用了wangEdtior进行上传,利用原生代码进行解析回显
wangEditor上传视频在h5是可以的,在app需要修改源码支持,这里就友情提示,可以根据上传图片进行修改上传视频
上传的案例
<template>
<view class="addOrEditMsg_wagePolicy" :editorHtml="editorHtml" :change:editorHtml="wagePolicyNew.changeHtml">
<view>
<u-form :model="form" ref="uForm">
<u-form-item label="标题" prop="title" required>
<u-input v-model="form.title" placeholder="请输入标题" />
</u-form-item>
<u-form-item label="正文内容" prop="policy_content" required class="hasTextarea form_flex_column">
<view class="editH" id="editH">
<!-- <jinEdit placeholder="请输入内容并保存" ref="editFrom" @editOk="editOk" :html="initHtml"></jinEdit> -->
</view>
</u-form-item>
<u-form-item label="附件" prop="attachment_code" class="form_flex_column">
<view class="test">
<view class="wrap">
<view class="pre-box">
<view class="pre-item" v-for="(item, index) in lists" :key="index">
<view><text class="textOver">{{item.substr(item.lastIndexOf('\\') + 1)}}</text>
<image src="../../static/img/icon/false.png" @click="delfoc(index)"></image>
</view>
</view>
</view>
<view class="uploadFiles">
<UploadFile @uploaded='uploaded'></UploadFile>
</view>
</view>
</view>
</u-form-item>
</u-form>
<view class="form_button flex_a">
<button @click="wagePolicyNew.submitToComp">提交</button>
</view>
</view>
</view>
</template>
<script>
import {
Config
} from '@/utils/config.js';
const config = new Config();
let prefix = config.getImgPdfUrl();
// import jinEdit from '@/components/jin-edit/jin-edit.vue';
import {
UploadApi
} from '@/api/upload.js';
import {
WagePolicyApi
} from '@/api/wagePolicy.js';
import UploadFile from '@/pages/commonComponents/uploadFile.vue'
const uploadApi = new UploadApi();
const wagePolicyApi = new WagePolicyApi();
export default {
components: {
UploadFile // jinEdit
},
data() {
return {
showUploadList: false, //展示下载列表
lists: [], //附件列表
initHtml: '',
editorHtml: '',
fileList: [],
// attachmentList: [], //附件列表
form: {
title: "", //标题
"policy_content": "", //正文内容
attachment_code: {
attachment: []
}, //附近
sys_org_code: '', //部门id
create_by: '', //创建人
create_name: "", //创建人姓名
},
attachmentLimitType: ['zip', 'docx', 'doc', 'pdf', 'xlsx', 'xls','jpg', 'png', 'jpeg'], //文档限制类型
rules: {
title: [{
required: true,
message: '请输入标题',
// 可以单个或者同时写两个触发验证方式
trigger: ['change', 'blur'],
}]
},
}
},
onLoad(params) {
this.form.sys_org_code = this.vuex_org_code;
this.form.create_by = this.vuex_userName;
this.form.create_name = this.vuex_realname;
this.flag = params.flag; //1为新增,2为编辑
this.addOpt = params.addOpt;
//新增
if (params.flag == 1) {
uni.setNavigationBarTitle({
title: '新增'
})
} else {
//编辑
uni.setNavigationBarTitle({
title: '编辑'
})
this.id = params.id;
this.getDetail(params.id)
}
},
mounted() {
this.$refs.uForm.setRules(this.rules);
},
methods: {
//上传显示
uploaded(url) {
this.lists.push(url)
},
//获取细节详情
async getDetail(id) {
try {
let res = await wagePolicyApi.queryWagePolicyDetail(id);
console.log(res)
this.editorHtml = this.initHtml = res.policy_content.replace(/\http:.*?\upload/g, `${prefix}/upload`);
this.form.policy_content = res.policy_content.replace(/\http:.*?\upload/g, `${prefix}/upload`);
this.form.title = res.title;
//回显pdf
if (res.attachment_code) {
let files = res.attachment_code.split(',')
if (files.length > 0) {
this.lists = files;
}
}
} catch (err) {
console.log(err)
throw(e)
}
},
//提交表单
submit(html) {
this.$refs.uForm.validate(async valid => {
if (valid) {
//对正文内容进行判断
this.form.policy_content = html;
if (!this.form.policy_content) {
uni.showToast({
title: '请输入正文内容',
icon: 'none'
});
return
}
this.form.attachment_code= this.lists.join(',');
this.toApproval();
} else {
console.log('验证失败');
}
});
},
delfoc(index) {
// 删除文档
this.lists.splice(index, 1);
},
async toApproval() {
console.log('真实提交')
try {
let res, title
if (this.flag == 1) {
console.log(this.form, 'xxx');
res = await wagePolicyApi.addApprovalData(this.form);
title = '提交成功'
} else {
this.form['id'] = this.id;
res = await wagePolicyApi.editApprovalData(this.form);
title = '修改成功'
}
uni.showToast({
title,
duration: 2000
})
//跳转到列表页面
setTimeout(() => {
//跳转到列表页面
uni.navigateTo({
url: `/pages/wagePolicy/index?addOpt=${this.addOpt}`
})
}, 2000)
} catch (e) {
throw (e)
}
}
}
}
</script>
<script module="wagePolicyNew" lang="renderjs">
import wangEditor from '@/utils/wangEditor.js';
import {
UploadApi
} from '@/api/upload.js';
const uploadApi = new UploadApi();
import {
Config
} from '@/utils/config.js';
const config = new Config();
let prefix = config.getImgPdfUrl();
let editor;
export default {
beforeDestroy(){
editor.destroy();
},
mounted() {
editor = new wangEditor('#editH');
editor.config.showFullScreen = false;
editor.config.showLinkImg = false
editor.config.excludeMenus = [
'indent',
'code'
]
//编辑设置
if (this.flag !== 1) {
//设置初始化
editor.txt.html(this.initHtml);
}
editor.create();
//绑定wangEditor的插入图片和视频
editor.config.customUploadImg = async (resultFiles, insertImgFn) => {
// resultFiles 是 input 中选中的文件列表
// insertImgFn 是获取图片 url 后,插入到编辑器的方法
// 上传图片,返回结果,将图片插入到编辑器中
try {
let res = await uploadApi.uploadFileByJquery(resultFiles[0], 1);
console.log(res)
insertImgFn(prefix + res)
} catch (e) {
// uni.showToast({
// title: '上传图片失败',
// icon: 'none'
// });
throw (e)
}
};
//上传视频
editor.config.customUploadFile = async (file, i) => {
console.log(file, i);
console.log(URL.createObjectURL(file[0]), 'xx')
try {
let res = await uploadApi.uploadFileByJquery(file[0], 2);
console.log(res, 'res返回数据');
// 做上传
// 返回src
i(editor, prefix + res)
document.getElementsByClassName('w-e-panel-container')[0].style.diplay = none;
} catch (e) {
throw (e)
}
}
},
methods:{
submitToComp() {
this.$ownerInstance.callMethod('submit', editor.txt.html())
},
changeHtml(newValue, oldValue, ownerVm, vm) {
editor.txt.html(newValue)
}
}
}
</script>
<style lang="scss" scoped>
@import 'uview-ui/libs/css/style.components.scss';
.addOrEditMsg_wagePolicy {
background: #f5f6f8;
.form_flex_column /deep/ .u-form-item__body {
display: flex;
flex-direction: column !important;
}
.form_step {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 150rpx;
.form_step_left {
display: flex;
flex-direction: row;
align-items: center;
.form_dot {
width: 15rpx;
height: 15rpx;
border-radius: 50%;
background: #dadada;
margin-right: 34rpx;
}
.form_text {
display: flex;
margin-right: 34rpx;
flex-direction: column;
justify-content: space-around;
align-items: center;
height: 68rpx;
line-height: 0;
text:last-child {
color: #a9a9a9;
}
}
}
.form_step_right {
width: 60%;
height: 100%;
// display: flex;
flex-direction: row;
// align-items: center;
.form_step_right_show {
padding-top: 15rpx;
max-width: 80%;
float: right;
/deep/ .uni-scroll-view-content {
display: flex !important;
flex-direction: row;
// justify-content: flex-end;
}
.form_step_right_showImg {
display: flex !important;
flex-direction: row;
flex-wrap: nowrap;
.form_step_right_icon {
line-height: 75rpx;
color: #999;
margin: 0 10rpx;
}
&>view {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
image {
width: 70rpx;
height: 70rpx;
border-radius: 50%;
}
text {
margin-top: -15rpx;
color: #999;
}
.form_step_people_del {
position: absolute;
top: 5rpx;
right: 0;
width: 23rpx;
height: 23rpx;
font-size: 15rpx;
border-radius: 50%;
line-height: 15rpx;
text-align: center;
color: white;
background: black;
}
}
}
}
.form_step_right_add {
float: right;
margin-top: 15rpx;
width: 70rpx;
height: 70rpx;
border-radius: 50%;
margin-left: 10rpx;
text-align: center;
line-height: 65rpx;
font-size: 45rpx;
font-weight: 600;
color: #01a4e8;
border: 1px dashed #01a4e8;
}
}
}
.form_button {
width: 100%;
height: 120rpx;
background: white;
button {
width: 480rpx;
height: 85rpx;
background: #0383fb;
border: none !important;
border-radius: 10rpx;
color: white;
}
}
.hasTextarea /deep/ .u-form-item__body {
.u-form-item--right__content {
height: 880rpx;
}
.u-form-item--left__content {
flex: 0 0 138rpx;
}
.uni-input-placeholder {
top: 0 !important;
}
.u-input__input {
max-height: 170rpx !important;
}
.u-input {
text-align: left !important;
height: 170rpx;
// margin-right: 15rpx;
// text-indent: 22rpx;
}
}
.u-form-item {
margin-bottom: 14rpx;
font-size: 32rpx !important;
background: white;
padding: 15rpx 30rpx;
border: none;
line-height: none;
/deep/.u-form-item--left__content .u-form-item--left__content--required {
color: #fa3534;
left: 100% !important;
}
/deep/ .u-form-item--left {
width: auto !important;
flex: none !important;
margin-right: 36rpx;
}
/deep/ .u-input {
text-align: right !important;
}
// &:first-child /deep/ .uni-input-placeholder {
// left: -38rpx !important;
// }
/deep/ .uicon-arrow-down-fill:before {
position: absolute;
top: -28rpx;
font-size: 30rpx;
content: '>' !important;
}
}
.editH {
width: 100%;
height: 800rpx;
max-width: 700rpx;
z-index: 0;
// overflow-y: scroll;
/deep/ .w-e-toolbar .w-e-droplist {
left: -45px !important;
}
}
//弹出层样式
.toCommomApproval_modal {
.content {
// padding: 0 50rpx;
.content_top_button {
padding: 25rpx 50rpx;
border-bottom: 1rpx solid #F5F7F9;
font-weight: 500;
}
.content_main {
padding: 0 50rpx;
color: rgb(96, 98, 102);
.unitType {
padding: 25rpx 0;
border-bottom: 1rpx solid #F5F7F9;
}
}
}
}
.test {
width: 700rpx;
.wrap {
padding: 24rpx;
width: 100%;
.slot-btn {
width: 140rpx;
height: 140rpx;
display: flex;
justify-content: center;
// align-items: center;
line-height: 130rpx;
font-size: 60rpx;
background: rgb(244, 245, 246);
border-radius: 10rpx;
}
.slot-btn__hover {
background-color: rgb(235, 236, 238);
}
.pre-box {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
}
.pre-item {
width: 100%;
// border-radius: 10rpx;
// height: 140rpx;
overflow: hidden;
position: relative;
&>view {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
font-size: 30rpx;
text {
width: 90%;
}
image {
width: 30rpx;
height: 30rpx;
}
}
}
}
}
}
</style>
视频图片等富文本的回显 - 同样是利用renderjs,原生解析,与上传附件类似
<template>
<view :id="randomID" :richHtml="richHtml" :change:richHtml="richTextSelf.changeHtml" :randomID="randomID" :change:randomID="richTextSelf.changeRandomID">
</view>
</template>
<script>
export default {
name: 'rich-text-self',
props:{
id: '',
html: '',
},
data() {
return {
randomID: '',
richHtml: ''
};
},
mounted() {
this.randomID = 'richtextSelf' + parseInt(Math.random() * 10000)
this.richHtml = this.html
},
created() {
}
}
</script>
<script module="richTextSelf" lang="renderjs">
var container
var html
export default {
mounted() {},
methods: {
changeHtml(newValue, oldValue, ownerVm, vm) {
html = newValue
var div = document.createElement("DIV");
div.className = 'rich-text-self'
var reg = new RegExp('<video', 'g');
html = html.replace(reg, '<video style="width:100%;"')
div.innerHTML = "'" + html + "'"
var videos = document.getElementsByTagName('video', div)
if(videos && videos.length > 0){
videos.forEach(video => {
video.style.width = '100%'
})
}
var regImg = new RegExp('<img', 'g');
html = html.replace(regImg, '<img style="width:100%;"')
div.innerHTML = "'" + html + "'"
// var videos = document.getElementsByTagName('video', div)
// if(videos && videos.length > 0){
// videos.forEach(video => {
// video.style.width = '100%'
// })
// }
container.appendChild(div)
},
changeRandomID(newValue, oldValue, ownerVm, vm) {
container = document.getElementById(newValue)
}
}
}
</script>
6.实现下拉刷新
pages里面配置
{
"path": "pages/commonComponents/DynamicForm/index", //公共表单首页
"style": {
"enablePullDownRefresh": true, //可以下来刷新
"titleNView": {
"titleColor": "#ffffff",
"titleText": "",
"backgroundColor": "#186ff2"
},
"navigationStyle": "default",
"pullToRefresh": { //下来刷新样式
"support": true,
"style": "default",
"offset": "70px",
"color": "#007AFF",
"contentdown": {
"caption": ""//下拉可刷新自定义文本
}
}
}
},
页面进行监听
onPullDownRefresh(){
// console.log('onpull')
if(this.TabCur == 0){
uni.stopPullDownRefresh()
return
}
this.$nextTick(() => {
this.$refs.approvalDate.getList();
setTimeout(() => {
uni.stopPullDownRefresh()
})
})
},
如果还是不能实现,可以看看最后的那个文章,scroll-view和原生下拉刷新不能混动哦
7.实现分页(下拉下一页)
实现下拉下一页,主要就是下面这个监听回调-一旦到了底部,就page+1就行了
下面是实现得代码
//触底继续下拉刷新
onReachBottom() {
this.getList();
},
methods:{
//获取列表
async getList() {
//是否为最后一页
if (!this.isLastPage) {
this.loading = true
// console.log(this.policyParams, 'xxxx')
let res;
if (this.isAuth) {
res = await policyApi.qryQList(this.policyParams)
} else {
res = await policyApi.qryList(this.policyParams);
}
this.loading = false;
if (res.list && res.list.length > 0) {
this.favourable = this.favourable.concat(res.list);
this.policyParams.pageNum = res.nextPage;
this.isLastPage = res.isLastPage;
}
}
}
}
8.查看图片和富文本
主要是利用自带得两个api-uni.previewImage,uni.openDocument
export function searchPdf(url) {
if (url.includes('jpeg') || url.includes('jpg') || url.includes('png')) {
uni.previewImage({
urls: [url],
fail: () => {
console.log("预览图片失败", JSON.stringify(err))
uni.showToast({
title: '预览图片失败',
icon: 'none'
});
},
success(index, tapIndex) {
console.log("预览图片成功", index, tapIndex)
}
});
return
} else {
uni.showLoading({
icon: 'loading',
title: '正在打开,请等待'
});
uni.downloadFile({
url: url,
fail: () => {
uni.hideLoading()
uni.showToast({
title: '预览文件失败',
icon: 'none'
});
},
success: function(res) {
console.log(res, 'res')
var filePath = res.tempFilePath;
console.log(filePath, 'folefasa',filePath)
uni.openDocument({
filePath: filePath,
success: function(res) {
console.log("预览文件成功", res)
uni.hideLoading();
},
fail(err) {
console.log("预览文件失败", err)
uni.hideLoading();
uni.showToast({
title: '预览文件失败',
icon: 'none'
});
}
});
},
})
}
}
9.微信授权登录
超详细的uniapp实现微信登录功能_哆来A梦没有口袋的博客-优快云博客_uniapp 微信登录
10.APP检测是否是最新版本号
检查最新版本号,一般是在App.vue的onLauch生命周期,获取版本号并检测是否是最新版本号吗,提示用户是否需要更新
onLaunch: function() {
let that = this
//#ifdef APP-PLUS
plus.runtime.getProperty(plus.runtime.appid, function(wgtinfo) {
// 获取 app的version
let appversion = wgtinfo.version;
// 调取接口查询版本号
let url = 'http://222.180.163.242:9769'
uni.request({
url: `${url}/tsAdmin/wxApp/checkAppUpdate`,
method: 'GET',
success: (result) => {
if (result.data.code == 'rest.success') {
let info = result.data.result;
// 版本号不一致
if (info.versionText !== appversion) {
uni.showModal({ //提醒用户更新
title: "更新提示",
content: "已有新版本,请确认是否更新",
success: (res) => {
//点击确认
if (res.confirm) {
//浏览器打开下载地址
plus.runtime.openURL(`${url}/tsAdmin/wxApp/downloadApp?url=${info.path}`)
}
}
})
}
}
},
fail:(err)=> {
console.log(err,'err')
}
})
});
//#endif
11.分享
分享是常见的app的功能
官网对于分享的讲解很详细
这里讲一下其他的分享 - 微信小程序分享
微信的button加一个open-type="share",立即会实现分享功能,什么也不用写
<button class="toshare-button" open-type="share">
去分享
</button>
这样子的分享,会分享当前页面,有微信的默认样子
点击会自动进入分享页面
但是其实有时候我们分享出去的页面,想跳转的并不是当前点击页面,应该怎么做
可以监听点击分享
onShareAppMessage(res) {
return {
title: '分享注册就领现金红包,提现不设限,最高200元',
path: '/share/open'
}
}
这个时候在点击分享链接进入的就是path - share/open啦
12.H5中使用高德地图
uniapp使用H5高德地图_哆来A梦没有口袋的博客-优快云博客
13. H5中高德地图实现uni.chooseLcation
H5实现高德地图的uni.chooseLocation_哆来A梦没有口袋的博客-优快云博客
当然,uniapp还有一个小坑在里面。uniapp的那些坑_哆来A梦没有口袋的博客-优快云博客_uniapp的坑有哪些 ,这篇博客写了在项目中遇到的一些问题
文章持续更新中