为了性能(更多的是ios能共审核上架通过)需要把js打包到客户端本地,这个时候就需要实现一个比较灵活的js加载机制了。
思路:通过第一个加载的js的路径来决定后续js的加载根路径。
比如第一个js 来自 http://xxx.com/weex/xxx.js,那么后面的js都从这个域名下的 weex目录来,uri可以通过写一个nativeRouter的配置来做到和一致的调用。
vue router
这个我是为了和原生的路由配置做一个统一,所有这样写,在用的时候还要做一个转换
通用jump方法实现
/**
* 返回
* @param callback
*/
back: function (callback) {
if (this.web) {
this.$router.back();
} else {
this.newNavigator.pop({animated: true}, () => {
if (commonUtils.isNullOrUndefined(callback) || callback.constructor !== Function) {
return;
}
callback();
});
}
},
/**
* 跳转
* @param url 跳转的目标url
* @param params 请求参数
* @param isPopSelf 是否清除自身url(仅支持原生)
* @param callback 回调函数(仅支持原生)
*/
jump(url = "", params = {}, isPopSelf = false, callback = () => {
}) {
if (!this.web) {
let routerKey = url.split("?")[0].substr(1, url.length);
const nativeRoute = this.getNativeRoute();
let route = nativeRoute[routerKey]; //尝试从路由配置中获取
console.log(route);
console.log(url);
let gotoURL = "";
if (commonUtils.isNullOrUndefined(route)) {
//未获取到改配置,则通过工具类获取该js的地址
gotoURL = weexGetPathUtils.getNativeGoToURL(url, weex);
route = {
path: "",
meta: {}
};
} else {
let baseURL = this.getBasePath(); //获取根目录地址
gotoURL = baseURL + route.url;
}
const {main, requireAuth} = Object.assign({main: false, requireAuth: false}, route.meta);
if (requireAuth) {
//需要登陆 检查登陆
if (!this.isLogin()) {
//未登录 跳到登陆页面
this.jump("/login?redirect=" + url);
return;
}
}
if (route.path.indexOf(":") > 0) {
//存在参数
//仅支持单个参数的解析
let split = route.path.split(":");
let paramsKey = split[1];
let value = url.replace(split[0], "");
let p = {};
p[paramsKey] = value;
params = Object.assign({}, params, p);
}
this.openWeexByNative(gotoURL, main, params, callback);
if (isPopSelf && this.android) {
//清除自己的堆栈,防止点击返回时回到该页面
console.log("清除自己的堆栈,防止点击返回时回到该页面");
this.newNavigator.pop({
animated: true
});
}
} else {
if (!this.$router) {
console.log("vue-router 未实例化!");
return;
}
if (url.indexOf("/") !== 0) {
//不是绝对地址
url = weexGetPathUtils.getWebGoToURL();
}
if (commonUtils.isNullOrUndefined(params)) {
this.$router.push(url);
} else {
console.log(params);
this.$router.push({path: url, query: params});
}
}
},
/**
* 直接打开远程的weex页面 (仅支持原生调用)
* @param url
* @param main 是否为主页
* @param params
* @param callback
*/
openWeexByNative(url, main = false, params = {}, callback = () => {
}) {
if (url.indexOf("?") < 0) {
url += "?";
}
let i = 0;
//构建参数
for (let key in params) {
url += key + "=" + params[key] + "&";
i++;
}
if (i > 0) {
url = url.substr(0, url.length - 1);
}
let gotoURL = "weex://" + packageName + (main ? "/main/" : "/page/") + url;
this.newNavigator.push({
url: gotoURL,
animated: "true"
}, event => {
callback();
});
},
/**
* 获取参数
* @param keys 参数的名称列表 例如 ["id","name"]
* @param useQuery 是否使用查询字符串参数
* @return {*}
*/
getParams(keys, useQuery = true) {
let params = {};
let length = keys.length;
if (!this.web) {
const bundleUrl = weex.config.bundleUrl;
const queryStr = bundleUrl.split("?")[1]; //获取查询字符串
if (queryStr === undefined || queryStr.trim().length === 0) {
//如果不存在查询字符串则直接返回
return params;
}
let list = queryStr.split("&");
list.forEach(function (item) {
let p = item.split("=");
params[p[0]] = p[1];
});
console.log("参数-->" + JSON.stringify(params));
} else {
const self = this;
if (length > 1 || useQuery === true) {
keys.forEach((key) => {
//多个参数使用query对象传递
params[key] = self.$route.query[key];
});
} else {
params[keys[0]] = self.$route.params[keys[0]];
}
}
if (length === 1) {
return params[keys[0]];
}
return params;
},
/**
* 获取base path 路径
* @param uri 非必填,若传入则放回完整url
* @return String
*/
getBasePath(uri = null) {
let basePath = weexUtils.getBasePath(weex);
if (uri === null) {
return basePath;
} else {
return basePath + uri;
}
},
这样不论在web端还是原生,不管js是在远程还是在本地都是统一的调用 this.jump(“/xxx”,{id:xxx});