关注公众号前端小白菜
,更多前端小干货等着你喔!公众号会不定期分享前端技术,每天进步一点点,与大家相伴成长
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能力,可以参考以上写法。如果您有任何想法或疑问可以在下方留言评论探讨。
历史文章阅读
本文首发于本人公众号,前端小白菜,分享与关注前端技术,欢迎关注~~