Skip to content

Commit

Permalink
feat: tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
yang1206 committed Jun 20, 2023
1 parent b00a7c4 commit e31e9f5
Show file tree
Hide file tree
Showing 19 changed files with 1,168 additions and 20 deletions.
2 changes: 2 additions & 0 deletions example/src/components.d.ts
Expand Up @@ -47,6 +47,8 @@ declare module '@vue/runtime-core' {
NutSwitch: typeof import('uniapp-nutui/components/switch/switch.vue')['default']
NutTabbar: typeof import('uniapp-nutui/components/tabbar/tabbar.vue')['default']
NutTabbarItem: typeof import('uniapp-nutui/components/tabbaritem/tabbaritem.vue')['default']
NutTabPane: typeof import('uniapp-nutui/components/tabpane/tabpane.vue')['default']
NutTabs: typeof import('uniapp-nutui/components/tabs/tabs.vue')['default']
NutToast: typeof import('uniapp-nutui/components/toast/toast.vue')['default']
ThemeSwitch: typeof import('./components/ThemeSwitch.vue')['default']
}
Expand Down
2 changes: 1 addition & 1 deletion example/src/demo/feedback/pages/actionsheet/index.vue
Expand Up @@ -143,7 +143,7 @@ export default {
<nut-action-sheet
v-model:visible="state.isVisible2"
cancel-txt="取消"
:safe-area-inset-bottom="true"
safe-area-inset-bottom
:menu-items="menuItemsOne"
@choose="chooseItemTwo"
/>
Expand Down
8 changes: 4 additions & 4 deletions example/src/demo/nav/pages/navbar/index.vue
Expand Up @@ -88,10 +88,10 @@ export default defineComponent({
</h2>
<nut-navbar desc="编辑" @on-click-back="back" @on-click-title="title" @on-click-right="rightClick">
<template #content>
<!-- <nut-tabs v-model="tab1value" @click="changeTab">
<nut-tabs v-model="tab1value" @click="changeTab">
<nut-tab-pane title="商品" />
<nut-tab-pane title="店铺" />
</nut-tabs> -->
</nut-tabs>
</template>

<template #right>
Expand All @@ -104,12 +104,12 @@ export default defineComponent({
</h2>
<nut-navbar @on-click-back="back">
<template #content>
<!-- <nut-tabs v-model="tab2value" @click="changeTabList">
<nut-tabs v-model="tab2value" @click="changeTabList">
<nut-tab-pane title="商品" />
<nut-tab-pane title="评价" />
<nut-tab-pane title="详情" />
<nut-tab-pane title="推荐" />
</nut-tabs> -->
</nut-tabs>
</template>

<template #right>
Expand Down
239 changes: 239 additions & 0 deletions example/src/demo/nav/pages/tabs/index.vue
@@ -0,0 +1,239 @@
<script lang="ts">
import { reactive } from 'vue'
export default {
props: {},
setup() {
const state = reactive({
tab1value: '0',
tab11value: '0',
tab2value: '0',
tab3value: '0',
tab4value: '0',
tab5value: '0',
tab6value: '0',
tab7value: 'c1',
list3: Array.from(new Array(2).keys()),
list4: Array.from(new Array(10).keys()),
list5: Array.from(new Array(2).keys()),
list6: [
{
title: '自定义 1',
paneKey: 'c1',
icon: 'dongdong',
},
{
title: '自定义 2',
paneKey: 'c2',
icon: 'JD',
},
{
title: '自定义 3',
paneKey: 'c3',
},
],
})
setTimeout(() => {
state.list3.push(999)
}, 3000)
return { state }
},
}
</script>

<template>
<div class="demo full">
<h2 class="title">
基础用法
</h2>
<nut-tabs v-model="state.tab1value">
<nut-tab-pane title="Tab 1">
Tab 1
</nut-tab-pane>
<nut-tab-pane title="Tab 2">
Tab 2
</nut-tab-pane>
<nut-tab-pane title="Tab 3">
Tab 3
</nut-tab-pane>
</nut-tabs>
<h2 class="title">
手势滑动切换
</h2>
<nut-tabs v-model="state.tab1value" swipeable>
<nut-tab-pane title="Tab 1">
Tab 1
</nut-tab-pane>
<nut-tab-pane title="Tab 2">
Tab 2
</nut-tab-pane>
<nut-tab-pane title="Tab 3">
Tab 3
</nut-tab-pane>
</nut-tabs>
<h2 class="title">
基础用法-微笑曲线
</h2>
<nut-tabs v-model="state.tab11value" type="smile">
<nut-tab-pane title="Tab 1">
Tab 1
</nut-tab-pane>
<nut-tab-pane title="Tab 2">
Tab 2
</nut-tab-pane>
<nut-tab-pane title="Tab 3">
Tab 3
</nut-tab-pane>
</nut-tabs>
<h2 class="title">
通过 pane-key 匹配
</h2>
<nut-tabs v-model="state.tab2value">
<nut-tab-pane title="Tab 1" pane-key="0">
Tab 1
</nut-tab-pane>
<nut-tab-pane title="Tab 2" pane-key="1" :disabled="true">
Tab 2
</nut-tab-pane>
<nut-tab-pane title="Tab 3" pane-key="2">
Tab 3
</nut-tab-pane>
</nut-tabs>
<h2 class="title">
Tab Pane 自动高度
</h2>
<nut-tabs v-model="state.tab2value" :auto-height="true">
<nut-tab-pane title="Tab 1" pane-key="0">
<p>Tab 1</p>
<p>Tab 1</p>
<p>Tab 1</p>
<p>Tab 1</p>
</nut-tab-pane>
<nut-tab-pane title="Tab 2" pane-key="1">
Tab 2
</nut-tab-pane>
<nut-tab-pane title="Tab 3" pane-key="2">
Tab 3
</nut-tab-pane>
</nut-tabs>
<h2 class="title">
数据异步渲染 3s
</h2>
<nut-tabs v-model="state.tab3value">
<nut-tab-pane v-for="item in state.list3" :key="item" :title="`Tab ${item}`">
Tab {{ item }}
</nut-tab-pane>
</nut-tabs>

<h2 class="title">
数量多,滚动操作(横向)
</h2>
<nut-tabs v-model="state.tab4value" title-scroll title-gutter="10" name="tab4value">
<nut-tab-pane v-for="item in state.list4" :key="item" :title="`Tab ${item}`">
Tab {{ item }}
</nut-tab-pane>
</nut-tabs>
<h2 class="title">
数量多,滚动操作(纵向)
</h2>
<nut-tabs
v-model="state.tab4value"
title-scroll
name="tab4valueVertical"
direction="vertical"
custom-style="height: 220px;"
>
<nut-tab-pane v-for="item in state.list4" :key="item" :title="`Tab ${item}`">
Tab {{ item }}
</nut-tab-pane>
</nut-tabs>
<h2 class="title">
左右布局
</h2>
<nut-tabs v-model="state.tab5value" custom-style="height: 300px;" title-scroll direction="vertical">
<nut-tab-pane v-for="item in state.list5" :key="item" :pane-key="item" :title="`Tab ${item}`">
Tab {{ item }}
</nut-tab-pane>
</nut-tabs>
<h2 class="title">
左右布局-微笑曲线
</h2>
<nut-tabs v-model="state.tab6value" custom-style="height: 300px;" type="smile" title-scroll direction="vertical">
<nut-tab-pane v-for="item in state.list5" :key="item" :pane-key="item" :title="`Tab ${item}`">
Tab {{ item }}
</nut-tab-pane>
</nut-tabs>
<h2 class="title">
标签栏字体尺寸 large normal small
</h2>
<nut-tabs v-model="state.tab1value" size="large">
<nut-tab-pane title="Tab 1">
Tab 1
</nut-tab-pane>
<nut-tab-pane title="Tab 2">
Tab 2
</nut-tab-pane>
<nut-tab-pane title="Tab 3">
Tab 3
</nut-tab-pane>
</nut-tabs>
<nut-tabs v-model="state.tab1value" size="normal">
<nut-tab-pane title="Tab 1">
Tab 1
</nut-tab-pane>
<nut-tab-pane title="Tab 2">
Tab 2
</nut-tab-pane>
<nut-tab-pane title="Tab 3">
Tab 3
</nut-tab-pane>
</nut-tabs>
<nut-tabs v-model="state.tab1value" size="small">
<nut-tab-pane title="Tab 1">
Tab 1
</nut-tab-pane>
<nut-tab-pane title="Tab 2">
Tab 2
</nut-tab-pane>
<nut-tab-pane title="Tab 3">
Tab 3
</nut-tab-pane>
</nut-tabs>
<h2 class="title">
自定义标签栏
</h2>
<nut-tabs v-model="state.tab7value">
<template #titles>
<view class="nut-tabs__list">
<view
v-for="item in state.list6"
:key="item.paneKey"
class="nut-tabs__titles-item"
:class="{ active: state.tab7value === item.paneKey }"
@click="state.tab7value = item.paneKey"
>
<nut-icon name="dongdong" />
<view class="nut-tabs__titles-item__text">
{{ item.title }}
</view>
<view class="nut-tabs__titles-item__line" />
</view>
</view>
</template>
<nut-tab-pane v-for="item in state.list6" :key="item" :pane-key="item.paneKey">
{{ item.title }}
</nut-tab-pane>
</nut-tabs>
</div>
</template>

<style lang="scss" scoped></style>

<route lang="json">
{
"style": {
"navigationBarTitleText": "Tabs"
}
}
</route>
2 changes: 1 addition & 1 deletion example/src/pages.json
@@ -1 +1 @@
{"easycom":{"autoscan":true,"custom":{}},"globalStyle":{"navigationBarBackgroundColor":"@navBgColor","navigationBarTextStyle":"@navTxtStyle","navigationBarTitleText":"NutUi","backgroundColor":"@bgColor","backgroundTextStyle":"@bgTxtStyle","backgroundColorTop":"@bgColorTop","backgroundColorBottom":"@bgColorBottom"},"pages":[{"path":"pages/index/index","type":"home"}],"subPackages":[{"root":"demo","pages":[{"path":"basic/pages/button/index","type":"page","style":{"navigationBarTitleText":"Button"}},{"path":"basic/pages/cell/index","type":"page","style":{"navigationBarTitleText":"Cell"}},{"path":"basic/pages/icon/index","type":"page","style":{"navigationBarTitleText":"Icon"}},{"path":"basic/pages/overlay/index","type":"page","style":{"navigationBarTitleText":"Overlay"}},{"path":"basic/pages/popup/index","type":"page","style":{"navigationBarTitleText":"Popup"}},{"path":"exhibition/pages/avatar/index","type":"page","style":{"navigationBarTitleText":"Avatar"}},{"path":"exhibition/pages/badge/index","type":"page","style":{"navigationBarTitleText":"Badge"}},{"path":"exhibition/pages/countdown/index","type":"page","style":{"navigationBarTitleText":"CountDown"}},{"path":"feedback/pages/actionsheet/index","type":"page","style":{"navigationBarTitleText":"Actionsheet"}},{"path":"feedback/pages/backtop/index","type":"page","style":{"navigationBarTitleText":"BackTop"}},{"path":"feedback/pages/dialog/index","type":"page","style":{"navigationBarTitleText":"Dialog"}},{"path":"feedback/pages/drag/index","type":"page","style":{"navigationBarTitleText":"Drag"}},{"path":"feedback/pages/infiniteloading/index","type":"page","style":{"navigationBarTitleText":"InfiniteLoading"}},{"path":"feedback/pages/notify/index","type":"page","style":{"navigationBarTitleText":"Notify"}},{"path":"feedback/pages/swipe/index","type":"page","style":{"navigationBarTitleText":"Swipe"}},{"path":"feedback/pages/switch/index","type":"page","style":{"navigationBarTitleText":"Switch"}},{"path":"feedback/pages/toast/index","type":"page"},{"path":"layout/pages/divider/index","type":"page","style":{"navigationBarTitleText":"Divider"}},{"path":"layout/pages/grid/index","type":"page","style":{"navigationBarTitleText":"Grid"}},{"path":"layout/pages/layout/index","type":"page","style":{"navigationBarTitleText":"Layout"}},{"path":"layout/pages/sticky/index","type":"page","style":{"navigationBarTitleText":"Sticky"}},{"path":"nav/pages/elevator/index","type":"page","style":{"navigationBarTitleText":"Elevator"}},{"path":"nav/pages/fixednav/index","type":"page","style":{"navigationBarTitleText":"Fixednav"}},{"path":"nav/pages/indicator/index","type":"page","style":{"navigationBarTitleText":"Indicator"}},{"path":"nav/pages/menu/index","type":"page","style":{"navigationBarTitleText":"Menu"}},{"path":"nav/pages/navbar/index","type":"page","style":{"navigationBarTitleText":"NavBar"}},{"path":"nav/pages/pagination/index","type":"page","style":{"navigationBarTitleText":"Pagination"}},{"path":"nav/pages/sidenavbar/index","type":"page","style":{"navigationBarTitleText":"SideNavbar"}},{"path":"nav/pages/tabbar/index","type":"page","style":{"navigationBarTitleText":"TabBar"}}]}]}
{"easycom":{"autoscan":true,"custom":{}},"globalStyle":{"navigationBarBackgroundColor":"@navBgColor","navigationBarTextStyle":"@navTxtStyle","navigationBarTitleText":"NutUi","backgroundColor":"@bgColor","backgroundTextStyle":"@bgTxtStyle","backgroundColorTop":"@bgColorTop","backgroundColorBottom":"@bgColorBottom"},"pages":[{"path":"pages/index/index","type":"home"}],"subPackages":[{"root":"demo","pages":[{"path":"basic/pages/button/index","type":"page","style":{"navigationBarTitleText":"Button"}},{"path":"basic/pages/cell/index","type":"page","style":{"navigationBarTitleText":"Cell"}},{"path":"basic/pages/icon/index","type":"page","style":{"navigationBarTitleText":"Icon"}},{"path":"basic/pages/overlay/index","type":"page","style":{"navigationBarTitleText":"Overlay"}},{"path":"basic/pages/popup/index","type":"page","style":{"navigationBarTitleText":"Popup"}},{"path":"exhibition/pages/avatar/index","type":"page","style":{"navigationBarTitleText":"Avatar"}},{"path":"exhibition/pages/badge/index","type":"page","style":{"navigationBarTitleText":"Badge"}},{"path":"exhibition/pages/countdown/index","type":"page","style":{"navigationBarTitleText":"CountDown"}},{"path":"feedback/pages/actionsheet/index","type":"page","style":{"navigationBarTitleText":"Actionsheet"}},{"path":"feedback/pages/backtop/index","type":"page","style":{"navigationBarTitleText":"BackTop"}},{"path":"feedback/pages/dialog/index","type":"page","style":{"navigationBarTitleText":"Dialog"}},{"path":"feedback/pages/drag/index","type":"page","style":{"navigationBarTitleText":"Drag"}},{"path":"feedback/pages/infiniteloading/index","type":"page","style":{"navigationBarTitleText":"InfiniteLoading"}},{"path":"feedback/pages/notify/index","type":"page","style":{"navigationBarTitleText":"Notify"}},{"path":"feedback/pages/swipe/index","type":"page","style":{"navigationBarTitleText":"Swipe"}},{"path":"feedback/pages/switch/index","type":"page","style":{"navigationBarTitleText":"Switch"}},{"path":"feedback/pages/toast/index","type":"page"},{"path":"layout/pages/divider/index","type":"page","style":{"navigationBarTitleText":"Divider"}},{"path":"layout/pages/grid/index","type":"page","style":{"navigationBarTitleText":"Grid"}},{"path":"layout/pages/layout/index","type":"page","style":{"navigationBarTitleText":"Layout"}},{"path":"layout/pages/sticky/index","type":"page","style":{"navigationBarTitleText":"Sticky"}},{"path":"nav/pages/elevator/index","type":"page","style":{"navigationBarTitleText":"Elevator"}},{"path":"nav/pages/fixednav/index","type":"page","style":{"navigationBarTitleText":"Fixednav"}},{"path":"nav/pages/indicator/index","type":"page","style":{"navigationBarTitleText":"Indicator"}},{"path":"nav/pages/menu/index","type":"page","style":{"navigationBarTitleText":"Menu"}},{"path":"nav/pages/navbar/index","type":"page","style":{"navigationBarTitleText":"NavBar"}},{"path":"nav/pages/pagination/index","type":"page","style":{"navigationBarTitleText":"Pagination"}},{"path":"nav/pages/sidenavbar/index","type":"page","style":{"navigationBarTitleText":"SideNavbar"}},{"path":"nav/pages/tabbar/index","type":"page","style":{"navigationBarTitleText":"TabBar"}},{"path":"nav/pages/tabs/index","type":"page","style":{"navigationBarTitleText":"Tabs"}}]}]}
2 changes: 1 addition & 1 deletion packages/nutui/components/actionsheet/actionsheet.vue
Expand Up @@ -47,7 +47,7 @@ export default defineComponent({
</script>

<template>
<NutPopup :visible="visible" position="bottom" round :close-on-click-overlay="closeAbled" @click-overlay="close">
<NutPopup v-bind="props" :visible="visible" position="bottom" round :close-on-click-overlay="closeAbled" @click-overlay="close">
<view :class="classes">
<view v-if="title" class="nut-action-sheet__title">
{{ title }}
Expand Down
4 changes: 2 additions & 2 deletions packages/nutui/components/col/index.scss
Expand Up @@ -16,10 +16,10 @@

@for $i from 1 through 24 {
.nut-col-offset-#{$i} {
margin-left: calc(100 / 24) * $i * 1%;
margin-left: calc((100 / 24) * #{$i} * 1%);
}

.nut-col-#{$i} {
width: calc(100 / 24) * $i * 1%;
width: calc((100 / 24) * #{$i} * 1%);
}
}
2 changes: 2 additions & 0 deletions packages/nutui/components/index.ts
Expand Up @@ -37,3 +37,5 @@ export type * from './tabbaritem'
export type * from './badge'
export type * from './avatar'
export type * from './avatargroup'
export type * from './tabs'
export type * from './tabpane'
22 changes: 11 additions & 11 deletions packages/nutui/components/row/row.vue
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { defineComponent, provide } from 'vue'
import { computed, defineComponent, provide } from 'vue'
import { PREFIX } from '../_utils'
import { rowProps } from './row'
Expand All @@ -11,15 +11,15 @@ provide('gutter', props.gutter)
function getClass(prefix: string, type: string) {
return prefix ? (type ? `nut-row-${prefix}-${type}` : '') : `nut-row-${type}`
}
function getClasses() {
return `
${getClass('', props.type)}
${getClass('justify', props.justify)}
${getClass('align', props.align)}
${getClass('flex', props.flexWrap)}
${prefixCls}
`
}
const classes = computed(() => {
return [
prefixCls,
getClass('', props.type),
getClass('justify', props.justify),
getClass('align', props.align),
getClass('flex', props.flexWrap),
]
})
</script>

<script lang="ts">
Expand All @@ -32,7 +32,7 @@ export default defineComponent({
</script>

<template>
<view :class="getClasses()">
<view :class="classes">
<slot />
</view>
</template>
Expand Down
22 changes: 22 additions & 0 deletions packages/nutui/components/tabpane/index.scss
@@ -0,0 +1,22 @@
.nut-theme-dark {
.nut-tab-pane {
background: $dark-background2;
}
}

.nut-tab-pane {
box-sizing: border-box;
display: block;
flex-shrink: 0;
width: 100%;
height: 100%;
padding: 24px 20px;
overflow: auto;
word-break: break-all;
background-color: #fff;

&.inactive {
height: 0;
overflow: visible;
}
}
1 change: 1 addition & 0 deletions packages/nutui/components/tabpane/index.ts
@@ -0,0 +1 @@
export * from './tabpane'

0 comments on commit e31e9f5

Please sign in to comment.