Search K
Appearance
👍欢迎大家积极投稿交流👍
如果文档内容陈旧或者链接失效,请发现后及时同步,我将尽快修改
👇微信👇

Appearance
得益于 @uni-helper/vite-plugin-uni-layouts,你可以轻松地切换不同的布局。
src/layouts 文件夹下的 vue 文件都会自动生成一个布局,默认的布局文件名为 default ,路径 src/layouts/default.vue 。
如果需要修改使用的布局,可以通过 vue 文件内 route 代码块指定需要的布局,如下示例使用 demo 布局。
不推荐json5的写法
新版的 definePage 具有更高的灵活性和可读性。
<route lang="json5">
{
layout: 'navbar',
style: {
navigationBarTitleText: '关于',
},
}
</route>
<script lang="ts" setup>
// JS逻辑
</script>
<template>
<view>
<!-- 这里可以写通用的布局,比如导航栏,tabbar 等 -->
<!-- slot里面装的就是子页面的内容 -->
<slot />
</view>
</template>👍 推荐写法
2025-08-28 更新, route-block 在 v3.12.0 已被 definePage 替代。
<script lang="ts" setup>
definePage({
layout: 'navbar',
style: {
navigationBarTitleText: '关于',
},
})
</script>
<template>
<view>
<!-- 这里可以写通用的布局,比如导航栏,tabbar 等 -->
<!-- slot里面装的就是子页面的内容 -->
<slot />
</view>
</template>模板项目中除了默认的 default 布局,还提供了 navbar 布局,主要是用于自定义导航以及页面在顶部时为透明背景,当页面在滚动的时候,有透明背景变为指定颜色或者图片的效果,效果如下:

- 在使用这个自定义布局时,需要在
vue文件内definePage禁用layout,直接使用navbar无法传递参数- 模板中使用
uni-layout组件通过name属性指定布局为navbar来实现效果。
<script setup lang="ts">
definePage({
layout: false,
style: {
navigationBarTitleText: '关于',
},
})
// 因使用 AutoImport 自动引入的方式,需要在页面内调用 onPageScroll 事件,不处理回调即可,组件中已处理相应事件
onPageScroll(() => {})
</script>
<template>
<uni-layout
ref="uniLayout"
name="navbar"
title="标题"
:placeholder="true"
:fixed="true"
navbar-style="background: 'linear-gradient(180deg, #d14328 0%, #a83220 100%)'"
>
<!-- 页面内容 -->
</uni-layout>
</template><script setup lang="ts">
definePage({
layout: false,
style: {
navigationBarTitleText: '关于',
},
})
// 定义 uni-layout 组件 Ref
const uniLayout = ref()
// 处理滚动事件
const handleScroll = (e) => {
// 调用 uni-layout 组件的 setPageScroll 方法设置滚动距离
uniLayout.value?.setPageScroll(e.detail.scrollTop)
}
</script>
<template>
<uni-layout
ref="uniLayout"
name="navbar"
title="标题"
:placeholder="true"
:fixed="true"
use-scroll-view
navbar-style="background: 'linear-gradient(180deg, #d14328 0%, #a83220 100%)'"
>
<!-- 页面内容 -->
<scroll-view scroll-y @scroll="handleScroll">
<!-- 内容 -->
</scroll-view>
</uni-layout>
</template>| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| name | string | default | 布局名称,需要设置为 navbar |
| title | string | 导航栏标题 | |
| bordered | boolean | true | 是否显示边框 |
| fixed | boolean | true | 是否固定导航栏 |
| placeholder | boolean | true | 是否显示占位符 |
| safeAreaInsetTop | boolean | true | 是否顶部安全区域 |
| useScrollView | boolean | true | 是否使用 scroll-view,启用后页面的 onPageScroll 事件失效 |
| distance | number | 200 | 导航栏背景完全显示需要滚动的距离,单位 px |
| navbarStyle | string/CSSProperties | 导航栏自定义样式(字符串或者样式对象类型) | |
| customStyle | string/CSSProperties | navbar 组件自定义样式(字符串或者样式对象类型)基本不用,主要用 navbarStyle 控制显示效果 |
在 navbar 布局中,传入组件的插槽,因组件使用 v-if="$slots.capsule" 的方式做判断,当自定义组件使用 <template v-if="capsule" #capsule></template> 时,v-if="$slots.capsule" 一直为 true ,并不能通过 v-if 动态控制是否使用当前插槽,在网页端可以通过动态插槽的方式解决,在小程序端不支持。目前有两种解决方案,不过都有一定的局限性,具体方法参考如下:
将 wot-ui 改为 uni_modules 的安装方式,然后修改 wd-navbar 组件,将需要使用的插槽,添加通过 props 传参一起控制是否显示,示例代码如下:
<template>
<!-- 只展示部分代码 -->
<view class="wd-navbar__capsule" v-if="$slots.capsule">
<view class="wd-navbar__capsule" v-if="useCapsuleSlot && $slots.capsule">
<slot name="capsule" />
</view>
</template>
<script setup lang="ts">
import { navbarProps } from './types'
const props = defineProps(navbarProps)
</script>export const navbarProps = {
...baseProps,
/**
* 标题文字
*/
title: String,
// ..... 忽略中间代码
/**
* 是否使用胶囊插槽
*/
useCapsuleSlot: makeBooleanProp(false),
// 下边俩视情况决定
/**
* 是否使用标题插槽
*/
useTitleSlot: makeBooleanProp(false),
/**
* 是否使用左侧插槽
*/
useLeftSlot: makeBooleanProp(false),
/**
* 是否使用右侧插槽
*/
useRightSlot: makeBooleanProp(false),
}针对网页端使用,除了小程序端不支持,APP 端未测试,不确定是否支持,有使用过并且可行的话,可以告知
<script setup lang="ts">
// 只展示部分代码,其他代码参考原组件
import { computed, useSlots } from 'vue'
// 获取所有传入的插槽然后处理为所需要的插槽
const delegatedSlots = computed(() => {
// 获取所有传入的插槽
const slots = useSlots()
const resultSlots: string[] = []
for (const key of Object.keys(slots)) {
// 排除默认插槽
if (key !== 'default') {
resultSlots.push(key)
}
}
// 如果使用胶囊插槽,添加胶囊插槽
if (props.capsule) {
resultSlots.push('capsule')
}
return resultSlots
})
</script>
<template>
<!-- 只展示部分代码 -->
<wd-navbar
:title="title"
:left-arrow="leftArrow"
:left-text="leftText"
:safe-area-inset-top="safeAreaInsetTop"
:bordered="bordered"
:custom-style="navbarCustomStyle"
@click-left="handleBack"
>
<template v-for="slotName in delegatedSlots" :key="slotName" #[slotName]>
<template v-if="slotName === 'capsule'">
<wd-navbar-capsule @back="handleBack" @back-home="handleBackHome" />
</template>
<slot v-else :name="slotName" />
</template>
</wd-navbar>
</template>