使用Weex navigator模块
second.vue
<template>
<div>
<text style="font-size: 20wx">Hellow World!21</text>
<image src="local:///weex_logo" style="width: 640px; height: 302px"></image>
<image src="https://gw.alicdn.com/tfs/TB1yopEdgoQMeJjy1XaXXcSsFXa-640-302.png" style="width: 64px; height: 64px"></image>
<text style="padding: 32px; background-color: red; font-size: 15wx; color: white" @click="onTextClick">测试跳页.....</text>
</div>
</template>
<script>
var navigator = weex.requireModule('navigator')
export default {
methods : {
onTextClick: function () {
navigator.push({
url: 'http://192.168.31.79:8081/dist/three.js',
title: '新页面',
animated: "true",
params: {
id: 11111
}
})
}
}
}
</script>
Three.vue
<template>
<div style="align-items: center; justify-content: center">
<text style="font-size: 18wx">这是个新页面</text>
<text>{{id}}</text>
</div>
</template>
<script>
export default {
data() {
return {
id: weex.config.id
}
}
}
</script>
从网络端加载js文件,实现动态更新
Android 端
每个Activity页面打开一个单独的js, 使用原生渲染, 不使用webview加载网页
编译vue文件
使用weex compile 编译vue文件为js文件, 添加-m参数压缩js文件
weex compile src dist -m
封装通用的activity,使用不同的url
借助路由框架,我这里使用的是 ARouter, 也可以使用别的
@Route(path = "/weex/activity")
public class WeexPageActivity extends AppCompatActivity implements IWXRenderListener{
WXSDKInstance mWXSDKInstance;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWXSDKInstance = new WXSDKInstance(this);
mWXSDKInstance.registerRenderListener(this);
String url = getIntent().getStringExtra("url");
String title = getIntent().getStringExtra("title");
String params = getIntent().getStringExtra("params");
//设置标题...
Map<String, Object> options = new HashMap<>();
JSONObject json = JSON.parseObject(params);
Set<String> keys = json.keySet();
for(String key : keys){
options.put(key, json.getString(key));
}
mWXSDKInstance.renderByUrl("com.xy.weex", url, options, null, WXRenderStrategy.APPEND_ASYNC);
}
@Override
public void onViewCreated(WXSDKInstance instance, View view) {
setContentView(view);
}
@Override
public void onRenderSuccess(WXSDKInstance instance, int width, int height) {
}
@Override
public void onRefreshSuccess(WXSDKInstance instance, int width, int height) {
}
@Override
public void onException(WXSDKInstance instance, String errCode, String msg) {
}
@Override
protected void onResume() {
super.onResume();
if(mWXSDKInstance!=null){
mWXSDKInstance.onActivityResume();
}
}
@Override
protected void onPause() {
super.onPause();
if(mWXSDKInstance!=null){
mWXSDKInstance.onActivityPause();
}
}
@Override
protected void onStop() {
super.onStop();
if(mWXSDKInstance!=null){
mWXSDKInstance.onActivityStop();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mWXSDKInstance!=null){
mWXSDKInstance.onActivityDestroy();
}
}
}
实现 Seettt 接口, 重写push方法
public class WeexActivityNavBarSetter implements IActivityNavBarSetter {
@Override
public boolean push(String s) {
JSONObject json = JSON.parseObject(s);
String url = json.getString("url");
JSONObject params = json.getJSONObject("params");
if(url.startsWith("http") && url.endsWith(".js")){
ARouter.getInstance().build("/weex/activity")
.withString("url", url)
.withString("title", json.getString("title"))
.withString("params", JSON.toJSONString(params))
.navigation();
return true;
}
return false;
}
@Override
public boolean pop(String s) {
return false;
}
@Override
public boolean setNavBarRightItem(String s) {
return false;
}
@Override
public boolean clearNavBarRightItem(String s) {
return false;
}
@Override
public boolean setNavBarLeftItem(String s) {
return false;
}
@Override
public boolean clearNavBarLeftItem(String s) {
return false;
}
@Override
public boolean setNavBarMoreItem(String s) {
return false;
}
@Override
public boolean clearNavBarMoreItem(String s) {
return false;
}
@Override
public boolean setNavBarTitle(String s) {
return false;
}
}
设置 Setttt 类
public class BaseApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ARouter.init(this); // 尽可能早,推荐在Application中初始化
InitConfig config = new InitConfig.Builder()
.setImgAdapter(new WeexImageAdapter())
.build();
WXSDKEngine.initialize(this, config);
WXSDKEngine.setActivityNavBarSetter(new WeexActivityNavBarSetter());
}
}
好了, 可以运行程序看看效果,可以在push方法中打断点,查看参数值,
可以自行设定参数,处理各种情况,比如右上角添加菜单,拦截back返回事件,更换标题颜色等
Web端
使用路由跳转页面
变更启动页入口
entry.js
/*global Vue*/
/* weex initialized here, please do not move this line */
const router = require('./router');
const App = require('@/index.vue');
/* eslint-disable no-new */
new Vue(Vue.util.extend({el: '#root', router}, App));
router.push('/second');
定义路由
router.js
/*global Vue*/
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Second from '@/second.vue'
import Three from '@/three.vue'
Vue.use(Router)
module.exports = new Router({
routes: [
{path: '/', name: 'HelloWorld', component: HelloWorld},
{path: '/second', name: 'Second', component: Second},
{path: '/three', name: 'Three', component: Three}
]
});
重新运行 npm start 命令, 点击按钮试试效果, 会发现可以看到three.js文件内容,并没有渲染,这不是我想要的结果, 接着修改下second.vue里的onTextClick 方法
onTextClick: function () {
if(weex.config.env.platform == 'Web'){
console.log(this.$router);
this.$router.push('/three')
}else{
navigator.push({
url: 'http://192.168.31.79:8081/dist/second.js',
title: '新页面',
animated: "true",
params: {
id: 11111
}
})
}
}
等编译完成,重新点击按钮看看,会发现达到了我想要的结果,渲染出three.vue里的内容了, 接下来看下使用vue router 怎么传递参数
//this.$router.push('/three')
this.$router.push({name:'Three',params: {id : 11111} })
修改three.vue
<template>
<div style="align-items: center; justify-content: center">
<text style="font-size: 18wx">这是个新页面</text>
<text>{{id}}</text>
<text>{{ids}}</text>
</div>
</template>
<script>
export default {
data() {
return {
id: weex.config.id,
ids : this.$route.params
}
}
}
</script>
刷新看看效果,参数也拿到了
至此,就实现了 Web 端 和 Android 端的页面跳转, 可是并不完美,不同的终端需要加判断才能区分,接下来继续改进,统一写法,实现相同的效果
扩展 Web 端 weex module
在入口文件entry.js中注册 webNavigator
/*global Vue*/
/* weex initialized here, please do not move this line */
weex.registerModule('webNavigator', {
push (params) {
// 打印出 this, 观察 $router在那,获取
this._root['wx-root-0'].$router.push(params);
}
})
const router = require('./router');
const App = require('@/index.vue');
/* eslint-disable no-new */
new Vue(Vue.util.extend({el: '#root', router}, App));
router.push('/second');
修改 second.vue, 引用webNavigator, push参数中添加name
<template>
<div>
<text style="font-size: 20wx">Hellow World!21</text>
<image src="local:///weex_logo" style="width: 640px; height: 302px"></image>
<image src="https://gw.alicdn.com/tfs/TB1yopEdgoQMeJjy1XaXXcSsFXa-640-302.png" style="width: 64px; height: 64px"></image>
<text style="padding: 32px; background-color: deepskyblue; font-size: 18wx; color: white" @click="onTextClick">测试跳页.....</text>
</div>
</template>
<script>
//var navigator = weex.requireModule('navigator')
var navigator = weex.requireModule('webNavigator')
export default {
methods : {
onTextClick: function () {
navigator.push({
url: 'http://192.168.31.79:8081/dist/second.js',
name: 'Three',
title: '新页面',
animated: "true",
params: {
id: 11111
}
})
}
}
}
</script>
重新运行,查看效果, 发现页面已跳转,参数也传过去了, 离目标更进了一步, 不需要判断是否web环境了,使用和Android端相同的写法, 继续改进
使用loader替换 navigator 为 webNavigator
修改second.vue, 把webNavigator改为navigator
var navigator = weex.requireModule('navigator')
//var navigator = weex.requireModule('webNavigator')
自定义 web-h5-navigator-loader.js
module.exports = function (source) {
source = source.replace(/requireModule\('navigator'\)/g, `requireModule('navigatorModule')`)
//替换 weex.config 为 this.$route.params, web 和 android 使用相同的方式获取参数
source = source.replace(/weex.config./g, 'this.$route.params.');
//不替换 weex.config.env
source = source.replace(/this.\$route.params.env/g, 'weex.config.env');
return source;
}
配置loader
config/webpack.common.conf.js
在webConfig的module下添加代码,引入新建的自定义loader
module: {
rules: [
......, //原有的配置不变
{
test: /\.vue$/,
use: [
{
loader: path.resolve('loaders/web-h5-navigator-loader.js'),
}
]
}
]
}
修改three.vue
<template>
<div style="align-items: center; justify-content: center">
<text style="font-size: 18wx">这是个新页面</text>
<text>{{id}}</text>
<text>{{env}}</text>
</div>
</template>
<script>
export default {
data() {
return {
id: weex.config.id,
env: weex.config.env
}
}
}
</script>
重新运行,查看下效果,和Android端同样的写法,相同的效果,只是在navigator.push()参数中多加了个name, 这个也可以继续改进,今天就到这了,写的太累了
因为使用this.$route.params获取参数,data 不能使用()=> 这种写法,会报异常
网友评论