1. 介绍
uni-app
是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。
uni-app
在手,做啥都不愁。即使不跨端,uni-app
也是更好的小程序开发框架(详见)、更好的App跨平台框架、更方便的H5开发框架。不管领导安排什么样的项目,你都可以快速交付,不需要转换开发思维、不需要更改开发习惯。
2. 环境搭建
2.1 安装编辑器HBuilder X (APP开发版)
下载地址 通用前端开发工具,为uniapp做了特别强化
插件安装(工具 -> 插件安装 -> 选择插件下载
)
sass
git
-
npm
2.2 安装微信开发者工具
下载地址
3. 使用HBuilderX初始化项目
文件 -> 新建 -> uniapp项目
微信开发者工具端口开放 设置 -> 安全设置 -> 端口开启
4. 项目目录及作用
┌─components 符合vue组件规范的uni-app组件目录
│ └─comp-a.vue 可复用的组件
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用的本地静态资源(如图片、视频等)的目录,注意: 静态资源只能存放于此
├─uni_modules 存放uni_module规范的插件
├─wxcomponents 存放小程序组件的目录
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json 配置应用名称、appid、logo、版本等打包信息
└─pages.json 配置页面路由、导航条、选项卡等页面类信息
pages: 页面存放目录
static: 静态资源目录
unpackage: 打包输出目录
components: 组件存放目录
App.vue: 根组件,所有页面都在App.vue下进行切换,是页面入口文件,可以调用应用的生命周期函数。
main.js: 项目入口文件,初始化vue实例并使用需要的插件。
manifest.json: 应用的配置文件,用于指定应用的名称、图标、权限等。
pages.json: 对uni-app进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏以及底部tabbar等。
uni.scss: 预置了scss变量预置,方便整体控制应用的风格,比如按钮颜色、边框风格
开发规范:
页面文件遵循Vue单文件组件(SFC)规范
组件标签靠近小程序规范
接口能力靠近小程序规范
数据绑定及事件处理同Vue.js规范,同时补充了APP及页面规范生命周期
为兼容多端运行,建议使用flex布局进行开发
5. 全局配置和页面配置
pages.json 配置手册
globelStyle: 全局配置
pages: 页面配置 通过 pages 节点配置应用由哪些页面组成,pages 节点接收一个数组,数组每个项都是一个对象,其属性值如下:
tabbar: 导航栏配置 在App和小程序端提升性能。在这两个平台,底层原生引擎在启动时无需等待js引擎初始化,即可直接读取 pages.json 中配置的 tabBar 信息,渲染原生tab。
6. condition
启动模式配置,仅开发期间生效,用于模拟直达页面的场景,如:用户点击所打开的页面7. uni-app组件
搭建页面基础结构
-
视图组件 view
-
基础组件 text
-
表单组件 button
-
媒体组件 image
8. 样式设置
9. 数据绑定和事件绑定
同vue: v-bind\v-on
{{title}}
10. 生命周期
-
应用生命周期 仅可在
App.vue
中监听,在页面监听无效。 - 页面生命周期
11. 下拉刷新
11.1 开启下拉刷新
在pages.json
中加入下拉刷新属性,globalStyle为全局添加,page中为单页面添加
11.2 在页面中进行uni.startPullDownRefresh(OBJECT)
调用
官方文档查看 开始下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
11.3 监听下拉刷新
在页面生命周期中加入监听事件。当处理完数据刷新后,uni.stopPullDownRefresh
可以停止当前页面的下拉刷新。
onPullDownRefresh() {
console.log('刷新了');
uni.stopPullDownRefresh();
}
12. 网络请求
uni.request(Object)
13. 数据存储
-
异步存储
uni.setStorage(OBJECT)
将数据存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容uni.getStorage(OBJECT)
uni.removeStorage(OBJECT)
同步存储
uni.setStorageSync(KEY, DATA)
将 data 存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容
try {
uni.removeStorageSync('storage_key');
} catch (e) {
// error
}
uni.getStorageSync(KEY)
uni.removeStorageSync(KEY)
14. 图片上传预览
uni.chooseImage(OBJECT)
从本地相册选择图片或使用相机拍照。
uni.chooseImage({
count: 6, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: function (res) {
console.log(JSON.stringify(res.tempFilePaths));
}
});
uni.previewImage(OBJECT)
预览图片。
15. 条件编译跨端兼容
注释: #ifdef <端名>... #endif16. 导航跳转和传参
在起始页面跳转到test.vue页面并传递参数
uni.navigateTo({
url: 'test?id=1&name=uniapp'
});
在页面接受参数
export default {
onLoad: function (option) { //option为object类型,会序列化上个页面传递的参数
console.log(option.id); //打印出上个页面传递的参数。
console.log(option.name); //打印出上个页面传递的参数。
}
}
17. 组件创建、生命周期与父子组件传值
(同vue)
18. request封装(引用参考文章2)
var http = {
post(path, params, contentType = 'form', otherUrl, ) {
return new Promise((resolve, reject) => {
var url = (otherUrl || config.baseUrl) + path
if (!checkUrl(url)) {
rej('请求失败')
}
uni.request({
method: 'POST',
url,
header: {
"Content-Type": contentType === 'json' ? "application/json" :
"application/x-www-form-urlencoded"
},
data: params,
success: (res) => {
console.log('request:POST请求' + config.baseUrl + path + ' 成功', res.data)
resolve(res.data)
},
fail: (err) => {
message.toast('请求失败', 'err')
console.error('request:请求' + config.baseUrl + path + ' 失败', err)
reject('请求失败')
}
})
})
},
put(path, params, contentType = 'form', otherUrl, ) {
return new Promise((resolve, reject) => {
var url = (otherUrl || config.baseUrl) + path
if (!checkUrl(url)) {
rej('请求失败')
}
uni.request({
method: 'PUT',
url,
header: {
"Content-Type": contentType === 'json' ? "application/json" :
"application/x-www-form-urlencoded"
},
data: params,
success: (res) => {
console.log('request:PUT请求' + config.baseUrl + path + ' 成功', res.data)
resolve(res.data)
},
fail: (err) => {
message.toast('请求失败', 'err')
console.error('request:PUT请求' + config.baseUrl + path + ' 失败', err)
reject('请求失败')
}
})
})
},get(path, params, otherUrl) {
return new Promise((resolve, reject) => {
var url = (otherUrl || config.baseUrl) + path
if (!checkUrl(url)) {
return
}
uni.request({
url,
data: params,
success: (res) => {
console.log('request:GET请求' + config.baseUrl + path + ' 成功', res.data)
resolve(res.data)
},
fail: (err) => {
message.toast('请求失败', 'err')
console.error('request:GET请求' + config.baseUrl + path + ' 失败', err)
reject(err)
}
})})
},
delete(path, params, otherUrl) {
return new Promise((resolve, reject) => {
var url = (otherUrl || config.baseUrl) + path
if (!checkUrl(url)) {
return
}
uni.request({
url,
data: params,
method: "DELETE",
success: (res) => {
console.log('request:DELETE请求' + config.baseUrl + path + ' 成功', res.data)
resolve(res.data)
},
fail: (err) => {
message.toast('请求失败', 'err')
console.error('request:DELETE请求' + config.baseUrl + path + ' 失败', err)
reject(err)
}
})})
},
async upload(path, fileArray, otherUrl) {
if (typeof fileArray !== 'object') {
console.error('request:参数错误,请传入文件数组')
return
}
var url = (otherUrl || config.baseUrl) + path
if (!checkUrl(url)) {
return
}
var arr = []
for (let i in fileArray) {
const res = await uni.uploadFile({
url: otherUrl || config.baseUrl + path,
filePath: fileArray[i],
name: 'file'
})
console.log(res)
if (res[0]) {
console.error('request:上传失败', res[0])
return
}
arr.push(JSON.parse(res[1].data).data)
}
return arr
},}
function checkUrl(url) {
var urlReg = /((ht|f)tps?)://[\w-]+(.[\w-]+)+([\w-.,@?=%&:/+#]*[\w-@?^=%&/+#])?$/;
if (!urlReg.test(url)) {
console.error('request:请求路径错误' + url)
return false
}
return true
}
module.exports = http
19. 小程序打包发布
19.1 登录微信公众平台 -> 开发 -> 开发设置 -> 获取AppId放在manifest.json微信小程序配置的AppID中
19.2 Hbuilder中发行 -> 小程序-微信
19.3 微信开发者工具中点击上传 -> 上传
19.4 微信开发者平台 -> 版本管理 -> 选择提交的版本 -> 提交审核 -> 下一步填写信息 -> 提交审核 (-> 撤回审核)-> 审核成功 -> 上线
20. H5发布
20.1 HBuilder中进入manifest.json H5页面 -> 设置标题
20.2 HBuilder中点击发行 -> 网站-H5手机版
参考文章:
uniapp实现小程序微信登录
uniapp小程序开发的超长实践总结