uni-app项目动态路由实践
# 动态替换tabbar
# 目前app端部分功能地图功能还没有实现兼容,要先屏蔽掉;
脚本运行启动前设置
"devApp": "yarn tabbar && cross-env NODE_ENV=development UNI_PLATFORM=app-plus VUE_APP_PLATFORM=app-plus vue-cli-service uni-build --watch",
"proApp": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus VUE_APP_PLATFORM=app-plus vue-cli-service uni-build --sourcemap",
"tabbar": "cross-env VUE_APP_PLATFORM=app-plus node scripts/build.js",
1
2
3
2
3
conf.js
const baseTabBar = [ {
"text": "首页",
"pagePath": "pages/home/index",
"iconPath": "static/image/tabbar/home.png",
"selectedIconPath": "static/image/tabbar/home-s.png"
},
{
"text": "水库",
"pagePath": "pages/reservoir/index",
"iconPath": "static/image/tabbar/reservoir.png",
"selectedIconPath": "static/image/tabbar/reservoir-s.png"
},
{
"text": "地图",
"pagePath": "pages/map/index",
"iconPath": "static/image/tabbar/map.png",
"selectedIconPath": "static/image/tabbar/map-s.png"
},
{
"text": "我的",
"pagePath": "pages/my/index",
"iconPath": "static/image/tabbar/my.png",
"selectedIconPath": "static/image/tabbar/my-s.png"
}]
const tabBarList = isApp ? baseTabBar.splice(2,1) && baseTabBar : baseTabBar
console.log("------tabBarList------", tabBarList);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
build.js
const {readFileSync, writeFileSync} = require('fs');
const {tabBarList} = require('../src/conf')
const path = require('path')
// const pathFile = '../src/pages.json';
console.log("-------__dirname-----",__dirname);
console.log("-------__filename-----",__filename);
const pathFile = path.join(__dirname, '..', 'src', 'pages.json')
console.log("-------pathFile-----",pathFile);
try {
const fileData = readFileSync(pathFile)
const jsonData = JSON.parse(fileData.toString())
console.log(jsonData.tabBar.list);
jsonData.tabBar.list = tabBarList
writeFileSync(pathFile, JSON.stringify(jsonData, null, " "))
console.log('----------全局配置tablist修改成功-------------');
} catch (error) {
console.error(error);
}
// fs.readFile(path, function(err, data) {
// if (err) return console.error(err);
// const jsonData = JSON.parse(data.toString())
// console.log(jsonData.tabBar.list);
// jsonData.tabBar.list = tabBarList
// fs.writeFile(path, JSON.stringify(jsonData, null, " "), function(err) {
// if (err) {
// console.error(err);
// }
// });
// });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 引入路由拦截后调整的部分
# 首页要设置默认/
要不然在第三方路口匹配不到数据;
{
"path": "pages/auth/index",
"name":"index",
"aliasPath":"/",
"meta":{
"title": "授权页"
},
"style": {
"navigationBarTitleText": "监管平台-授权中"
}
},
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
vue.conf.js中设置
new webpack.DefinePlugin({
ROUTES: webpack.DefinePlugin.runtimeValue(() => {
const tfPages = new TransformPages({
includes: ['path', 'name', 'meta', 'aliasPath']
});
console.log(tfPages.routes);
return JSON.stringify(tfPages.routes)
}, true )
}),
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 路径要设置为完整路径
# 路径参数不能传递对象str长字符串
# 原来的参数方式
//传
toReview() {
let itemObj = JSON.stringify(this.tempObj)
console.log('status:', this.detailObj.reviewStatus)
uni.navigateTo({
url: `/pagesubs/standardAssess/reservoir/typeTree?reviewStatus=${this.detailObj.reviewStatus}&resultId=${this.resultId}&itemObj=${itemObj}`
})
},
//接收
onLoad(options) {
uni.showToast({
icon: 'none',
title: this.currentTab
})
this.tempObj = JSON.parse(decodeURIComponent(options.itemObj))
this.reviewStatus = JSON.parse(decodeURIComponent(options.reviewStatus))
this.resultId = JSON.parse(decodeURIComponent(options.resultId))
if (this.reviewStatus > 30) {
this.edit = false
}
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 修改后的参数方式
- 传递参数时,对象要用
encodeURIComponent(JSON.stringify())
处理; - 接收参数时,解析直接用,不用再次解码处理;
//传
toReview() {
//let itemObj = JSON.stringify(this.tempObj)
let itemObj = encodeURIComponent(JSON.stringify(this.tempObj))
uni.navigateTo({
url: `/pagesubs/standardAssess/reservoir/typeTree?reviewStatus=${this.detailObj.reviewStatus}&resultId=${this.resultId}&itemObj=${itemObj}`
})
},
//接收
onLoad(options) {
uni.showToast({
icon: 'none',
title: this.currentTab
})
//this.tempObj = JSON.parse(decodeURIComponent(options.itemObj))
//this.reviewStatus = JSON.parse(decodeURIComponent(options.reviewStatus))
//this.resultId = JSON.parse(decodeURIComponent(options.resultId))
this.tempObj = options.itemObj
this.reviewStatus = options.reviewStatus
this.resultId = options.resultId
if (this.reviewStatus > 30) {
this.edit = false
}
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# app端返回监听处理
# 详见路由拦截和监听实现
# 多次返回退出
const router = createRouter({
// @ts-ignore
platform: process.env.VUE_APP_PLATFORM,
routes: [...ROUTES],
routerErrorEach: ({type,level,...args}) => {
console.log('---routerErrorEach---',type,level, args);
if(type===3){
router.$lockStatus=false;
if(isApp && level==1&&args.uniActualData.from==='backbutton') runtimeQuit()
}
else if(type===0){
router.$lockStatus=false;
}
},
});
router.beforeEach((to, from, next) => {
console.log('--beforeEach跳转开始--111--',to.path,from.path)
// showLoading('页面加载中')
// TODO:token权限判断,加白名单
let menuList = store.state?.user?.menuList
if (isEmpty(menuList)) menuList = menuListTree
if (!isEmpty(menuList)) {
//@ts-ignore hasRoute 先不处理
const hasRoute = findRoute(menuList, to) || to.meta?.forceShow
console.log('---beforeEach----hasRoute---',hasRoute);
}
next();
});
router.afterEach((to, from, ) => {
console.log('--afterEachh跳转结束--222--',to.path,from.path)
// hideLoading()
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 返回提示保存
beforeRouteLeave(to, from, next) {
//1.如果是在上传到场打卡图片或者隐患图片时点击则返回巡查页
// if (to.BACKTYPE === 'backbutton' && (to.name === 'reservoir' || to.name === 'reservoirList' || to.name === 'reservoirDetail' || to.name === 'preFloodInspect')) {
if ((to.name === 'reservoir' || to.name === 'reservoirList' || to.name === 'reservoirDetail' || to.name === 'preFloodInspect')) {
if(this.patrolReady === 2 || this.patrolReady === 3) {
this.patrolReady = 1
next(false);
return
}
var xcData = uni.getStorageSync("xcData");//巡查数据里的对象
if(xcData) {
var obj = xcData[this.resCode+'-'+this.dataType];
if(obj?.state == 'stop' ) {
next(false);
return
}
}
uni.showModal({
title: "确定退出巡查?",
content: "此操作将退出巡查,退出后可能会造成巡查数据丢失,请谨慎操作!",
success: (res) => {
if (res.confirm) {
next()
}else{
next(false)
}
}
})
}else{
next()
}
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# reLaunch/redirectTo跳转App延时
# 这两个方法,app端要做跳转延时处理;
/**
* redirectTo跳转页面 关闭当前页面,跳转到应用内的某个页面。
* @param {*} urlOrObj 地址
* @param {*} data 数据,url或者对象
* @param {*} isCheck 检查是否为空
* redirectTo app情况下一定要延时处理
*/
export function redirectTo(urlOrObj: any, data?: any, isCheck=true, timeOut=400){
const urlNew = checkUrlAndPram(urlOrObj, data, isCheck)
if (urlNew){
if (isApp) {
setTimeout(() => uni.redirectTo({url:urlNew}), timeOut);
} else {
uni.redirectTo({url:urlNew})
}
}else{
showToast('路径为空,请检查路径url!')
}
}
/**
* reLaunch跳转页面 关闭所有页面,打开到应用内的某个页面。
* @param {*} urlOrObj 地址
* @param {*} data 数据,url或者对象
* @param {*} isCheck 检查是否为空
* reLaunch app情况下一定要延时处理
*/
export function reLaunch(urlOrObj: any, data?: any, isCheck=true, timeOut=400){
const urlNew = checkUrlAndPram(urlOrObj, data, isCheck)
if (urlNew) {
if (isApp) {
setTimeout(() => uni.reLaunch({url:urlNew}), timeOut);
} else {
uni.reLaunch({url:urlNew})
}
}else{
showToast('路径为空,请检查路径url!')
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
上次更新: 2023/11/17, 05:08:20