项目架构方案

1.静态资源解决方案(图片、字体)
静态资源需要支持服务器地址或着本地地址配置,在config目录中新增assets.config.js文件,创建json对象,达到统一管理的目的,挂载到vue原型中:$assets,所有页面可以通过this. $assets.imgKey访问图片url。

css背景图片应尽量使用行内样式设置。

背景图片图片应用路径仅支持绝对路径,不支持相对路径,绝对路径~@/static/…

标签图片路径:

UNICON 架构描述_封装


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端偶尔会出现关不掉的情况,暂未找到解决方案。