uni-app项目搭建
路由
request工具封装
UI组件如何引入
什么是uni-app
uni-app是一个使用Vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台。
为什么要选择uni-app
uni-app在开发者数量、案例、跨端抹平度、扩展灵活性、性能体验、周边生态、学习成本、开发成本等8大关键指标上拥有更强的优势。
怎么用uni-app创建项目
使用HBuilderX创建以uni-ui项目为模板的项目
注意点:
1 创建项目成功之后自助下载一些编译插件(内置终端,scss编译,uni-app编译各端,内置浏览器等等)
2 在下载插件如果出现下载失败或者安装失败的可以将插件的压缩包直接解压到HBuilderX的安装目录下面的plugins下面;如果是使用HBuilder安装插件失败 可以找到安装目录下->update->plugins下面的安装包直接解压到安装目录下->plugins下面即可
3 业务项目需要的插件或者依赖工具都可以在插件市场导入到项目中
如果是第一次运行小程序需要设置对应的小程序ide的安装路径以及设置小程序的AppId,如下图
使用vue-cli安装项目
vue create -p dcloudio/uni-preset-vue my-project
npm run dev:%PLATFORM%
npm run build:%PLATFORM%
复制代码
PLATFORM的参考值
值 | 平台 |
---|---|
app-plus | app平台生成打包资源(支持npm run build:app-plus,可用于持续集成。不支持run,运行调试仍需在HBuilderX中操作) |
h5 | H5 |
mp-alipay | 支付宝小程序 |
mp-baidu | 百度小程序 |
mp-weixin | 微信小程序 |
mp-toutiao | 字节跳动小程序 |
mp-qq | qq 小程序 |
mp-360 | 360 小程序 |
quickapp-webview | 快应用(webview) |
quickapp-webview-union | 快应用联盟 |
quickapp-webview-huawei | 快应用华为 |
开发规范
页面文件遵循 Vue 单文件组件 (SFC) 规范
组件标签靠近小程序规范,详见uni-app 组件规范uni-app 组件规范
接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 uni,详见uni-app接口规范
数据绑定及事件处理同 Vue.js 规范,同时补充了App及页面的生命周期
为兼容多端运行,建议使用flex布局进行开发
目录结构
┌─uniCloud 云空间目录,阿里云为uniCloud-aliyun,腾讯云为uniCloud-tcb(详见uniCloud)
│─components 符合vue组件规范的uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─hybrid App端存放本地html文件的目录,详见
├─platforms 存放各平台专用页面的目录,详见
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用的本地静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├─uni_modules 存放[uni_module](/uni_modules)规范的插件。
├─wxcomponents 存放小程序组件的目录,详见
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─h5.template.html h5的html模板
├─manifest.json 配置应用名称、appid、logo、版本等打包信息,详见
└─pages.json 配置页面路由、导航条、选项卡等页面类信息,详见
复制代码
Tips
编译到任意平台时,static 目录下的文件均会被完整打包进去,且不会编译。非 static 目录下的文件(vue、js、css 等)只有被引用到才会被打包编译进去。
static 目录下的 js 文件不会被编译,如果里面有 es6 的代码,不经过转换直接运行,在手机设备上会报错。
css、less/scss 等资源不要放在 static 目录下,建议这些公用的资源放在自建的 common 目录下。
HbuilderX 1.9.0+ 支持在根目录创建 ext.json、sitemap.json 等小程序需要的文件。
在我的之前的uniapp的项目中有用到两种方式来处理页面路由跳转
使用uni-app官方的api进行路由跳转,然后针对这几个api做一个二次封装模拟路由拦截
使用uni-simple-router来做路由管理
模拟路由跳转的封装官方跳转文档
const navigateTo = (params) => {
let token = uni.getStorageSync("token");
//别的操作
if(token){
//可以再做一次token校检
uni.navigateTo(params)
}else{
uni.redirectTo("login=?"+params.url)
}
}
const redirectTo = (params) => {
let token = uni.getStorageSync("token");
//别的操作
if(token){
//可以再做一次token校检
uni.redirectTo(params)
}else{
uni.redirectTo("login=?"+params.url)
}
}
const reLaunch = (params) => {
let token = uni.getStorageSync("token");
//别的操作
if(token){
//可以再做一次token校检
uni.reLaunch(params)
}else{
uni.redirectTo("login=?"+params.url)
}
}
const switchTab = (params) => {
let token = uni.getStorageSync("token");
//别的操作
if(token){
//可以再做一次token校检
uni.switchTab(params)
}else{
uni.redirectTo("login=?"+params.url)
}
}
const navigateBack = (params) => {
let token = uni.getStorageSync("token");
//别的操作
if(token){
//可以再做一次token校检
uni.navigateBack(params)
}else{
uni.redirectTo("login=?"+params.url)
}
}
const preloadPage = (params) => {
let token = uni.getStorageSync("token");
//别的操作
if(token){
//可以再做一次token校检
uni.preloadPage(params)
}else{
uni.redirectTo("login=?"+params.url)
}
}
module.exports = {
navigateTo,
redirectTo,
reLaunch,
switchTab,
preloadPage
}
复制代码
当然以上的封装为了可以方便使用,可以在main.js里面挂载到vue实例上或者直接使用mixin混入到app.vue组件中
uni-simple-router
一个更为简洁的Vue-router,专为 uni-app 量身打造
介绍
uni-simple-router
是专为 uni-app 打造的路由器。它与 uni-app 核心深度集成,使使用 uni-app 轻松构建单页应用程序变得轻而易举。功能包括:
H5端
能完全使用 vue-router
进行开发。
模块化,基于组件的路由器配置。
路由参数,查询,通配符。
H5端
查看由 uni-simple-router
过渡系统提供动力的过渡效果。
更细粒度的导航控制。
H端
自动控制活动的CSS类链接。
通配小程序端、APP端、H5端。
安装uni-simple-router
插件市场直接使用HBuilder导入
因为uni-simple-router官方文档推荐使用npm安装,HBuilder导入需要自己捣鼓;所以我在网上找了类似的案例, 找到一个可行方案如下!压缩包链接:uni-simple-router
目录如下
将压缩包解压到指定的目录下,我是创建了一个js_sdk的目录
创建router目录,这里面的路由声明以及路由拦截跟Vue-router用法是一模一样的;
router/index.js
import modules from './modules'
import Vue from 'vue'
import Router from '@/js_sdk/uni-simple-router/index.js'
Vue.use(Router)
//初始化
const router = new Router({
encodeURI:true,
routes: [...modules]//路由表
});
const whiteList = ['/pages/login/login']
//全局路由前置守卫
router.beforeEach((to, from, next) => {
let token='token';
if(token){
next()
}else{
if (whiteList.indexOf(to.path) !== -1) {
next()
}else{
next({ path: '/pages/login/login'})
}
}
})
// 全局路由后置守卫
router.afterEach((to, from) => {
console.log("afterEach")
})
export default router;
复制代码
main.js
import Vue from 'vue'
import App from './App'
import router from './common/router'
import {RouterMount} from './js_sdk/uni-simple-router/index.js'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
// #ifdef H5
RouterMount(app,'#app');
// #endif
// #ifndef H5
app.$mount(); //为了兼容小程序及app端必须这样写才有效果
// #endif
复制代码
npm安装,router使用方式跟vue是一样的
npm install uni-simple-router --save
复制代码
注意
router里面的页面路径一定要跟pages.json中pages的保持一致
常用API
Router 实例方法
router.beforeEach((to, from, next) => {
// `to` 和 `from` 都是路由对象
})
router.afterEach((to, from) => {
// `to` 和 `from` 都是路由对象
})
router.push({name:'tab1'})
router.replace({name:'tab1'})
router.replaceAll({name:'tab1'})
router.pushTab({name:'tab1'})
router.back(2,{
success:(...arg)=>{
console.log(arg)
}
})
复制代码
uni-app官方路由跳转方法'链接'
// 保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面。
// 2.8.9+ 支持
uni.navigateTo({
url: 'pages/test?id=1',
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function(data) {
console.log(data)
},
someEvent: function(data) {
console.log(data)
}
...
},
success: function(res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'test' })
}
})
// 关闭当前页面,跳转到应用内的某个页面。
uni.redirectTo({
url: 'test?id=1'
});
// 关闭所有页面,打开到应用内的某个页面
uni.reLaunch({
url: 'test?id=1'
});
// 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
uni.switchTab({
url: '/pages/index/index'
});
// 关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。
// 注意:调用 navigateTo 跳转时,调用该方法的页面会被加入堆栈,而 redirectTo 方法则不会。见下方示例代码
// 此处是A页面
uni.navigateTo({
url: 'B?id=1'
});
// 此处是B页面
uni.navigateTo({
url: 'C?id=1'
});
// 在C页面内 navigateBack,将返回A页面
uni.navigateBack({
delta: 2
});
// 预加载页面,是一种性能优化技术。被预载的页面,在打开时速度更快。
uni.preloadPage({url: "/pages/test/test"});
复制代码
在vue的项目中我们用的最多的是axios来作为前端http请求的工具,那么其实在uni-app中也是提供了这类api直接使用. 但是在实际项目中,我们为了代码易于维护并且减少我们的代码量,都会再做一次封装。那么下面我们看下对于request的封装 我们需要做哪些事情
因为没有axios的请求拦截api,所以我们需要在真正请求之前做一些全局的判断以及设置包括:
请求URL,自定义请求头,请求超时,是否登录,根据请求方式设置content-type,以及参数转义 2. 请求成功之后的成功 失败 以及无响应缺省操作 3. 返回给api请求的相应数据结构重组
import operate from '../common/operate.js' // 接口地址的域名
// vuex 的使用 详情参考官网 https://uniapp.dcloud.io/vue-vuex
import store from '../store/index.js'
export default class Request {
http(param) {
let token = store.getToken() || ""
if (!token) {
// 这里处理没有token认证逻辑
}
// 请求参数
var url = param.url,
method = param.method,
header = {},
data = param.data || {},
hideLoading = param.hideLoading || false;
//拼接完整请求地址
var requestUrl = operate.api + url;
//请求方式:GET或POST(POST需配置
// header: {'content-type' : "application/x-www-form-urlencoded"},)
if (method) {
method = method.toUpperCase(); //小写改为大写
if (method == "POST") {
header = {
'content-type': "application/x-www-form-urlencoded"
};
} else {
header = {
'content-type': "application/json"
};
}
}
//加载圈
if (!hideLoading) {
uni.showLoading({
title: '加载中...'
});
}
// 返回promise
return new Promise((resolve, reject) => {
// 请求
uni.request({
url: requestUrl,
data: data,
method: method,
header: header,
success: (res) => {
// 判断 请求api 格式是否正确
if (res.statusCode && res.statusCode != 200) {
uni.showToast({
title: "api错误" + res.errMsg,
icon: 'none'
});
return;
}
// code判断:200成功,不等于200错误
if (res.data.code) {
if (res.data.code != '200') {
uni.showToast({
title: "" + res.data.msg,
icon: 'none'
});
return;
}
} else {
uni.showToast({
title: "code!=200" + res.data.msg,
icon: 'none'
});
return;
}
// 将结果抛出
resolve(res.data)
},
//请求失败
fail: (e) => {
uni.showToast({
title: "" + e.data.msg,
icon: 'none'
});
resolve(e.data);
},
//请求完成
complete() {
//隐藏加载
if (!hideLoading) {
uni.hideLoading();
}
resolve();
return;
}
})
})
}
}
复制代码
在实际业务项目中经常会使用到第三方的插件,如果是用vue-cli安装的项目直接用npm安装然后引入使用就可以。但是如果是使用HBuilder创建的项目需要参考easycom的组件规范引入组件然后才能使用
easycom组件规范
传统vue组件,需要安装、引用、注册,三个步骤后才能使用组件。easycom将其精简为一步。只要组件安装在项目的components目录下或uni_modules目录下,并符合components/组件名称/组件名称.vue目录结构。就可以不用引用、注册,直接在页面中使用。
不管components目录下安装了多少组件,easycom打包后会自动剔除没有使用的组件,对组件库的使用尤为友好。
不满足easycom规范的组件如何使用
第一种方法:如果你的组件名称或路径不符合easycom的默认规范,
可以在pages.json的easycom节点进行个性化设置,自定义匹配组件的策略
"easycom": {
"autoscan": true, // 开启扫描
"custom": {
"^uni-(.*)": "@/components/uni-$1.vue", // 匹配components目录内的vue文件
"^vue-file-(.*)": "packageName/path/to/vue-file-$1.vue" // 匹配node_modules内的vue文件
}
}
复制代码
第二种方法: 直接采用vue的组件引用的方法也可以满足,组件安装 引用 注册
注意
easycom组件规范只能满足vue文件的组件,其他文件格式的组件无法满足