项目架构方案
1.静态资源解决方案(图片、字体)
静态资源需要支持服务器地址或着本地地址配置,在config目录中新增assets.config.js文件,创建json对象,达到统一管理的目的,挂载到vue原型中:$assets,所有页面可以通过this. $assets.imgKey访问图片url。
css背景图片应尽量使用行内样式设置。
背景图片图片应用路径仅支持绝对路径,不支持相对路径,绝对路径~@/static/…
标签图片路径:
2.api集中管理
为简化逻辑代码量整洁的原则,像调用函数一样调用api,做到代码分离,在common目录创建http.js封装axios请求方法,在新建index.js中引入http.js,统一创建api函数,
并且封装接口返回数据类型校验的方法,页面通过引入接口函数调用
export function loginInfo(params) {
return get(constant.loginInfo, params)
}
调用:
import {loginInfo } from '@/api/index'
loginInfo({ name: name }).then(res => {
if (res.code === 0) {
loginUtils.setUserInfo(JSON.stringify(res.data))
state.commit(type.LOGIN, res.data);
localStorage.setItem('verify', res.data.verify)
localStorage.setItem('userId', res.data.userId)
let redirect = '/pages/video/gwList'
$mRouter.redirectTo({
route: {
name: "网关列表",
path: redirect
},
});
}
})
3.uni-app实现登陆拦截解决方案;
由于框架没有全局路由守卫函数,那么要实现登陆拦截需要在router目录中创建index.js封装路由api,在router目录中创建权限路由表routes.config.js,两者配合以达到路由跳转权限控制目的。
interceptor.js封装路由跳转拦截
// 全局路由钩子函数 对全局有效
$mRouter.beforeEach((navType, to) => {
console.log(to)
// let token = store.getters['login/token'];
const isWhite = checkWhiteList(to.route.path)
if (isWhite) {
codeLogin(to, 'next')
} else {
if (loginUtils.isLogin()) {
var query = ''
if (to.query) {
for (let key in to.query) {
query += (key + '=' + to.query[key] + '&')
}
}
if (env === 'production') {
Logintest().then(res => {
if (res.code === 0) {
uni.redirectTo({
url: to.route.path + '?' + query
})
} else if (res.code === -3) {
// uni.showToast({
// title: '登录失效,请重新登陆!',
// icon: 'none',
// duration: 2000
// });
setTimeout(function () {
codeLogin(to)
}, 500);
// if (!window.localStorage.getItem('checked')) {
// window.localStorage.getItem('pwd') ? window.localStorage.setItem('pwd', '') : ''
// window.localStorage.getItem('name') ? window.localStorage.setItem('username', '') : ''
// }
}
}).catch(err=>{
uni.showToast({
title: '登录失效,请重新登陆!',
icon: 'none',
duration: 2000
});
setTimeout(function() {
codeLogin(to)
}, 1500);
})
}else{
uni.redirectTo({
url: to.route.path + '?' + query
})
}
} else {
// 用户没有登录的情况下,跳转到 '/' 登录页面,允许用户正常跳转。
if(to.redirectedFrom == '/'){
codeLogin(to)
}else{
uni.showToast({
title: '登录失效,请重新登陆!',
icon: 'none',
duration: 2000
});
setTimeout(function () {
codeLogin(to)
}, 1500);
}
}
}
})
4.icon图标跨端通用解决方案。
统一使用字体图标库,跨端兼容好,也是官方推荐的,注意:字体文件太大建议做分割处理,避免加载过慢的情况。
引用阿里字体图标 main.js: import “./style/iconfont/iconfont.css”
5.pages目录分包管理
由于微信小程序的限制,上传发布机制总包大小不能大于2m,所以项目若超出该限制,要在page.json中做分包处理,分包处理的配置与pages目录保持一致。
6. AppEnterControll.js 应用的全局类,继承vue的所有方法。
场景:app入口控制,用户登陆。非页面自有方法。
中心思想:类似小程序app.js
7.采坑记录
- v-if在slot中慎用。
组件中与slot内容若同时出现v-if,会导致slot内容里的元素样式不生效。仅在H5复现。 - 不支持在组件上定义样式类名,各端互不兼容。
举例: 其中page的样式在ios的app中不生效。 - slot中使用v-for需要注意
场景:在一个popup组件中,在slot中通过v-for渲染数据列表,非H5端会出现空白。 - 点击popup中的列表某一项,选择后并关闭popup,在非H5端偶尔会出现关不掉的情况,暂未找到解决方案。