關注公眾號前端小白菜,更多前端小乾貨等着你喔!公眾號會不定期分享前端技術,每天進步一點點,與大家相伴成長
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開發實戰(二)
本文首發於本人公眾號,前端小白菜,分享與關注前端技術,歡迎關注~~