uniapp?動態(tài)組件實(shí)現(xiàn)Tabs標(biāo)簽切換組件(喜馬拉雅app作為案例)
uniapp 動態(tài)組件實(shí)現(xiàn)Tabs標(biāo)簽切換組件
一、功能描述
拿喜馬拉雅app作為案例,它的tabs標(biāo)簽有很多,如:推薦、小說、兒童等等。用戶點(diǎn)擊小說就會切換到小說組件,如果仔細(xì)看第一次是有一個加載的過程,如果你再返回到推薦頁,再次點(diǎn)擊小說時就沒有加載過程,而是直接顯示出來。
這就有兩個知識點(diǎn)
(1)動態(tài)組件切換 (vue3 中 component組件 is屬性)(2)保持組件被移除時的狀態(tài)(vue3 中是 KeepAlive)
二、在uniapp中實(shí)現(xiàn)動態(tài)組件切換需看uniapp是否支持
從官方文檔看到,component是支持 App 和 H5的(我實(shí)在app上實(shí)現(xiàn)的),而keepAlive只支持H5
<template> <!-- 標(biāo)簽數(shù)據(jù) --> <u-tabs class="tabsBox" :list="tabData" @click="changeTab" :scrollable="false" lineColor="#000" :activeStyle="{color: '#000',fontWeight: 'bold',transform: 'scale(1.05)'}" :inactiveStyle="{color: '#000'}" ></u-tabs> <!-- 組件切換 --> <component :is="tabData[current].comName"></component> </template> <script setup> import {ref,reactive,onMounted,markRaw} from 'vue'; import A from "./a.vue"; import B from "./b.vue"; import C from "./c.vue"; let tabData = reactive([ {name: '體育',comName:markRaw(A)}, {name: '經(jīng)濟(jì)',comName:markRaw(B)}, {name: 'IT信息',comName:markRaw(C)} ]); //切換標(biāo)簽事件 let current = ref(0); const changeTab = (obj)=>{ current.value = obj.index; } </script>
解釋一下:
(1)u-tabs 是 uview-plus 里面的標(biāo)簽組件
(2)markRaw 將一個對象標(biāo)記為不可被轉(zhuǎn)為代理。返回該對象本身,不然用響應(yīng)式的ref 會報出警告
關(guān)于如何保持組件被移除時的狀態(tài),我也在尋找方案
uniapp實(shí)現(xiàn)tab分類切換
<template> <view class="content"> <view class="nav"> <!-- 選項卡水平方向滑動,scroll-with-animation是滑動到下一個選項時,有一個延時效果 --> <scroll-view class="tab-scroll" scroll-x="true" scroll-with-animation :scroll-left="scrollLeft"> <view class="tab-scroll_box"> <!-- 選項卡類別列表 --> <view class="tab-scroll_item" v-for=" (item,index) in category" :key="index" :class="{'active':isActive==index}" @click="chenked(index)"> {{item.name}} </view> </view> </scroll-view> </view> <!-- 選項卡內(nèi)容輪播滑動顯示,current為當(dāng)前第幾個swiper子項 --> <swiper @change="change" :current="isActive" class="swiper-content" :style="fullHeight"> <swiper-item class="swiperitem-content"> <scroll-view scroll-y style="height: 100%;"> <view class="nav_item" v-for="(item,index) in add":key="index" > <view class=""> {{item.name}} </view> <view class=""> {{item.num}} </view> <view class=""> {{item.pink}} </view> </view> </scroll-view> </swiper-item> </swiper> </view> </template> <script> export default { watch:{ // swiper與上面選項卡聯(lián)動 currentindex(newval){ this.isActive = newval; this.scrollLeft = 0; // 滑動swiper后,每個選項距離其父元素最左側(cè)的距離 for (let i = 0; i < newval - 1; i++) { this.scrollLeft += this.category[i].width }; }, }, data() { return { isActive: 0, index: 0, currentindex:0, category:[ { id:1, name:'選項卡一', }, { id:2, name:'選項卡二', }, { id:3, name:'選項卡三', }, { id:4, name:'選項卡四', }, { id:5, name:'選項卡五', }, { id:6, name:'選項卡六', }, ], contentScrollW: 0, // 導(dǎo)航區(qū)寬度 scrollLeft: 0, // 橫向滾動條位置 fullHeight:"", arr:[ { name:'123444', num:'dfrgthh', pink:'1000', type:1 },{ name:'kkkkkkkk', num:'dfrgthh', pink:'1000', type:1 },{ name:'123444', num:'dfrgthh', pink:'1000', type:1 },{ name:'vvvvvvvv', num:'dfrgthh', pink:'1000', type:2 },{ name:'aaaaaaaaa', num:'dfrgthh', pink:'1000', type:3 },{ name:'gggggggg', num:'dfrgthh', pink:'1000', type:5 },{ name:'ddddddd', num:'dfrgthh', pink:'1000', type:5 }, ], add:[] } }, mounted() { var that = this; //獲取手機(jī)屏幕的高度,讓其等于swiper的高度,從而使屏幕充滿 uni.getSystemInfo({ success: function (res) { that.fullHeight ="height:" + res.windowHeight + "px"; } }); // 獲取標(biāo)題區(qū)域?qū)挾龋兔總€子元素節(jié)點(diǎn)的寬度 this.getScrollW() }, methods: { // 獲取標(biāo)題區(qū)域?qū)挾?,和每個子元素節(jié)點(diǎn)的寬度以及元素距離左邊欄的距離 getScrollW() { const query = uni.createSelectorQuery().in(this); query.select('.tab-scroll').boundingClientRect(data => { // 拿到 scroll-view 組件寬度 this.contentScrollW = data.width }).exec(); query.selectAll('.tab-scroll_item').boundingClientRect(data => { let dataLen = data.length; for (let i = 0; i < dataLen; i++) { // scroll-view 子元素組件距離左邊欄的距離 this.category[i].left = data[i].left; // scroll-view 子元素組件寬度 this.category[i].width = data[i].width } }).exec() }, // 當(dāng)前點(diǎn)擊子元素靠左留一個選項展示,子元素寬度不相同也可實(shí)現(xiàn) chenked(index) { if(index == 0){ this.add = this.arr }else{ let ass = [] for(let i in this.arr){ if(this.arr[i].type == index){ ass.push(this.arr[i]) } } this.add =ass } console.log(this.add); // this.isActive = index; // this.scrollLeft = 0; // for (let i = 0; i < index - 1; i++) { // this.scrollLeft += this.category[i].width // }; }, // swiper滑動時,獲取其索引,也就是第幾個 change(e){ const {current} = e.detail; this.currentindex = current; }, } } </script> <style lang="scss"> page{ height: 100%; display: flex; background-color: #FFFFFF; } .content{ display: flex; flex-direction: column; width: 100%; flex: 1; .nav{ border-top: 1rpx solid #f2f2f2; background-color: #fceeee; position: fixed; z-index: 99; width: 100%; align-items: center; height: 100rpx; .tab-scroll{ flex: 1; overflow: hidden; box-sizing: border-box; padding-left: 30rpx; padding-right: 30rpx; .tab-scroll_box{ display: flex; align-items: center; flex-wrap: nowrap; box-sizing: border-box; .tab-scroll_item{ line-height: 60rpx; margin-right: 35rpx; flex-shrink: 0; padding-bottom:10px; display: flex; justify-content: center; font-size: 16px; padding-top: 10px; } } } } .swiper-content{ padding-top: 120rpx; flex: 1; .swiperitem-content{ background-color: #ffffff; .nav_item{ background-color: #FFFFFF; padding:20rpx 40rpx 0rpx 40rpx ; } } } } .active { position: relative; color: #ff0000; font-weight: 600; } .active::after { content: ""; position: absolute; width: 130rpx; height: 4rpx; background-color: #ff0000; left: 0px; right: 0px; bottom: 0px; margin: auto; } /* 隱藏滾動條,但依舊具備可以滾動的功能 */ /deep/.uni-scroll-view::-webkit-scrollbar { display: none } </style>
到此這篇關(guān)于uniapp 動態(tài)組件實(shí)現(xiàn)Tabs標(biāo)簽切換組件的文章就介紹到這了,更多相關(guān)uniapp Tabs標(biāo)簽切換組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Web技術(shù)實(shí)現(xiàn)移動監(jiān)測的介紹
移動偵測,一般也叫運(yùn)動檢測,常用于無人值守監(jiān)控錄像和自動報警。通過攝像頭按照不同幀率采集得到的圖像會被 CPU 按照一定算法進(jìn)行計算和比較,當(dāng)畫面有變化時,如有人走過,鏡頭被移動,計算比較結(jié)果得出的數(shù)字會超過閾值并指示系統(tǒng)能自動作出相應(yīng)的處理2017-09-09Jquery+javascript實(shí)現(xiàn)支付網(wǎng)頁數(shù)字鍵盤
這篇文章主要為大家詳細(xì)介紹了Jquery+javascript實(shí)現(xiàn)支付網(wǎng)頁數(shù)字鍵盤,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-12-12Javascript實(shí)現(xiàn)簡易導(dǎo)航欄
這篇文章主要為大家詳細(xì)介紹了Javascript實(shí)現(xiàn)簡易導(dǎo)航欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-06-06