您好,登錄后才能下訂單哦!
這篇文章主要介紹“uni-app小程序沉浸式導航怎么實現”,在日常操作中,相信很多人在uni-app小程序沉浸式導航怎么實現問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”uni-app小程序沉浸式導航怎么實現”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
項目要在多個頁面上加自定義導航欄,還要有漸變效果,就是隨著頁面上滑,導航欄透明度由0逐漸變為1。這里面有幾個基本點需要注意下。
page 不能是height: 100%
,可以設置height: auto
,這樣才可以觸發 onPageScroll。
只有 page 才有 onPageScroll 事件。試驗發現,mixin 和頁面內都寫了 onPageScroll 的話,都會觸發。
如果把它放在 mixin 中,寫成下面這樣,可能會有問題:
data() { return { pageScrollTop: 0, }; }, onPageScroll({ scrollTop }) { this.pageScrollTop = scrollTop || 0; },
因為自定義導航欄不一定要在頁面級組件上,很多頁面都是寫在子組件里,而 mixin 是各個組件各自維護了一份data,所以無法傳遞。這也是Vue組件和小程序組件的不同之處。
解決方法有多個:
將 onPageScroll 寫在頁面級組件上,然后獲取到 scrollTop 后傳給子組件,這種方法太麻煩
onPageScroll 依然寫在 mixin 中,保存 scrollTop 到 vuex 的 state 中,然后在頁面或者組件中獲取這個 state
這里面還有兩個性能相關的點要注意下:
只有頁面級組件或者個別組件需要用的數據,不要放在 mixin 的 data/computed 中。因為 mixin 是所有組件的混入,并且 uni-app 中所有 data 和 computed 都會作為渲染依賴(不管用沒用到),可能會引起很多性能開銷。
onPageScroll 中不要做復雜邏輯,不要頻繁調用 setData,在 uni-app 中就是不要頻繁更新 data。因為小程序是雙線程通信,邏輯層更改數據要先到 native層,再傳到渲染層,中間可能還有 JSON.stringify 等操作。
綜上,目前采用的方案是:
mixin中,監聽 onPageScroll,因為這個在只會在當前頁面觸發,子組件會被忽略,所以寫在這里并不影響性能。
vuex 中保存 pageScrollTop、mpHeaderHeight,及一個衍生變量 mpHeaderBg。
然后,需要使用 mpHeaderBg 的頁面,去引用 vuex 中的變量。
如果想要在一個新頁面加上漸變導航,只需要引用 vuex 中的 mpHeaderBg 即可。
// 某個頁面 <template> <MatchHeaderMp :header-bg="mpHeaderBg" /> </template> <script> computed: { mpHeaderBg() { // getMpHeaderBg 方法來自于 mixin return this.getMpHeaderBg(); }, } </script>
// mixin export const uniSystemInfoMixin = { data() { return { // page-meta上設置的根標簽字體大小 mixinRootFontSize: 50, }; }, mounted() { // 設置根字體大小 this.onSetFontSize(); }, onPageScroll({ scrollTop }) { const mpHeaderHeight = this.$store.state.wxHeader.mpHeaderHeight || 44; const pageScrollTop = this.$store.getters.['wxHeader/pageScrollTop'] || 44; const parsedScrollTop = scrollTop > mpHeaderHeight ? mpHeaderHeight : scrollTop; // 如果滑動值大于 mpHeaderHeight,就不再更新 data if (parsedScrollTop === mpHeaderHeight && pageScrollTop === mpHeaderHeight) { return; } this.$store.commit('wxHeader/setPageScrollTop', parsedScrollTop); }, beforeDestroy() { if (this.mpType === 'page') { this.$store.commit('wxHeader/setPageScrollTop', 0); } }, methods: { getMpHeaderBg() { const pageScrollTop = this.getMpPageScrollTop(); const mpHeaderHeight = this.$store.state.wxHeader.mpHeaderHeight || 44; return `rgba(255, 255, 255, ${Math.min(1, pageScrollTop / mpHeaderHeight)})`; }, getMpPageScrollTop() { const curPageName = this.getCurPageName(); const pageScrollTopMap = this.$store.state.wxHeader.pageScrollTopMap || {}; return pageScrollTopMap[curPageName] || 0; }, getCurPageName() { const pages = getCurrentPages(); return pages[pages.length - 1].route; }, onSetFontSize() { // 寬度 375 時(iphone6),rootFontSize為50,則一份為 375/50=7.5 const screenNumber = 7.5; const that = this ; if (that.mpType === 'page') { // 窗體改變大小觸發事件 uni.onWindowResize((res) => { if (res.size.windowWidth) { that.mixinRootFontSize = parseFloat(res.size.windowWidth) / screenNumber; } }); // 打開獲取屏幕大小 uni.getSystemInfo({ success(res) { const fontsize = res.screenWidth / screenNumber; that.mixinRootFontSize = fontsize; const mpHeaderHeight = res.statusBarHeight + 44; that.$store.commit('wxHeader/setMpHeaderHeight', mpHeaderHeight); }, }); } }, }, };
// store/modules/wx-header.js const wxHeaderStore = { namespaced: true, state: () => ({ // 存放多個頁面的pageScrollTop pageScrollTopMap: {}, // 狀態欄高度 mpHeaderHeight: 44, }), mutations: { setPageScrollTop(state, pageScrollTop = 0) { const curPageName = getCurPageName(); state.pageScrollTopMap = { ...state.pageScrollTopMap, [curPageName]: pageScrollTop, }; }, setMpHeaderHeight(state, mpHeaderHeight) { state.mpHeaderHeight = mpHeaderHeight; }, }, };
不要多個頁面共享同一個變量,會存在多個頁面互相影響的可能。
小程序重新進入某個頁面,都會重新回到頂部,包括page
和所有scroll view
,所以要在beforeDestroy
中重置pageScrollTop
。
到此,關于“uni-app小程序沉浸式導航怎么實現”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。