Weex的页面跳转方案的选择

准备使用 Weex 来做新的移动端项目,但是在页面跳转方面有些疑惑。现有以下几种方案:

  • Android就一个Activity,页面跳转逻辑都通过 vue-router 来实现。

  • 每个页面都是一个Activity,每个Activity加载各自的 bundle.js 文件,数据通过 storage 模块传输。

  • 通过navigator模块实现页面跳转。

第一种呢,感觉用 vue-router 之后界面很生硬,效果不好。
第二种么,自己瞎想的,感觉交互会好点。
第三种,直接不会用,囧……好像打包的js文件必须是远程的吧?

不知道有没有好的解决方案让weex来优雅地实现页面跳转呢?大家都是用的什么来进行Weex页面跳转的呢?

阅读 11.7k
5 个回答

我用的是第三种:var params = {'url':nextUrl,'animated':'true'} 把nextUrl替换成你另外个js文件的地址就行了,不用远程,直接本地地址可以。

<template>
  <div class="div">
    <text class="text" onclick="onItemClick">click me! {{message}}</text>
  </div>
</template>
<script>
  var navigator = require('@weex-module/navigator')
  var nextUrl = 'http://dotwe.org/raw/dist/6cd1703a45d7b2752cf05303069ce881.js'
  module.exports ={
    data:{
      message:''
    },
    methods:{
      onItemClick:function(e){
        var params = {'url':nextUrl,'animated':'true'}
        navigator.push(params, function(e) {
          console.log('i am the callback.')
        });
      }
    }
  }
</script>
<style>
  .div {
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    width: 750;
    height: 90;
    padding-left:30;
    padding-right:30;
    border-bottom-width: 1;
    border-style: solid;
    border-color: #dddddd;
  }
  .text{
    width: 750;
    height: 90;
  }
</style>

weex端维护一个routes,保存相对路径——》文件路径的映射关系

import {getBaseURL} from '../tools/base-url'

// 路由前缀
const root = getBaseURL()

// 页面路由
const routes = [
    {path: '/home', component: 'home', name: '首页'},
].map(route => {
    route.location = `${root}${route.component}.js`
    return route
})

export default routes

利用vue的mixins机制,往每个界面的vue实例中注入mixins

import router from '../tools/navigator'
import Vue from 'vue'

export default {
    beforeCreate() {
        this.route = router.getCurrentRoute()
        this.router = router
    }
}

利用注入的router对象,进行跳转

this.router.push({ path: '/home' })

push核心逻辑无非遍历routes数组,取出js文件地址利用navigator模块跳转。也可以这里做些vue-router类似的带参数跳转操作

const push = ({
    path,
    name,
    query,
    params
}) => {
    return new Promise(resolve => {
        let route = matchRoute(path)
        navigator.push({
            url: route.location,
            animated: 'true'
        }, e => {
            console.log('callback: ', e)
            resolve(e)
        })
    })
}

以上方案是所有业务由weex维护,所以路由也由weex来维护。如果你们公司是hybrid方案,部分业务weex,部分业务native。需要解决的核心问题会变成处理weex->native,native->weex的动态化跳转问题。你们可以指定一个路由跳转规范。
比如对Activity注解

@Route("activity://example/:s{username}/:i{password}")
public class ExampleActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_example);
        initDataFromIntent();
    }

    public void initDataFromIntent() {
        //get params in intent
        String username = getIntent().getStringExtra("username");
        int password = getIntent().getIntExtra("password", -1);
    }
}

然后可以通过这个url来完成对Activity的跳转,这样就摆脱了编译是跳转startActivity的尴尬

ActivityRequest.from(this, "activity://example/kevin/123455")
                .open();

如此weex端仍然可以维护一个路由文件,记录相对路径(/example)到绝对路径(activity://example/kevin/123455)的映射关系

关于页面跳转,简单说下我的做法。
首先每个页面都有自己的Activity/UIViewController(当然如果页面元素比较少,可以嵌套使用vue-router),然后渲染页面时记得带上当前Activity/UIViewController获得的参数
Android

Bundle bundle = mIntent == null ? new Bundle() : mIntent.getExtras();
        jsonInitData = StringUtils.isEmpty(jsonInitData) ? bundleConvertJSON(bundle).toString() : jsonInitData;
        mInstance.render(
                getPageName(),
                source,
                options,
                jsonInitData,
                WXRenderStrategy.APPEND_ASYNC);          

iOS:

renderWithURL:options:data:@{test:'value'}

然后可以直接在当前页面的data中进行获取,最后可以在native维护一个类似vuex功能的模块。

当然在打包的时候webpackentry的配置需要注意一下,还有导航模块最好是自己定义,然后在里面做一些兼容的处理即可。

重写nav module自定义options传参。源码里值留了url

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏