1
0

app-navigation-two-icon.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <template>
  2. <view class="app-navigation-two-icon" :style="{backgroundColor: background}">
  3. <view v-if="navType === 'fixed'" class="dir-top-nowrap nav-fixed u-border-box"
  4. :class="{'nav-fixed-text' : modeType === 'text'}">
  5. <view v-for="(navs, index1) in newNavs" :key="index1" class="dir-left-nowrap">
  6. <view v-for="(nav, index2) in navs" :key="index2"
  7. :style="{marginRight: index2 === navs.length - 1 ? 'auto' : '0',marginLeft: 'auto'}">
  8. <app-jump-button form :url="nav.link_url" :open_type="nav.open_type" arrangement="column"
  9. class="cross-top">
  10. <view class="nav-list dir-top-nowrap main-center cross-center u-border-box"
  11. :class="{'nav-list-text' : modeType === 'text'}">
  12. <image v-if="modeType === 'img'" class="nav-image" :src="nav.icon_url" lazy-load></image>
  13. <div v-if="nav.name" class="nav-name u-border-box" :style="{color: color}"
  14. :class="{'nav-name-text': modeType === 'text'}">
  15. {{nav.name.substring(0,columns > 5 ? 4: 5)}}
  16. </div>
  17. </view>
  18. </app-jump-button>
  19. </view>
  20. </view>
  21. </view>
  22. <block v-if="navType === 'alone'">
  23. <scroll-view scroll-x class="dir-left-nowrap" :style="{'max-height': modeType === 'img'? '192rpx': '100rpx'}">
  24. <view v-for="(nav, index) in navs" :key="index" :style="[formatB(index)]" class="box-list">
  25. <app-jump-button style="height: 100%" form :url="nav.link_url" :open_type="nav.open_type"
  26. arrangement="column"
  27. class="cross-top">
  28. <image v-if="modeType === 'img'" :src="nav.icon_url" :style="{height:'88rpx',width: '88rpx','margin-bottom': 'auto'}"
  29. lazy-load></image>
  30. <div v-if="nav.name" class="t-omit nav-name" :style="{color: color}"
  31. :class="{'nav-name-alone': modeType === 'text'}">
  32. {{nav.name.substring(0,aloneNum > 5 ? 4: 5)}}
  33. </div>
  34. </app-jump-button>
  35. </view>
  36. </scroll-view>
  37. </block>
  38. <block v-if="navType === 'multi'">
  39. <swiper @change="changeSwiper" :style="{height: multiswiper}">
  40. <swiper-item v-for="(navlist, index0) in muitiNavs" :key="index0" :item-id="index0">
  41. <view class="dir-top-nowrap nav-fixed" :class="'nav-swiper-' + tempIndex">
  42. <view v-for="(navs, index1) in navlist" :key="index1" class="dir-left-nowrap">
  43. <view v-for="(nav, index2) in navs" :key="index2"
  44. :style="{marginRight: index2 === navs.length - 1 ? 'auto' : '0',marginLeft: 'auto'}">
  45. <app-jump-button form :url="nav.link_url" :open_type="nav.open_type"
  46. arrangement="column"
  47. class="cross-top">
  48. <view class="nav-list dir-top-nowrap main-center cross-center"
  49. :class="{'nav-list-text' : modeType === 'text'}">
  50. <image v-if="modeType === 'img'" class="nav-image" :src="nav.icon_url"
  51. lazy-load></image>
  52. <div v-if="nav.name" class="nav-name" :style="{color: color}"
  53. :class="{'nav-name-text': modeType === 'text'}">
  54. {{nav.name.substring(0,columns > 5 ? 4: 5)}}
  55. </div>
  56. </view>
  57. </app-jump-button>
  58. </view>
  59. </view>
  60. </view>
  61. </swiper-item>
  62. </swiper>
  63. <!-- 指示点 -->
  64. <view class="main-center cross-center indicator u-border-box">
  65. <block v-if="swiperType === 'rectangle'">
  66. <view class="dir-left-nowrap">
  67. <view v-for="(i,index) in muitiNavs" :key="index" class="rectangletwo"
  68. :style="{backgroundColor: current === index ? swiperColor : swiperNoColor}">
  69. </view>
  70. </view>
  71. <!--<view :style="{width: `${muitiNavs.length * 44}rpx`}" class="rectangle">-->
  72. <!-- <view class="rectangle active"-->
  73. <!-- :style="{left: `${current * 44}rpx`,backgroundColor: swiperColor}"></view>-->
  74. <!--</view>-->
  75. </block>
  76. <block v-if="swiperType === 'circle'">
  77. <view class="dir-left-nowrap">
  78. <view v-for="(i,index) in muitiNavs" :key="index" class="circle"
  79. :style="{backgroundColor: current === index ? swiperColor : swiperNoColor}">
  80. </view>
  81. </view>
  82. </block>
  83. </view>
  84. </block>
  85. </view>
  86. </template>
  87. <script>
  88. export default {
  89. name: 'app-navigation-two-icon',
  90. props: {
  91. background: {
  92. type: String,
  93. default() {
  94. return '#ffffff';
  95. }
  96. },
  97. modeType: {
  98. type: String,
  99. default() {
  100. return 'img';
  101. }
  102. },
  103. color: {
  104. type: String,
  105. default() {
  106. return '#333333';
  107. }
  108. },
  109. //每行个数
  110. columns: {
  111. type: Number,
  112. default() {
  113. return 3;
  114. }
  115. },
  116. navs: {
  117. type: Array,
  118. default() {
  119. return []
  120. }
  121. },
  122. navType: String,
  123. aloneNum: Number, //一屏显示
  124. lineNum: Number, //一屏行数
  125. swiperType: String,
  126. swiperColor: String,
  127. swiperNoColor: String,
  128. tempIndex: Number,
  129. },
  130. data() {
  131. return {
  132. current: 0,
  133. multiswiper: '80px',
  134. defaultInfo: {
  135. imageHeight: 88,
  136. left: 32,
  137. limit: 30,
  138. }
  139. }
  140. },
  141. methods: {
  142. calcHeight: function () {
  143. setTimeout(() => {
  144. // #ifdef MP-ALIPAY || MP-BAIDU
  145. let query = uni.createSelectorQuery();
  146. // #endif
  147. // #ifndef MP-ALIPAY || MP-BAIDU
  148. let query = uni.createSelectorQuery().in(this);
  149. // #endif
  150. query.select(`.nav-swiper-${this.tempIndex}`).boundingClientRect(item => {
  151. if (item) {
  152. this.multiswiper = item.height + 'px';
  153. }
  154. }).exec();
  155. });
  156. },
  157. changeSwiper: function (e) {
  158. this.current = e.detail.current;
  159. },
  160. group: function (array, subGroupLength) {
  161. subGroupLength = parseInt(subGroupLength);
  162. let index = 0;
  163. let newArray = [];
  164. while (index < array.length) {
  165. newArray.push(array.slice(index, index += subGroupLength));
  166. }
  167. return newArray;
  168. },
  169. addNull: function () {
  170. let columns = this.columns;
  171. let length = this.navs.length;
  172. let addNum = length % columns === 0 ? 0 : columns - length % columns;
  173. return this.navs.concat(new Array(addNum).fill({
  174. 'url': '',
  175. 'openType': '',
  176. 'icon_url': '',
  177. 'name': '',
  178. }))
  179. }
  180. },
  181. created() {
  182. this.calcHeight();
  183. },
  184. beforeUpdate() {
  185. this.calcHeight();
  186. },
  187. computed: {
  188. newNavs() {
  189. let arr = this.addNull();
  190. return this.group(arr, this.columns)
  191. },
  192. muitiNavs() {
  193. let arr = this.addNull();
  194. arr = this.group(arr, this.columns);
  195. arr = this.group(arr, this.lineNum)
  196. return arr;
  197. },
  198. aloneWidth() {
  199. return `100rpx`;
  200. /*
  201. let aloneNum = Number(this.aloneNum);
  202. let width = 0;
  203. if (aloneNum < 5) {
  204. width = this.defaultInfo.imageHeight;
  205. } else {
  206. width = (750 - this.defaultInfo.left - (aloneNum - 1) * this.defaultInfo.limit) / (aloneNum * 2 - 1) * 2;
  207. }
  208. return `${uni.upx2px(width)}px`;
  209. */
  210. },
  211. formatB() {
  212. return (index) => {
  213. let aloneNum = Number(this.aloneNum);
  214. let extra = {width: this.aloneWidth};
  215. if (aloneNum < 5) {
  216. extra = Object.assign(extra, {
  217. marginLeft : `${uni.upx2px(750 - parseFloat(this.aloneWidth) * aloneNum) / (aloneNum + 1)}px`,
  218. })
  219. } else {
  220. extra = Object.assign(extra, {
  221. marginLeft: `${uni.upx2px((750 - parseFloat(this.aloneWidth) * aloneNum + parseFloat(this.aloneWidth) / 2) / aloneNum)}px`,
  222. })
  223. }
  224. if (index === this.navs.length - 1) extra = Object.assign(extra, {'margin-right': extra.marginLeft})
  225. return extra;
  226. }
  227. },
  228. },
  229. }
  230. </script>
  231. <style scoped lang="scss">
  232. .app-navigation-two-icon {
  233. ::-webkit-scrollbar {
  234. display: none;
  235. width: 0;
  236. height: 0;
  237. color: transparent;
  238. }
  239. .nav-fixed {
  240. padding: 0 0 #{24rpx};
  241. }
  242. .nav-fixed.nav-fixed-text {
  243. padding-bottom: #{32rpx - 36rpx + 32rpx};
  244. }
  245. .nav-list {
  246. padding-top: #{28rpx};
  247. width: #{100rpx};
  248. }
  249. .nav-list.nav-list-text {
  250. padding-top: 0;
  251. }
  252. .nav-image {
  253. height: #{88rpx};
  254. width: #{88rpx};
  255. display: block;
  256. margin-bottom: auto;
  257. }
  258. .nav-name {
  259. font-size: #{24rpx};
  260. color: #353535;
  261. padding-top: #{16rpx};
  262. padding-bottom: calc(#{32rpx} - #{28rpx});
  263. display: block;
  264. white-space: nowrap;
  265. line-height: 1;
  266. /*width: 100%;*/
  267. /*overflow: hidden;*/
  268. /*text-overflow: clip;*/
  269. text-align: center;
  270. }
  271. .nav-name.nav-name-text {
  272. padding-top: #{32rpx};
  273. padding-bottom: calc(#{36rpx} - #{32rpx});
  274. }
  275. .nav-name-alone {
  276. padding: calc(#{32rpx - 28rpx}) 0;
  277. }
  278. scroll-view {
  279. white-space: nowrap;
  280. padding: #{28rpx} 0;
  281. .box-list {
  282. display: inline-block;
  283. }
  284. image {
  285. width: 100%;
  286. display: block;
  287. }
  288. text {
  289. width: 100%;
  290. text-align: center;
  291. padding-top: #{12rpx};
  292. display: block;
  293. line-height: 1;
  294. padding-bottom: #{18rpx};
  295. font-size: #{12px};
  296. text-overflow: clip;
  297. }
  298. }
  299. .indicator {
  300. height: #{10rpx};
  301. margin-top: calc(#{16rpx - 24rpx});
  302. padding-bottom: #{12rpx};
  303. width: 100%;
  304. .rectangle {
  305. border-radius: #{6rpx};
  306. height: #{8rpx};
  307. background-color: #BCBCBC;
  308. position: relative;
  309. }
  310. .rectangle .active {
  311. position: absolute;
  312. top: 0;
  313. width: #{44rpx};
  314. }
  315. .rectangletwo {
  316. height: #{8rpx};
  317. margin: 0 #{2rpx};
  318. width: #{24rpx};
  319. border-radius: #{16rpx};
  320. }
  321. .circle {
  322. height: #{8rpx};
  323. margin: 0 #{5rpx};
  324. width: #{8rpx};
  325. border-radius: 50%;
  326. }
  327. }
  328. }
  329. </style>