前期概述:做了很长时间的小程序了,在此做一个完整的项目总结,希望可以帮助到正在学习、开发的小伙伴。此篇文章并不涉及一些原理,更重要的是帮助大家实现功能、流程。
uniapp 还是很强大的 可以开发 小程序、h5、pc、app
启动小程序 最好现在uniapp中配置一下小程序的appid 否则可能会出现启动不了的情况
步骤:
1.微信公众平台查看自己的小程序id 开发 → 开发管理 → 开发设置 → 找到appid
2.在uniapp 中进行配置 目录下的manifest.json → 微信小程序配置 → 填写小程序appid
├── pages # 页面 (每个页面可以作为一个文件)
├── static # 静态资源 (图片、音视频)
├── unpackage # 打包文件
├── App.vue # 主文件(可以定义全局方法、样式、变量)
├── main.js # 入口 (引入插件)
├── pages.json # 页面路由
├── package.json # npm相关文件
└── uni.scss # 常用于定义全局样式变量、第三方ui库的样式(插件)
更多详细介绍:uni-app官网
每次想要在pages里新加一个页面 都要在pages.json里配置一下
下面列举一些常用 style 配置项,一般情况下足以开发 更多:uni-app官网
属性 | 类型 | 默认值 | 描述 | 平台差异说明 |
---|---|---|---|---|
navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色(同状态栏背景色),如"#000000" | |
navigationBarTextStyle | String | white | 导航栏标题颜色及状态栏前景颜色,仅支持 black/white | |
navigationBarTitleText | String | 导航栏标题文字内容 | ||
navigationStyle | String | default | 导航栏样式,仅支持 default/custom。custom即取消默认的原生导航栏,需看使用注意 | 微信小程序 7.0+、百度小程序、H5、App(2.0.3+) |
disableScroll | Boolean | false | 设置为 true 则页面整体不能上下滚动(bounce效果),只在页面配置中有效,在globalStyle中设置无效 | 微信小程序(iOS)、百度小程序(iOS) |
backgroundColor | HexColor | #ffffff | 窗口的背景色 | 微信小程序、百度小程序、字节跳动小程序、飞书小程序、京东小程序 |
2. App.vue
一般常用在app.vue里面使用的 onLunch、globalData、style
1.onLunch 只会在进入程序的时候执行一次,一般搭配搭建或等获取微信公众号的code ,想要app.vue调取methods 的方法记得用 getApp.方法名( )
2.globalData:常用于定义一些公共的变量、例如图片路径资源、手机是否是ios 或 安卓。 使用 :现在js中引入 1. import app from '@/App.vue' 2. platform: app.globalData.platform,
3.style 定义公共的全局样式 例如垂直水平居中、布局、公共类目样式都可以定义
uniapp: uView 2.0 - 全面兼容nvue的uni-app生态框架 - uni-app UI框架
如果 有功能不好去实现也可以去uniapp 的插件市场 DCloud 插件市场
原生小程序(扩展):Vant Weapp - 轻量、可靠的小程序 UI 组件库
函数名 | 说明 | 执行时机 | 使用场景 |
---|---|---|---|
onLoad | 监听页面加载,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参),参考示例 | 页面初始进入 | 只在初始化时使用一次 |
onShow | 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面 | 每次进入 | 需要每次更新数据 |
onReady | 监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发 | 页面初始进入onLoad、onShow之后 | 更多根据搭配插件使用 |
onHide | 监听页面隐藏 | 每次离开 | 更多于 记录一些数据 |
onUnload | 监听页面卸载 | 最后离开 | 卸载一些监听事件 |
onLoad 接受参数
A页面
toB(){
uni.navigateTo({
url:'/pages/index/b?name=奥特曼'
})
}
B页面接受参数
onLoad(e) {
console.log(e.name);
}
uni-app
组件支持的生命周期,与vue标准组件的生命周期相同。这里没有页面级的onLoad等生命周期 如果想要发送请求 可以在子组件的生命周期去执行
函数名 | 说明 | 平台差异说明 |
---|---|---|
beforeCreate | 在实例初始化之前被调用。详见(opens new window) | |
created | 在实例创建完成后被立即调用。详见(opens new window) | |
beforeMount | 在挂载开始之前被调用。详见(opens new window) | |
mounted | 挂载到实例上去之后调用。详见 (opens new window)注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTick Vue官方文档(opens new window) |
|
beforeUpdate | 数据更新时调用,发生在虚拟 DOM 打补丁之前。详见(opens new window) | 仅H5平台支持 |
updated | 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。详见(opens new window) | 仅H5平台支持 |
beforeDestroy | 实例销毁之前调用。在这一步,实例仍然完全可用。详见(opens new window) | |
destroyed | Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。详见(opens new window) |
官方文档:uni-app官网
"tabBar": {
"color": "#8a8a8a", //tab 上的文字默认颜色
"selectedColor": "#B88DFF", //tab 上的文字选中时的颜色
"borderStyle": "white", // tabbar 上边框的颜色,可选值 black/white
"backgroundColor": "#ffffff", //tab 的背景色
"list": [{
"pagePath": "pages/index",
"text": "主页",
"iconPath": "static/home.png",
"selectedIconPath": "static/homeCurrent.png"
},
{
"pagePath": "pages/forum_index",
"text": "逛逛",
"iconPath": "static/map.png",
"selectedIconPath": "static/mapCurrent.png"
},
{
"pagePath": "pages/shop_car",
"text": "购物车",
"iconPath": "static/shop.png",
"selectedIconPath": "static/shopcurrent.png"
},
{
"pagePath": "pages/my",
"text": "我的",
"iconPath": "static/mine.png",
"selectedIconPath": "static/mineCurrent.png"
}
]
},
如果想要实现自定义底部导航 可参考 UI库 解决自定义切换闪动 :微信小程序 自定义tabbar 防止闪动
扩展 页面栈 getCurrentPages() 的使用
页面栈:常用于获取当前页面之前的页面的参数及修改之前页面的数据
首选在A页面做一个 navigateTo 的跳转到B页面 然后打印一下 页面栈
const pages = getCurrentPages()
console.log(pages);
如果想要拿上一页面的值 会采用 拿到上页的页面参数
const pages = getCurrentPages()
console.log(pages[pages.length-2]);
h5端 和 小程序的参数是有一些区别的 如果想要修改某个页面栈里的值 只需要 对象 点就可以直接修改了
prevPage.title = 'hello World' // h5 修改
prevPage.$vm.title='hello World' // 小程序修改
使用场景 :购买商品时的地址切换(点击一项后 把上页的 地址替换掉)
除了调接口渲染列表 内容之外、剩下的可能就需要小程序提供的API 去实现一些功能、例如 微信授权登录、获取经纬度、设置位置信息、上传图片等。
一般的授权登录流程 大概是
1. 调用uni.login() 获取 code
2. 通过code调取后端接口获取 sessionkey 和 openId
3. 授权用户信息 获取后端需要的参数
4. 调用登录接口 存储token
demo:
微信授权登录
onLoad() {
this.getCode()
},
methods: {
//获取code
getCode() {
let that = this
uni.login({
provider: 'weixin',
success: function(res) {
console.log(res);
that.code = res.code
that.getSessionKey()
}
})
},
// code换seccesskey
async getSessionKey() {
let that = this
console.log(1)
try {
const res = await getSessionKey({
code: that.code
})
console.log('getSessionKey', res)
uni.setStorageSync("sessionkey", res.session_key)
uni.setStorageSync("openid",res.openid)
// 保存数据
} catch (err) {
uni.showToast({
title: err,
icon: 'none'
})
console.log('getSessionKey', err)
}
},
// 登录
async miniProgramLogin() {
let obj = {
session_key: uni.getStorageSync("sessionkey"),
iv: this.iv,
encryptedData: this.encryptedData,
openid: uni.getStorageSync("openid"),
}
try {
const res = await miniProgramLogin(obj)
console.log('miniProgramLogin', res)
uni.setStorageSync("token", res.token)
uni.setStorageSync("userInfo", res)
uni.navigateBack({})
} catch (err) {
uni.showToast({
title: err,
icon: 'none'
})
console.log('miniProgramLogin', err)
}
},
//登录操作
getlogin() {
//获取成功基本资料后开启登录,基本资料首先要授权
uni.getUserProfile({
desc: "获取你的昵称、头像、地区及性别",
success: res => {
this.iv = res.iv
this.encryptedData = res.encryptedData
this.miniProgramLogin() //授权成功可调用登录接口
},
fail: res => {
//拒绝授权 也可以再次获取最新的code
uni.showToast({
title: "您已拒绝登录",
icon: 'none',
duration: 2000
})
return;
},
})
},
},
在小程序中也有像浏览器的locationstorage一样
uni.setStorageSync('token',res.userinfo.token) // 存
uni.getStorageSync('token') // 取
uni.removeStorageSync('token') // 移除指定键
uni.clearStorageSync() // 清除所有缓存
uni.getLocation({
type: 'wgs84',
success: function (res) {
console.log(res);
console.log('当前位置的经度:' + res.longitude);
console.log('当前位置的纬度:' + res.latitude);
},
fail:function(err){
console.log(err);
}
});
常用的使用上面代码就好了,如果获取失败可以继续优化一下想要的操作
如果后台要根据 经纬度算距离记得type 改成 gcj02
wx.chooseLocation({
success: (data) => {
console.log(data, '位置数据')
}
})
data() {
return {
title: 'Hello',
polyline: [{
points: [{
longitude: 121.44577861,
latitude: 37.48205260
}, {
longitude: 121.44611657,
latitude: 37.48207388
}, {
longitude: 121.44725382,
latitude: 37.48224841
}, {
longitude: 121.44766152,
latitude: 37.48237186
}, {
longitude: 121.4475274100,
latitude: 37.4827039000
}, {
longitude: 121.44748986,
latitude: 37.48299336
}, {
longitude: 121.4476454300,
latitude: 37.4831679000
}, {
longitude: 121.4478063600,
latitude: 37.4831381000
}, {
longitude: 121.4479565600,
latitude: 37.4831295800
}, {
longitude: 121.4480263000,
latitude: 37.4831636400
}, {
longitude: 121.44820869,
latitude: 37.48330837
}],
color: "#ff0004dd",
width: 3,
// arrowIconPath: true,
// dottedLine:true
}],
covers: [{
id: 1,
longitude: 121.44820869,
latitude: 37.48330837,
width: 100,
height: 45,
}],
}
},
属性名 | 类型 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|
longitude | Number | 中心经度 | ||
latitude | Number | 中心纬度 | ||
scale | Number | 16 | 缩放级别,取值范围为3-20 | 高德地图缩放比例与微信小程序不同 |
theme | String | normal | 主题(satellite 或 normal)只在初始化时有效,不能动态变更(仅Android支持) | 京东小程序 |
min-scale | Number | 3 | 最小缩放级别 | App-nvue 3.1.0+、微信小程序2.13+ |
max-scale | Number | 20 | 最大缩放级别 | App-nvue 3.1.0+、微信小程序2.13+ |
layer-style | Number/String | 1 | 个性化地图 | App-nvue 3.1.0+、微信小程序2.13+ |
markers | Array | 标记点 | ||
polyline | Array | 路线 | 飞书小程序不支持 |
一般的使用场景 可能定位 现在的坐标,或者 做一些物流的路线
uni.chooseImage({
count: 6, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: function (res) {
console.log(JSON.stringify(res.tempFilePaths));
}
});
参数名 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
count | Number | 否 | 最多可以选择的图片张数,默认9 | 见下方说明 |
sizeType | Array |
否 | original 原图,compressed 压缩图,默认二者都有 | App、微信小程序、支付宝小程序、百度小程序 |
extension | Array |
否 | 根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。 | H5(HBuilder X2.9.9+) |
sourceType | Array |
否 | album 从相册选图,camera 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项 | |
crop | Object | 否 | 图像裁剪参数,设置后 sizeType 失效 | App 3.1.19+ |
success | Function | 是 | 成功则返回图片的本地文件路径列表 tempFilePaths | |
fail | Function | 否 | 接口调用失败的回调函数 | 小程序、App |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
一般 都是 通过选择图片后 拿到本地路径 再上传到服务器 获取 服务器链接图片
uniapp 上传文件 封装方法
参数名 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
current | String/Number | 详见下方说明 | current 为当前显示图片的链接/索引值,不填或填写的值无效则为 urls 的第一张 | |
urls | Array |
是 | 需要预览的图片链接列表 | |
indicator | String | 否 | 图片指示器样式,可取值:"default" - 底部圆点指示器; "number" - 顶部数字指示器; "none" - 不显示指示器。 | App |
loop | Boolean | 否 | 是否可循环预览,默认值为 false | App |
longPressActions | Object | 否 | 长按图片显示操作菜单,如不填默认为保存相册 | App 1.9.5+ |
success | Function | 否 | 接口调用成功的回调函数 | |
fail | Function | 否 | 接口调用失败的回调函数 | |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
预览要的是网络链接
let photoList = ['xx','xx']
uni.previewImage({
current: index,
urls: photoList
});
uni.requestPayment({
provider: 'wxpay',
timeStamp: res.payDetail.timeStamp,
nonceStr: res.payDetail.nonceStr,
package: res.payDetail.package,
signType: res.payDetail.signType,
paySign: res.payDetail.paySign,
success: function(res) {
console.log('支付成功')
},
fail: function(err) {
toa.toast('取消支付')
console.log('fail:' + JSON.stringify(err));
},
})
支付这点没什么太难的 直接调用wx的requestPayment 方法就好了 毕竟是在微信环境下 内部已经封装好啦
在uniapp 中有一个事件 onReachBottom (和methods同级) 当他触底时就可以去请求最新的数据
// 触底触发
onReachBottom() {
if(this.page >= this.lastPage) return
this.page=this.page+1
this.repairOrder()
},
上面的方法是 触底了 如果 当前页大于等于 最后一页 就return 停止执行 如果用scroll-view 请去官方文档看 scroll-view 的方法哈
uni.showToast(OBJECT)
参数 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
title | String | 是 | 提示的内容,长度与 icon 取值有关。 | |
icon | String | 否 | 图标,有效值详见下方说明。 | |
image | String | 否 | 自定义图标的本地路径(app端暂不支持gif) | App、H5、微信小程序、百度小程序 |
mask | Boolean | 否 | 是否显示透明蒙层,防止触摸穿透,默认:false | App、微信小程序 |
duration | Number | 否 | 提示的延迟时间,单位毫秒,默认:1500 | |
position | String | 否 | 纯文本轻提示显示位置,填写有效值后只有 title 属性生效, 有效值详见下方说明。 |
App |
success | Function | 否 | 接口调用成功的回调函数 | |
fail | Function | 否 | 接口调用失败的回调函数 | |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
常用
uni.hideToast() 隐藏弹框
uni.hideToast();
uni.showLoading(OBJECT)
显示 loading 提示框, 需主动调用 uni.hideLoading 才能关闭提示框。
参数 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
title | String | 是 | 提示的文字内容,显示在loading的下方 | |
mask | Boolean | 否 | 是否显示透明蒙层,防止触摸穿透,默认:false | H5、App、微信小程序、百度小程序 |
success | Function | 否 | 接口调用成功的回调函数 | |
fail | Function | 否 | 接口调用失败的回调函数 | |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
默认情况下是不允许分享的
需要添加两个方法
onShareAppMessage(){},
onShareTimeline(){}
默认清空下 分享的都是页面的默认配置项,如果想更改可以参考文档
参数名 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
title | String | 是 | 分享标题 | |
path | String | 是 | 页面 path ,必须是以 / 开头的完整路径。注意:京东小程序,开头不要加'/' | QQ小程序不支持 |
imageUrl | String | 否 | 分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径。支持PNG及JPG。显示图片长宽比是 5:4 | |
desc | String | 否 | 自定义分享描述 | 支付宝小程序、字节跳动小程序、京东小程序 |
bgImgUrl | String | 否 | 自定义分享二维码的背景图,建议大小750*950(网络图片路径) | 支付宝小程序 |
总结 以上是开发的一些基础方法等使用API 如果需要其他功能 还需自己去翻阅文档,遇到问题可以去搜一些文章、插件市场、官方企鹅群 希望可以帮着刚开发不久的小伙伴 ^_^