关注公众号前端小白菜,更多前端小干货等着你喔!公众号会不定期分享前端技术,每天进步一点点,与大家相伴成长

uni-app App端内置了一个基于weex的原生渲染引擎,提供了原生的渲染能力。

想用JavaScript开发中原生的组件能力,前端有两种选择weex和react-native,两个框架分别依托于vue与react。weex依托于vue,与uni-app的设计理念一致,故而也是uni-app性能优化上的最优选择。

uni-app与本weex的区别在于uni-app本质上还是运行在webview之上的,说到底还是网页,而weex提供的是原生的渲染能力,weex实现原理简单点来说就是将weex组件映射到原生组件上,你写的是view,实际上渲染的安卓或者IOS的容器组件,故而能拥有近乎原生的渲染能力。

weex原理

放一张比较简单的weex的架构图。


图片来源网络

看图说话,不难理解。

1、WEEX通过前端构建能力将vue文件转换为打包JSBundle文件

2、通过网络或者是内置的方式加载

3、客户端提供js执行引擎,执行JSBundle文件,生成虚拟DOM

4、WEEX渲染引擎针对不同平台转换为对应的原生组件。

以上只是浅显的理解,但大致描述了WEEX能提供原生渲染能力的原因。

NVUE正是借用了WEEX的能力来提升uni-app的渲染能力。虽然NVUE可以提供不错的原生的能力,但是同时也有不少限制。

NVUE/WEEX的使用场景

纯NVUE项目,要想获得更好的性能,自然是全部使用NVUE最好,uni-app也提供了纯NVUE的编译模式,内部只提供WEEX渲染引擎,打包出来的APP性能更好,安装包也更小。

提升APP打开速度,混用模式下,推荐首页使用NVUE开发,uni-app提供fast编译模式,可以提升APP的加载以及打开速度。

覆盖原生组件,APP端的导航栏、tabbar、以及一些原生组件(比如VIDEO)无法被覆盖,页面内想要覆盖这些组件就需要用到NVUE。uni-app提供了SUBNVUE功能,SUBNVUE是一个NVUE页面,具有更高的层级,可以覆盖所有组件。

使用原生能力,uni-app虽然提供了众多组件,但是部分组件的部分能力只能在NVUE中使用,比如Input的 confirm-type功能,如果想要定制键盘右下角按钮为“发送”文案,则只能使用NVUE,这个需求在IM即时通讯中最为常见。

NVUE/WEEX的限制

WEEX开发有很多限制,主要表现在CSS的限制上,毕竟不是所有的CSS效果都能映射到原生组件上的。比如:

1、只支持flex布局,同时uni-app中默认flex排版方向纵向:flex-direction: column;  开发时需要稍加注意,也可以在 manifest.json 中配置 app-plus.nvue.flex-direction: row 来修改。

2、css只支持类选择器,且不支持嵌套,这意味着你不能写 #app,也不能写.app .main 以及其他更多写法。

3、背景图无法使用。

4、边框阴影支持度不足。

5、不能使用typescript,vue本身对ts的支持就比较弱,但现在已经是ts的天下,原生js的书写的代码简直无法维护,自己写的代码,过一个月自己都看不懂,ts绝对是前端开发者心目中的白月光。

6、无法访问Vue.prototype,一个常见的做法是,将vuex示例全局挂载在Vue.prototype上,这样各个组件中都可以很好的使用vuex。

// main.js
import store from "./store";
Vue.prototype.$store = store;
​
// App.vue
{
  methods: {
    update() {
      this.$store.dispatch('user/update');
    }
  }
}

7、无法访问全局挂载的组件,类似于Vue.prototype,NVUE中也无法使用全局组件,其原因在于nvue与vue本质上就不一样,甚至是编译环境都不一样,两者直接无法直接通讯,需要借助uni-app提供的通讯机制进行通讯。

NVUE的性能提升?

本人NVUE用的不多,性能数据没有实际测试过,纯眼睛测试~貌似看不出太多的不一样。但是上面提到的组件覆盖功能,以及原生组件能力还是需要使用NVUE来实现。 ~~

NVUE开发过程中其实坑不少,除了某些必须使用NVUE来实现的能力外,如果没有严格的性能追求,不太建议使用NVUE,为了那么点的性能,付出的开发成本可能会更多,此外现在的手机性能都有不错的性能,差距不大的话根本体验不出来。

首页使用NVUE是个不错的选择,毕竟是原生渲染,而首页的渲染速度又关乎着APP的打开速度,APP的打开速度是一个APP的重要衡量标准。原生渲染能力与WEBVIEW的渲染能力越是在性能较差的机器上表现越是明显。

NVUE全局挂在VUEX?

有同学就要问了,如果我非要在NVUE里面读取全局挂在VUEX实例该怎么办呢?别急还是有办法的。

uni-app参考小程序实现了globalData能力,这是一种比较简单的全局能力,在NVUE中也可以使用,通过这个全局能力,咱们就可以实现NVUE读取全局VUEX了。

// main.js
import store from "./store";
Vue.prototype.$store = store;
​
// App.vue
export default {
  globalData: {  
    $store: null,  
  },
  async onLaunch() {
    // 坑逼,getApp() 微信报错,this.$scope h5报错
    const _app = this.$scope || getApp();
    _app.globalData.$store = this.$store;
  }   
}
// chat.nvue
export default {
  methods: {
    send() {
      const { $store } = getApp().globalData || this;
      $store.dispatch('user/login');
    }
  }
}

想要挂载其他API能力,可以参考以上写法。如果您有任何想法或疑问可以在下方留言评论探讨。

历史文章阅读

Hybrid APP开发实战(一)

Hybrid APP开发实战(二)

本文首发于本人公众号,前端小白菜,分享与关注前端技术,欢迎关注~~

前端小白菜


孤月
144 声望5 粉丝

保持一颗不断进取的心,相信自己终会成功。