混合App开发

混合App开发

概念:将写好的移动端页面,通过web view嵌套在App里面
注意:调用安卓方法传参是只能接受字符串,所以都需要通过JSON.stringify()转一下

获取安卓提供给H5的方法

  • 在安卓通过web view打开移动端网页时,会在window里面挂载提供给H5的方法
  • H5需要获取这些方法
	export class bridge_javaToJs{
    
    
		getUserInfo(){
    
    
			return window.App && windwo.App.getUserInfo()
		}
	}
  • 并将其挂载在Vue上
import Vue form 'vue';
import bridge_javaToJs from './bridge_javaToJs';
Vue.prototype.$app=new bridge_javaToJs();
  • 为方便判断是否在安卓情况下打开的H5页面,在main.js里追加状态判定
import Vue form 'vue';
window.vm=new Vue({
    
    
	data(){
    
    
		return {
    
    
			isApp:window.App,
		}
	}
})

隐藏DOM元素

安卓有可能只采用一半H5页面,也就是一半安卓,这样就需要对H5网页进行处理

  • 隐藏DOM元素,这是一种比较简单的方法,看安卓需要那些部分,对于不需要的就进行隐藏操作
  • 重写路由,为安卓重新配置路由,将需要的页面组合起来
    • 优点是只加载需要DOM元素
    • 缺点是涉及页面重构,还需要注意父子组件传值

路由拦截

  • 在路由拦截之前我们需要分清楚那些是App用到的页面,哪些不是
    • 因为对于H5页面跳往安卓原生页,需要调用安卓原生提供H5的方法
    • 而H5跳往H5页面依旧依靠VueRouter
      可以通过对路由meta里面添加信息来区分
const routes=[
	{
    
    
		path:'/home',
		name:'Home',
		component:Home,
		meta:{
    
    
			isAppPage:true,
		}
	},
	{
    
    
		path:'/home',
		name:'Home',
		component:Home,
		meta:{
    
    
			isAppPage:false,
		}
	}
]
  • 安卓对于返回执行的方法是不一样的,通过重写VueRouter的方法和定义router.options里面选项来判断是前进还是后退
import Vue form 'vue';
import VueRouter from 'vue-router';
// 获取原型对象上push方法
const originalPush=VueRouter.prototype.push;
// 修改对象中push方法
VueRouter.prototype.push=function push(location){
    
    
	// push是路由前进
	router.options.isForward=true;
	return originalPush.call(this,location).catch(err=>err)
}
// 获取原型对象上replace方法
const originalReplace=VueRouter.prototype.replace;
// 修改对象中push方法
VueRouter.prototype.replace=function replace(location){
    
    
	// replace是路由前进
	router.options.isForward=true;
	return originalReplace.call(this,location).catch(err=>err)
}
// 获取原型对象上go方法
const originalGo=VueRouter.prototype.go;
// 修改对象中go方法
VueRouter.prototype.replace=function replace(index){
    
    
	if(index>0){
    
    
		router.options.isForward=true;
	}else{
    
    
		router.options.isForward=false;
	}
	return originalGo.call(this,index)
}
Vue.use(VueRouter);
const routes=[
	{
    
    
		path:'/home',
		name:'Home',
		component:Home,
		meta:{
    
    
			isAppPage:true,
		}
	},
	{
    
    
		path:'/home',
		name:'Home',
		component:Home,
		meta:{
    
    
			isAppPage:false,
		}
	}
]
const router=new VueRouter({
    
    
	mode:'history',
	routes,
	isForward:false,
})
export default router;
  • 在路由前置守卫中,通过Vue.$router.options.isForward和meta.isAppPage条件执行不同跳转操作
export const routerBefore=(to,from,next)=>{
    
    
	const isApp=window.App;
	// 是在安卓环境下并且是去往App页面或者去的信息里面表明是要去App页面(主要是为了一些是H5的页面但是要求用App的方法打开)
	if(isApp && (to.meta.isAppPage||to.query.isAppPage)){
    
    
		// 判断vue是否加载好了或者是否是前进
		if(!vm || vm.$router.options.isForward){
    
    
			const url='xxxx';
			// 调用安卓方法跳转
			vm?vm.$app.adjustRouter(url):window.App.adjustRouter(url)
		}else{
    
    
			// 调用安卓方法回退
			vm.$app.nativeFallBack();
		}
		return;
	}else{
    
    
		// VueRouter操作
		next();
	}
}
  • 对于第一次进入就有掉安卓回退方法的页面需要进行特殊操作,否则回退将失效。原因在于history里面只有一条历史记录,在浏览器里只有一条历史记录调用go回退时回回退到浏览器主页,web view并没有主页,回退不会生效,VueRouter里面的前置路由守卫也不会被触发,页面也就不会跳转
  1. 解决方案,先在VueRouter里进行配置count参数,重写Router方法以此来记录路由次数
import Vue from "vue";
import VueRouter from "vue-router";

//获取原型对象上的push函数
const originalPush = VueRouter.prototype.push;
//修改原型对象中的push方法
VueRouter.prototype.push = function push(location) {
    
    
  router.options.isForward=true;
  router.options.count++;
  return originalPush.call(this, location).catch(err => err)
};
//获取原型对象上的replace函数
const originalReplace = VueRouter.prototype.replace;
//修改原型对象中的replace方法
VueRouter.prototype.replace = function replace(location) {
    
    
  router.options.isForward=true;
  router.options.count++;
  return originalReplace.call(this, location).catch(err => err)
};
//获取原型对象上的go函数
const originGo=VueRouter.prototype.go;
VueRouter.prototype.go=function(index){
    
    
  if(index>=0){
    
    
    router.options.count++;
    router.options.isForward=true;
  }else{
    
    
    router.options.count--;
    router.options.isForward=false;
  }
  return originGo.call(this,index);
}

Vue.use(VueRouter);

const router = new VueRouter({
    
    
  mode: "history",
  // base: process.env.BASE_URL,
  routes,
  isForward:false,
  count:0,
});
  1. 在需要后退的页面在后退前进行判断,如果是第一个页面,那么就不调用VueRouter方法,改为调用安卓原生提供的方法进行回退操作
<template>
	<button @click="goBack">返回</button>
</template>
<script>
export default {
      
      
 methods: {
      
      
 	goBack(){
      
      
 		if(this.$root.isNewApp && (window.history.length===1||this.$router.options.count===0)){
      
      
	        this.$app.nativeFallBack()
	        return;
      	}
      	this.$router.back()
 	}
 }
}
</script>

猜你喜欢

转载自blog.csdn.net/weixin_64925940/article/details/127198442