update
迁移文档 小爱为你推荐使用新版本哦~~

# 提前享用生命周期 V 2.0.8+

通过代理和重写的手段将需要的生命周期进行包装,从而达到可提现享用生命周期。它的好处在于可以让我们对实际生命周期拥有完全控制权,实现异步、自定义参数、轻而易举。

# 出现原因

考虑到一些老项目需要集成 uni-simple-router,在参数的获取上会有较大的改动,同时为确保插件不做过多改动的情况下,实现这样一个提前享用生命周期的方案。下面我来逐步讲解他的使用及强大!

# 使用插件前的获取方式

  • 页面1
<template>
	<view class="content">
		<button type="default" @click="goToPage">去页面2</button>
	</view>
</template>

<script>
	export default {
		methods: {
			goToPage(){
				uni.navigateTo({
					url:`/pages/page2/page2?name=hhyang&ages=23&msg=你好`
				})
			}
		}
	}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  • 页面2
<template>
	<view>
		<h2>页面2</h2>
	</view>
</template>

<script>
	export default {
		onLoad(options){
			console.log(options)     // {name: "hhyang", ages: "23", msg: "你好"}
		},
		onShow(options){
			console.log(options)    // undefined
		}
	}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

我们使用uni-app原始API带不同参数跳转到页面2下,通过onLoadonShow及打印参数。官方告诉我们只能通过 onLoad 才能接受参数,不出所料,我们尝试的结果如下,仅只能在 onLoad 中才能获取参数。而onShow 中输出 undefined普通参数能满足我们的要求,但如果我们需要传递深度对象参数则需要先编码再传递再解码。

15:31:59.217 page2.js?  {name: "hhyang", ages: "23", msg: "你好"}
15:31:59.218 page2.js?  undefined
1
2

# 使用插件后的获取方式

  • 页面1
<template>
	<view class="content">
		<button type="default" @click="goToPage">去页面2</button>
	</view>
</template>

<script>
	export default {
		methods: {
			goToPage(){
                uni.navigateTo({
					url:`/pages/page2/page2?name=hhyang&ages=23&msg=你好`
				})
			}
		}
	}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  • 页面2
<template>
	<view>
		<h2>页面2</h2>
	</view>
</template>

<script>
	export default {
		onLoad(options){
			console.log(options)  // {name: "hhyang", ages: "23", msg: "%E4%BD%A0%E5%A5%BD"}
            console.log(this.$Route.query)  // {name: "hhyang", ages: "23", msg: "你好"}
		},
		onShow(options){
			console.log(options)    // undefined
            console.log(this.$Route.query)  // {name: "hhyang", ages: "23", msg: "你好"}
		}
	}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

可以看出使用插件的获取方式更方便,更容易管理。当加入插件后,每次跳转都会解锁所有的参数,并对中文字符及特殊字符进行编码处理。所以在onLoad下打印的参数是编码后的参数,无法正确还原到编码前。仅使用 this.$Route.query 才能正确解析,深度传参亦是如此。

# 默认对 onLoad 参数处理

v2.0.8 起插件内部默认支持对 onLoad 参数进行解码处理,当然你也可以自定义它。下面的例子是使用 v2.0.8 版本的插件

  • 页面1
<script>
	export default {
		methods: {
			goToPage(){
                uni.navigateTo({
					url:`/pages/page2/page2?name=hhyang&ages=23&msg=你好`
				})
			}
		}
	}
</script>
1
2
3
4
5
6
7
8
9
10
11
  • 页面2
<script>
	export default {
		onLoad(options){
			console.log(options)  // {name: "hhyang", ages: "23", msg: "你好"}
            console.log(this.$Route.query)  // {name: "hhyang", ages: "23", msg: "你好"}
		},
		onShow(options){
			console.log(options)    // undefined
            console.log(this.$Route.query)  // {name: "hhyang", ages: "23", msg: "你好"}
		}
	}
</script>
1
2
3
4
5
6
7
8
9
10
11
12

注意:默认的 onLoad 参数处理器受 parseQuery 的影响

# 动态改变参数

  • 下面的例子是同时让 onLoad 及 onShow 支持 options




 
 
 
 
 
 
 
 
 
 






























// router.js
const router = createRouter({
	platform: process.env.VUE_APP_PLATFORM,  
	routes: [...ROUTES],
	beforeProxyHooks: {
		onLoad(options, next){
			next([router.currentRoute.query]);
		},
		onShow([options], next){
			console.log(this);
			const args=options||router.currentRoute.query;
			next([args]);
		},
	},
});

// page1.vue
<script>
	export default {
		methods: {
			goToPage(){
                uni.navigateTo({
					url:`/pages/page2/page2?name=hhyang&ages=23&msg=你好`
				})
			}
		}
	}
</script>


// page2.vue
<script>
	export default {
		onLoad(options){
			console.log(options) // {name: "hhyang", ages: "23", msg: "你好"}
			console.log(this.$Route.query)  // {name: "hhyang", ages: "23", msg: "你好"}
		},
		onShow(options){
			console.log(options);   // {name: "hhyang", ages: "23", msg: "你好"}
			console.log(this.$Route.query)  // {name: "hhyang", ages: "23", msg: "你好"}
		} 
	}
</script>
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
40
41
42
43

你还可以用更多匹配规则完成生命周期代理,记住在 beforeProxyHooks 中的 onLoad 相对于页面 onLoad 是父级,而页面 onLoad 则为子级。 只有在父级中调用 next 后才会执行页面的对应生命周期,否则不会执行页面生命周期,同时在父级生命周期中也可以访问 this父级返回参数及回调参数见文档

# 异步生命周期

这意味着你可以在父级生命周期下执行异步操作,达到指定目的后执行 next 即可马上执行页面生命周期。注意:异步生命周期会打乱现有生命周期的顺序

  • router.js
// router.js
const cacheUserInfo={};
const getData=function(){
	return new Promise(resolve=>{
		if(Object.keys(cacheUserInfo).length>0){
			return resolve(cacheUserInfo);
		}
		setTimeout(()=>{
			Object.assign(
                cacheUserInfo,
                {
                    name:'hhyang',
                    ages:23
                }
            )
			resolve(cacheUserInfo)
		},2000)
	})
}

const router = createRouter({
	platform: process.env.VUE_APP_PLATFORM,  
	routes: [...ROUTES],
	beforeProxyHooks: {
		onLaunch:async ([options], next)=>{
			const result=await getData();
			next([{
				...options,
				...result
			}])
		},
	},
});
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
  • App.vue
// App.vue
<script>
	export default {
		onLaunch: function(options) {
			console.log(options)
		},
		onShow: function() {
			console.log('App onShow')
		},
	}
</script>
1
2
3
4
5
6
7
8
9
10
11

不单仅限于此,你还可以实现多个生命周期之间进行关联!