Skip to content

nax-tabs

当前版本:0.1.12

顶部标签导航(内容切换条)。面向 uni-app x:数据驱动、可横向滚动/均分宽度、主题色指示条、轻量徽标。只负责导航 UI,内容区由页面自管。

安装

easycom 自动生效,页面直接使用 <nax-tabs /> 即可。

建议同时安装主题包 uni_modules/nax-ui-theme 并在 App.uvue 引入主题变量,详见 主题接入

代码示例

用法
uvue
<template>
  <view class="page">
    <nax-tabs v-model="current" :list="tabs" @change="onChange" />
    <view v-if="current === 0">关注</view>
    <view v-else-if="current === 1">推荐</view>
    <view v-else>热榜</view>
  </view>
</template>

<script setup lang="uts">
const current = ref(0)
const tabs = [
  { name: '关注', badge: 3 },
  { name: '推荐' },
  { name: '热榜', dot: true },
  { name: '已下线', disabled: true }
]

function onChange(index: number) {
  console.log('tab', index)
}
</script>
基础 + 内容联动
uvue
<nax-tabs v-model="basicCurrent" :list="basicList" @change="onBasicChange" @click="onBasicClick"></nax-tabs>
uts
const basicCurrent = ref(0)
const lastEvent = ref('')

const basicList = [
	{ name: '关注' },
	{ name: '推荐' },
	{ name: '热榜' }
]

function onBasicChange(index : number) {
	lastEvent.value = 'change → ' + index.toString()
}

function onBasicClick(index : number) {
	lastEvent.value = 'click → ' + index.toString()
}
可滚动(多项)· 居中 scrollAlign=center
uvue
<nax-tabs v-model="scrollCurrent" :list="scrollList" :scrollable="true" scroll-align="center"></nax-tabs>
uts
const scrollCurrent = ref(1)

const scrollList = [
	{ name: '关注' },
	{ name: '推荐' },
	{ name: '热榜' },
	{ name: '同城' },
	{ name: '直播' },
	{ name: '影视' },
	{ name: '游戏' },
	{ name: '音乐' },
	{ name: '科技' },
	{ name: '更多' }
]
可滚动 · 贴左 scrollAlign=left
uvue
<nax-tabs v-model="scrollLeftCurrent" :list="scrollList" :scrollable="true" scroll-align="left"></nax-tabs>
uts
const scrollLeftCurrent = ref(4)

// scrollList 同上:10 项可滚动列表
均分宽度
uvue
<nax-tabs v-model="equalCurrent" :list="equalList" :scrollable="false"></nax-tabs>

<nax-button size="sm" label="选中 0" @click="setEqual(0)"></nax-button>
<nax-button size="sm" label="选中 1" @click="setEqual(1)"></nax-button>
<nax-button size="sm" label="选中 2" @click="setEqual(2)"></nax-button>
uts
const equalCurrent = ref(0)

const equalList = [
	{ name: '全部' },
	{ name: '待付款' },
	{ name: '已完成' }
]

function setEqual(index : number) {
	equalCurrent.value = index
}
徽标 / 红点 / 禁用
uvue
<nax-tabs v-model="badgeCurrent" :list="badgeList" :scrollable="false"></nax-tabs>

<nax-button size="sm" label="消息+1" @click="incBadge"></nax-button>
<nax-button size="sm" label="重置徽标" @click="resetBadge"></nax-button>
uts
const badgeCurrent = ref(0)
const msgBadge = ref(5)

const badgeList = computed((): any[] => {
	return [
		{ name: '消息', badge: msgBadge.value },
		{ name: '动态', dot: true },
		{ name: '下线', disabled: true },
		{ name: '我的' }
	] as any[]
})

function incBadge() {
	msgBadge.value = msgBadge.value + 1
}

function resetBadge() {
	msgBadge.value = 5
}
尺寸 size
uvue
<nax-tabs v-model="sizeCurrent" :list="sizeList" size="sm" :scrollable="false"></nax-tabs>
<nax-tabs v-model="sizeCurrent" :list="sizeList" size="md" :scrollable="false"></nax-tabs>
<nax-tabs v-model="sizeCurrent" :list="sizeList" size="lg" :scrollable="false"></nax-tabs>
uts
const sizeCurrent = ref(0)

const sizeList = [
	{ name: '选项A' },
	{ name: '选项B' },
	{ name: '选项C' }
]
指示条宽度 / 无指示条
uvue
<nax-tabs v-model="lineCurrent" :list="equalList" :scrollable="false" line-width="40"></nax-tabs>
<nax-tabs v-model="lineCurrent" :list="equalList" :scrollable="false" :show-line="false"></nax-tabs>
uts
const lineCurrent = ref(1)

// equalList 同「均分宽度」:3 项均分
字符串 list + keyName
uvue
<nax-tabs v-model="strCurrent" :list="strList" :scrollable="false"></nax-tabs>
<nax-tabs v-model="keyCurrent" :list="keyList" key-name="title" :scrollable="false"></nax-tabs>
uts
const strCurrent = ref(0)
const keyCurrent = ref(0)

const strList = ['早报', '午报', '晚报']

const keyList = [
	{ title: '标题一', name: '忽略' },
	{ title: '标题二', name: '忽略' },
	{ title: '标题三', name: '忽略' }
]
无底部分割线
uvue
<nax-tabs v-model="basicCurrent" :list="basicList" :border="false"></nax-tabs>
uts
// basicCurrent / basicList 复用「基础 + 内容联动」的声明

主题

通过 CSS 变量覆盖:

Token用途
--nax-color-bg背景色
--nax-color-border边框色
--nax-color-error错误色
--nax-color-primary主题主色
--nax-color-text-secondary次要文字色

Props

属性类型默认值说明
modelValuenumber0当前选中下标(v-model)
listarray() => [] as any[]项列表(name/text/label/title、badge/count、dot、disabled;支持字符串项)
keyNamestring'name'文案优先字段,默认 name
scrollablebooleantrue横向滚动,默认 true;false 均分
scrollAlignstring'center'left 左对齐 | center 居中;默认 centerleft 为必要时贴左并露出前一项
showLinebooleantrue指示条,默认 true
lineWidthstring'20'指示条宽,默认 20(px)
lineHeightstring'3'指示条高,默认 3(px)
sizestring'md'sm 小 | md 中 | lg 大;默认 md
borderbooleantrue底部分割线,默认 true
durationnumber300指示条过渡 ms,默认 300
stickybooleanfalseCSS sticky 吸顶(Web/小程序;App 端不支持),默认 false
offsetTopstring'0'sticky top,默认 0
badgeMaxnumber99徽标数字上限,默认 99
customClassstring''根扩展 class

list 项字段

字段说明
name / text / label / title文案(keyName 优先)
badge / count数字或文本徽标
dot / isDot红点
disabled禁用

字符串项也可:list={['关注','推荐']}

Events

事件说明
update:modelValuev-model 选中下标
change选中下标变化
click点击项(含重复点同一项;禁用项不触发)

全屏选项卡方案实现

不提供独立的 nax-tabs-swiper 组件。全屏选项卡 = nax-tabs + 原生 swiper 组合:

  1. 共用一个 current(tabs 用 v-model,swiper 用 :current + @change
  2. swiper 关闭 circular,避免下标与 Tab 语义错位
  3. 内容区高度 = 窗口高度 − tabs 高度;每页内用 scroll-view 单独滚动
  4. 业务负责懒加载、嵌套列表、空状态等,不要塞进导航组件
uvue
<template>
  <view class="page">
    <nax-tabs v-model="current" :list="tabs" />
    <swiper
      :current="current"
      :circular="false"
      :style="'height:' + contentH + 'px'"
      @change="onSwiperChange"
    >
      <swiper-item>
        <scroll-view scroll-y :style="'height:' + contentH + 'px'">
          <!-- 面板 0 -->
        </scroll-view>
      </swiper-item>
      <swiper-item>
        <scroll-view scroll-y :style="'height:' + contentH + 'px'">
          <!-- 面板 1 -->
        </scroll-view>
      </swiper-item>
    </swiper>
  </view>
</template>

<script setup lang="uts">
const current = ref(0)
const contentH = ref(400)
const tabs = [{ name: '关注' }, { name: '推荐' }]

function onSwiperChange(e: UniSwiperChangeEvent) {
  current.value = e.detail.current
}
</script>