使用HBuilderX构建支持多端平台编译的移动端商城项目。我们在开发中只需要做少部分的兼容性处理就可以将项目打包成支持各大小程序端、h5端和app端的项目。
在项目目录下的utils目录中创建config.js,并编写如下内容:
// 公共模块
let baseUrl = null; //域名
if(process.env.NODE_ENV == "development"){
baseUrl = "http://localhost:3000";// 开发版本api地址
}else{
baseUrl = "https://uapi.xqb.ink";// 生产版本api地址
}
export default baseUrl;
为了更好的管理项目中的业务数据请求,我们针对小程序端、h5端和app端做了请求层的封装,尽可能的提高请求代码的复用性,考虑到业务数据之间层层嵌套关系,通过promise封装请求方法解决回调地域问题,通过前段配置代理或后端允许跨域技术解决项目在h5端跨域的问题,通过平台检测技术动态控制测试和线上接口切换问题。
在项目目录下的utils目录中创建http.js,并编写如下内容:
// 封装请求方法
import baseUrl from "./config.js"
// 封装
const http = (options)=>{
return new Promise((resolve,reject)=>{
uni.request({
url:baseUrl+options.url,
data:options.data || {},
method:options.method || "get",
header:options.header || {
"content-type":"application/json"
},
success:resolve,
fail:reject
})
})
}
export default http;
在项目目录下的utils目录中创建api.js,并编写如下内容:
// 统一管理接口
// 引入http
import http from "./http.js";
//1. 获取一级分类
const _getcate = ()=>{
let options = {
url:"/api/getcate",
}
return http(options)
}
// 2.获取首页轮播图
const _getBanner = ()=>{
let options = {
url:"/api/getbanner"
}
return http(options)
}
// 3.获取秒杀活动
const _getSeckill = ()=>{
let options = {
url:"/api/getseckill"
}
return http(options)
}
// 4.获取首页数据
const _getIndexGoods = ()=>{
let options = {
url:"/api/getindexgoods"
}
return http(options)
}
// 5.获取一级分类下所有的商品
const _getCateGoodsPage = (data={})=>{
let options = {
url:"/api/getcategoodPage",
data,
}
return http(options)
}
// 6.获取所有的商品分类
const _getCates = ()=>{
let options = {
url:"/api/getcates",
}
return http(options)
}
// 7.获取制定商品详情信息
const _getGoodsInfo = (data={})=>{
let options = {
url:"/api/getgoodsinfo",
data,
}
return http(options)
}
// 8.获取制定商品详情信息
const _getPhoneCodeSms = (data={})=>{
let options = {
url:"/api/sms",
data,
}
return http(options)
}
// 9.执行登陆操作
const _wxlogin = (data={})=>{
let options = {
url:"/api/wxlogin",
data,
}
return http(options)
}
// 10.检测token是否过期
const _checkToken = (header={})=>{
let options = {
url:"/api/checktoken",
header,
}
return http(options)
}
// 11.插入购物车操作
const _cartAdd = (data={},header={})=>{
let options = {
url:"/api/cartadd",
data,
header,
}
return http(options)
}
// 12.获取购物车列表
const _cartList = (data={},header={})=>{
let options = {
url:"/api/cartlist",
data,
header,
}
return http(options)
}
// 13.购物车修改
const _cartEdit = (data={},header={})=>{
let options = {
url:"/api/cartedit",
data,
header,
}
return http(options)
}
// 14.购物车删除
const _cartDelete = (data={},header={})=>{
let options = {
url:"/api/cartdelete",
data,
header,
}
return http(options)
}
// 15.订单添加orderadd
const _orderAdd = (data={},header={})=>{
let options = {
url:"/api/orderadd",
data,
header,
}
return http(options)
}
// 16.查询所有的订单
const _orderList = (data={},header={})=>{
let options = {
url:"/api/orders",
data,
header,
}
return http(options)
}
export default {
_getcate,
_getBanner,
_getSeckill,
_getIndexGoods,
_getCateGoodsPage,
_getCates,
_getGoodsInfo,
_getPhoneCodeSms,
_wxlogin,
_checkToken,
_cartAdd,
_cartList,
_cartEdit,
_cartDelete,
_orderAdd,
_orderList
}
在项目目录的main.js中引入配置文件、接口文件等
//导入vue组件
import Vue from 'vue'
// 导入根组件app
import App from './App'
import api from "./utils/api.js"
Vue.prototype.$api = api;
import baseUrl from "./utils/config.js"
Vue.prototype.$baseUrl = baseUrl;
// 取消生产提示
Vue.config.productionTip = false
//指定根组件类型
App.mpType = 'app'
// 实例化vue组件
const app = new Vue({
...App
})
// 进行挂载
app.$mount()
我们整个项目以uniapp框架为基础,而uniapp框架底层基于vue.js开发思想,所以在整个开发中我们还是继续使用vue框架的mvvm模式,以组件化构建我们的业务页面,提高整个项目代码的复用率,同时便于多人协同开发和后期的项目维护升级。
uniapp中界面结构布局兼容了pc端的语法和移动端语法,我们为了保证多端能够更好的兼容适配采用官方的建议,页面结构使用微信小程序的组件构建,样式上采用移动端的flex弹性盒子布局和沿用css大部分的样式语法。
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 文字尺寸 */
$uni-font-size-sm:24upx;
$uni-font-size-base:28upx;
$uni-font-size-lg:32upx;
/* 图片尺寸 */
$uni-img-size-sm:40upx;
$uni-img-size-base:52upx;
$uni-img-size-lg:80upx;
/* Border Radius */
$uni-border-radius-sm: 4upx;
$uni-border-radius-base: 6upx;
$uni-border-radius-lg: 12upx;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 10px;
$uni-spacing-row-base: 20upx;
$uni-spacing-row-lg: 30upx;
/* 垂直间距 */
$uni-spacing-col-sm: 8upx;
$uni-spacing-col-base: 16upx;
$uni-spacing-col-lg: 24upx;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:40upx;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:36upx;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:30upx;
在用户请求业务数据时采用JWT验证方式,验证用户的身份有效性,保证用户私密数据的准确性和安全性。
示例代码:
// 检测是否登陆
let _checkTokenStatus = async (token=null,_this=null)=>{
if (!token) {
uni.setTabBarItem({
index: 2, //位置
text: "未登录"
})
return false;
}
// 1.检测是否过期
let result = await _this.$api._checkToken({
authorization: token
})
if (result.data.code == 403) {
//失效了。或者token错误
uni.setTabBarItem({
index: 2, //位置
text: "未登录"
})
// token失效,清楚缓存
uni.clearStorage();
return false;
} else if (result.data.code == 200) {
//正常
uni.setTabBarItem({
index: 2, //位置
text: "我的"
})
return true;
} else {
// 未知错误
}
}
export default _checkTokenStatus;