NavigationBar 导航栏

该组件目前处于实验性状态,需要进行更加严密的测试,API 也可能发生比较大的变动

我是谁,我从哪里来,我要到哪里去

import { DuNavigationBar } from 'dangoui'

说明

  1. 在小程序中使用 right 插槽时,如果你传递给 slot 为一个节点并且为 view,请务必给这个 view 添加一个 class
  2. 在小程序上,页面栈的第一个页面返回按钮会显示为 home 图标
  3. scoped-leftscoped-defaultscoped-right 对应 leftdefaultright,用于接收像 opacity 这种参数,之所以有这样的插槽受限于在 uni-app 中使用作用域插槽,必须添加 v-slot(也许后续会改掉,这个时候就不需要 scoped-xxx 这样的插槽了)
  4. DuActionButton 目前只能用于 DuNavigationBar 的右侧插槽

示例

各种类型
<template>
  <div class="min-h-screen bg-white">
    <div class="mb-16px">
      <DuNavigationBar share @share="handleShare">
        标题
        <template #right>
          <DuButton size="small" type="outline" color="default">按钮</DuButton>
        </template>
      </DuNavigationBar>
    </div>
    <div class="mb-16px">
      <DuNavigationBar share @share="handleShare">
        标题
        <template #right>
          <DuActionButton name="refresh" />
        </template>
      </DuNavigationBar>
    </div>
    <div class="mb-16px">
      <DuNavigationBar back-icon="room" @share="handleShare">
        左边是首页按钮
      </DuNavigationBar>
    </div>
    <div class="mb-16px">
      <DuNavigationBar share @share="handleShare">
        <div>标题</div>
          <div class="flex-auto w-0">
            <DuSearch bg="white" :placeholder="placeholders" readonly>
              <template #right>
                <DuIcon name="camera" />
                <DuDivider />
                <DuIcon name="scanning" />
              </template>
            </DuSearch>
          </div>
      </DuNavigationBar>
    </div>
    <div class="mb-16px">
      <DuNavigationBar share color="secondary" :back="false" @share="handleShare">
          <div>标题</div>
          <div class="flex-auto w-0">
          <DuSearch bg="white" placeholder="Labubu">
            <template #right>
              <DuIcon name="camera" />
              <DuDivider />
              <DuIcon name="scanning" />
            </template>
          </DuSearch>
          </div>
      </DuNavigationBar>
    </div>
    <div class="mb-16px">
      <DuNavigationBar share color="primary" :back="false" @share="handleShare">
          <div>标题</div>
          <div class="flex-auto w-0">
          <DuSearch bg="white" placeholder="Labubu">
            <template #right>
              <DuIcon name="camera" />
              <DuDivider />
              <DuIcon name="scanning" />
            </template>
          </DuSearch>
          </div>
      </DuNavigationBar>
    </div>
    <div class="mb-16px">
      <DuNavigationBar center>
        <DuTabs size="large" v-model:value="tab">
          <DuTab name="discovery">发现岛</DuTab>
          <DuTab name="joined">我的岛</DuTab>
        </DuTabs>
      </DuNavigationBar>
    </div>
    <div class="mb-16px">
      <DuNavigationBar center color="white">
        <DuTabs size="large" v-model:value="tab">
          <DuTab name="discovery">发现岛</DuTab>
          <DuTab name="joined">我的岛</DuTab>
        </DuTabs>
      </DuNavigationBar>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { DuNavigationBar, DuButton, DuSearch, DuIcon, DuDivider, DuTabs, DuTab, DuActionButton } from 'dangoui'

const placeholders = [
  'Molly',
  'Labubu',
  'Skullpanda'
]

const tab = ref('discovery')

function handleShare() {
  console.log('[demo] share')
}
</script>
0
固定在顶部

使用 fixed 将导航栏固定在顶部,同时你也可以使用 placeholder 给一个占位空间,这样你的内容就不会被导航栏覆盖了

右侧向下滚动试试

<template>
  <DuNavigationBar share fixed placeholder @share="handleShare">
      <div>标题</div>
          <div class="flex-auto w-0">
          <DuSearch bg="white" placeholder="Labubu">
            <template #right>
              <DuIcon name="camera" />
              <DuDivider />
              <DuIcon name="scanning" />
            </template>
          </DuSearch>
          </div>
  </DuNavigationBar>
  <div class="w-full h-200px bg-red-200 flex justify-center items-center text-48px">
    1
  </div>
  <div class="w-full h-200px bg-orange-200 flex justify-center items-center text-48px">
    2
  </div>
  <div class="w-full h-200px bg-yellow-200 flex justify-center items-center text-48px">
    3
  </div>
  <div class="w-full h-200px bg-green-200 flex justify-center items-center text-48px">
    4
  </div>
  <div class="w-full h-200px bg-blue-200 flex justify-center items-center text-48px">
    5
  </div>
</template>

<script setup lang="ts">
import { DuNavigationBar, DuButton, DuSearch, DuIcon, DuDivider } from 'dangoui'

const placeholders = [
  'Molly',
  'Labubu',
  'Skullpanda'
]

function handleShare() {
  console.log('[demo] share')
}
</script>
0
从透明到不透明

沉浸式的导航栏,滑动到一定的距离才显示导航栏里面的内容

返回按钮和 right 插槽中的内容会一直显示

适合比如商品详情页大图这种场景

<template>
  <DuNavigationBar share fixed :appear-threshold="100" @share="handleShare">
      <div>标题</div>
          <div class="flex-auto w-0">
          <DuSearch bg="white" placeholder="Labubu">
            <template #right>
              <DuIcon name="camera" />
              <DuDivider />
              <DuIcon name="scanning" />
            </template>
          </DuSearch>
          </div>
  </DuNavigationBar>
  <div class="w-full h-200px bg-red-200 flex justify-center items-center text-48px">
    1
  </div>
  <div class="w-full h-200px bg-orange-200 flex justify-center items-center text-48px">
    2
  </div>
  <div class="w-full h-200px bg-yellow-200 flex justify-center items-center text-48px">
    3
  </div>
  <div class="w-full h-200px bg-green-200 flex justify-center items-center text-48px">
    4
  </div>
  <div class="w-full h-200px bg-blue-200 flex justify-center items-center text-48px">
    5
  </div>
</template>

<script setup lang="ts">
import { DuNavigationBar, DuButton, DuSearch, DuIcon, DuDivider } from 'dangoui'

const placeholders = [
  'Molly',
  'Labubu',
  'Skullpanda'
]

function handleShare() {
  console.log('[demo] share')
}
</script>
0
从透明到不透明总是显示内容

默认情况下,透明情况下不会显示内容插槽(default slot),你可以通过 always-show-content 总是展示 default slot

<template>
  <DuNavigationBar share fixed :appear-threshold="100" always-show-content color="white" @share="handleShare">
    <div class="flex items-center text-12px font-medium gap-x-4px">
      <div class="w-16px h-16px rd-full overflow-hidden">
        <DuImage src="https://cdn.qiandaoapp.com/interior/images/ce1765477a674788b0f6286d0aba6d9f.jpg" />
      </div>
      <span>千岛观影团</span>
      <DuIcon name="arrow-heavy-right" :size="8" />
    </div>
  </DuNavigationBar>
  <div class="w-full h-200px bg-red-200 flex justify-center items-center text-48px">
    1
  </div>
  <div class="w-full h-200px bg-orange-200 flex justify-center items-center text-48px">
    2
  </div>
  <div class="w-full h-200px bg-yellow-200 flex justify-center items-center text-48px">
    3
  </div>
  <div class="w-full h-200px bg-green-200 flex justify-center items-center text-48px">
    4
  </div>
  <div class="w-full h-200px bg-blue-200 flex justify-center items-center text-48px">
    5
  </div>
</template>

<script setup lang="ts">
import { DuNavigationBar, DuButton, DuSearch, DuIcon, DuDivider, DuImage } from 'dangoui'

const placeholders = [
  'Molly',
  'Labubu',
  'Skullpanda'
]

function handleShare() {
  console.log('[demo] share')
}
</script>
0
指定透明时候的前景色

在一些情况下,透明状态的前景色和非透明状态下的前景色是不同的,你可以通过 transparent-front-color 指定透明状态下的前景色

如果你没给你的元素指定 color,就会集成对应透明度下的前景色

更进阶地,你还可以通过 scoped-left 插槽、scope-default 插槽和 scope-right 插槽获取当前的 opacity 来进一步支持在对应 opacity 下的样式

<template>
  <DuNavigationBar share fixed :appear-threshold="150" always-show-content color="white" @share="handleShare" transparent-front-color="white">
    <div class="flex items-center text-12px font-medium gap-x-4px">
      <div class="w-16px h-16px rd-full overflow-hidden">
        <DuImage src="https://cdn.qiandaoapp.com/interior/images/ce1765477a674788b0f6286d0aba6d9f.jpg" />
      </div>
      <span>千岛观影团</span>
      <DuIcon name="arrow-heavy-right" :size="8" />
    </div>
  </DuNavigationBar>
  <div class="w-full h-200px bg-black bg-op-80 flex justify-center items-center text-48px">
    1
  </div>
  <div class="w-full h-200px bg-orange-200 flex justify-center items-center text-48px">
    2
  </div>
  <div class="w-full h-200px bg-yellow-200 flex justify-center items-center text-48px">
    3
  </div>
  <div class="w-full h-200px bg-green-200 flex justify-center items-center text-48px">
    4
  </div>
  <div class="w-full h-200px bg-blue-200 flex justify-center items-center text-48px">
    5
  </div>
</template>

<script setup lang="ts">
import { DuNavigationBar, DuButton, DuSearch, DuIcon, DuDivider, DuImage } from 'dangoui'

const placeholders = [
  'Molly',
  'Labubu',
  'Skullpanda'
]

function handleShare() {
  console.log('[demo] share')
}
</script>
0
使用 scoped-xxx
<template>
  <DuNavigationBar share fixed :appear-threshold="150" always-show-content color="white" @share="handleShare" transparent-front-color="white">
    <template #scoped-default="{ opacity }">
      <div class="flex items-center text-12px font-medium gap-x-4px">
        <div class="w-16px h-16px rd-full overflow-hidden">
          <DuImage src="https://cdn.qiandaoapp.com/interior/images/ce1765477a674788b0f6286d0aba6d9f.jpg" />
        </div>
        <span v-if="opacity > 0.8">千岛观影团</span>
        <DuIcon v-if="opacity > 0.8" name="arrow-heavy-right" :size="8" />
      </div>
    </template>
  </DuNavigationBar>
  <div class="w-full h-200px bg-black bg-op-80 flex justify-center items-center text-48px">
    1
  </div>
  <div class="w-full h-200px bg-orange-200 flex justify-center items-center text-48px">
    2
  </div>
  <div class="w-full h-200px bg-yellow-200 flex justify-center items-center text-48px">
    3
  </div>
  <div class="w-full h-200px bg-green-200 flex justify-center items-center text-48px">
    4
  </div>
  <div class="w-full h-200px bg-blue-200 flex justify-center items-center text-48px">
    5
  </div>
</template>

<script setup lang="ts">
import { DuNavigationBar, DuButton, DuSearch, DuIcon, DuDivider, DuImage } from 'dangoui'

const placeholders = [
  'Molly',
  'Labubu',
  'Skullpanda'
]

function handleShare() {
  console.log('[demo] share')
}
</script>
0
使用 scoped-xxx(配合 DuTransition)
<template>
  <DuNavigationBar share fixed :appear-threshold="150" always-show-content color="white" @share="handleShare" transparent-front-color="white">
    <template #scoped-default="{ opacity }">
      <view v-if="opacity < 0.8">一起来看电影吧</view>
      <DuTransition v-else>
        <div class="flex items-center text-12px font-medium gap-x-4px">
          <div class="w-16px h-16px rd-full overflow-hidden">
            <DuImage src="https://cdn.qiandaoapp.com/interior/images/ce1765477a674788b0f6286d0aba6d9f.jpg" />
          </div>
          <span>千岛观影团</span>
          <DuIcon name="arrow-heavy-right" :size="8" />
        </div>
      </DuTransition>
    </template>
  </DuNavigationBar>
  <div class="w-full h-200px bg-black bg-op-80 flex justify-center items-center text-48px">
    1
  </div>
  <div class="w-full h-200px bg-orange-200 flex justify-center items-center text-48px">
    2
  </div>
  <div class="w-full h-200px bg-yellow-200 flex justify-center items-center text-48px">
    3
  </div>
  <div class="w-full h-200px bg-green-200 flex justify-center items-center text-48px">
    4
  </div>
  <div class="w-full h-200px bg-blue-200 flex justify-center items-center text-48px">
    5
  </div>
</template>

<script setup lang="ts">
import { DuNavigationBar, DuButton, DuSearch, DuIcon, DuDivider, DuImage, DuTransition } from 'dangoui'

const placeholders = [
  'Molly',
  'Labubu',
  'Skullpanda'
]

function handleShare() {
  console.log('[demo] share')
}
</script>
0
始终透明的导航栏
<template>
  <DuNavigationBar fixed color="white" @share="handleShare" transparent-front-color="white" transparent>
    始终透明
    <template #right>
      <DuActionButton name="refresh" />
    </template>
  </DuNavigationBar>
  <div class="w-full h-200px bg-black bg-op-80 flex justify-center items-center text-48px c-white">
    1
  </div>
  <div class="w-full h-200px bg-orange flex justify-center items-center text-48px c-white">
    2
  </div>
  <div class="w-full h-200px bg-yellow flex justify-center items-center text-48px c-white">
    3
  </div>
  <div class="w-full h-200px bg-green flex justify-center items-center text-48px c-white">
    4
  </div>
  <div class="w-full h-200px bg-blue flex justify-center items-center text-48px c-white">
    5
  </div>
</template>

<script setup lang="ts">
import { DuNavigationBar, DuButton, DuSearch, DuIcon, DuDivider, DuImage, DuActionButton } from 'dangoui'

const placeholders = [
  'Molly',
  'Labubu',
  'Skullpanda'
]

function handleShare() {
  console.log('[demo] share')
}
</script>
0

API

属性

属性名类型默认值说明
colorstring"default"颜色
centerbooleanfalse内容是否居中,目前需要自行保证内容不溢出
sharebooleanfalse是否显示分享按钮
backbooleantrueback
always-show-contentbooleanfalse即使滑动距离小于 `appearThreshold`,也一直显示内容
placeholderboolean - 固定在顶部时候有一个占位
back-iconstring - 返回按钮,在小程序平台不指定会根据页面所在层级自动判断
fixedboolean - 是否固定在顶部
transparent-front-color"black" | "white" - 前景色
transparentboolean - 是否一直是透明样式
appear-thresholdnumber - 透明到显示的阈值,只有在 fixed 的时候有效,单位为 px?(没想好)

插槽

名称
left
scoped-left
default
scoped-default
right
scoped-right

事件

名称类型
share(event: "share"): void
本页包含