Repository: Tencent/tdesign-mobile-vue
Pull request #391 (2022-10-10 02:24:25)

Refactor/navbar: 重构NavBar组件
#347 

<!--
首先，感谢你的贡献！😄
请阅读并遵循 [TDesign 贡献指南](https://github.com/Tencent/tdesign/blob/main/docs/contributing.md)，填写以下 pull request 的信息。
PR 在维护者审核通过后会合并，谢谢！
-->

### 🤔 这个 PR 的性质是？

- [ ] 日常 bug 修复
- [x] 新特性提交
- [x] 文档改进
- [x] 演示代码改进
- [ ] 组件样式/交互改进
- [ ] CI/CD 改进
- [x] 重构
- [ ] 代码风格优化
- [x] 测试用例
- [ ] 分支合并
- [ ] 其他

### 🔗 相关 Issue

<!--
1. 描述相关需求的来源，如相关的 issue 讨论链接。
-->
[navbar重构](https://github.com/Tencent/tdesign-mobile-vue/issues/347)

### 💡 需求背景和解决方案

<!--
1. 要解决的具体问题。
2. 列出最终的 API 实现和用法。
3. 涉及UI/交互变动需要有截图或 GIF。
-->
组件API文档不规范，需要重新生成文档，重构组件

### 📝 更新日志

<!--
从用户角度描述具体变化，以及可能的 breaking change 和其他风险。
-->

- refactor(navbar): 重构组件，包括API、文档和交互

- [ ] 本条 PR 不需要纳入 Changelog

### ☑️ 请求合并前的自查清单

⚠️ 请自检并全部**勾选全部选项**。⚠️

- [x] 文档已补充或无须补充
- [x] 代码演示已提供或无须提供
- [x] TypeScript 定义已补充或无须补充
- [x] Changelog 已提供或无须提供


github-actions[bot]: [<img height="96" alt="失败" src="https://user-images.githubusercontent.com/5378891/75333447-1e63a280-58c1-11ea-975d-235367fd1522.png">](https://github.com/Tencent/tdesign-mobile-vue/actions/runs/3216501318)
<!-- AUTO_PREVIEW_HOOK -->
anlyyao: 收到～ 我来处理一下ci
anlyyao: @TingShine  辛苦这里在跟进一下～

Patch:
diff --git a/src/navbar/demos/base.vue b/src/navbar/demos/base.vue
index 64d4f81b..7c6d50cc 100644
--- a/src/navbar/demos/base.vue
+++ b/src/navbar/demos/base.vue
@@ -1,9 +1,9 @@
 <template>
-  <div>
-    <div class="tdesign-demo-block">
-      <t-navbar> 界面标题 </t-navbar>
-    </div>
-  </div>
+  <t-navbar title="标题" left-icon :fixed="false" @left-click="handleClick" />
 </template>
 
-<script lang="ts" setup></script>
+<script lang="ts" setup>
+const handleClick = () => {
+  console.log('left-click');
+};
+</script>
diff --git a/src/navbar/demos/event.vue b/src/navbar/demos/event.vue
deleted file mode 100644
index ab8fd6a7..00000000
--- a/src/navbar/demos/event.vue
+++ /dev/null
@@ -1,36 +0,0 @@
-<template>
-  <div>
-    <div class="tdesign-demo-block">
-      <t-navbar @click-text="onClickText" @click-right="onClickMore">
-        界面标题
-        <template #left>
-          <t-icon name="close" @click="onClickLeft"></t-icon>
-        </template>
-      </t-navbar>
-    </div>
-  </div>
-</template>
-
-<script lang="ts">
-import { defineComponent } from 'vue';
-
-export default defineComponent({
-  setup() {
-    return {};
-  },
-  methods: {
-    onClickMore() {
-      this.$toast('Click More');
-      console.log('on click more');
-    },
-    onClickText() {
-      this.$toast('Click Text');
-      console.log('on click Text');
-    },
-    onClickLeft() {
-      this.$toast('Click close');
-      console.log('on click left');
-    },
-  },
-});
-</script>
diff --git a/src/navbar/demos/icon.vue b/src/navbar/demos/icon.vue
deleted file mode 100644
index 1668e98a..00000000
--- a/src/navbar/demos/icon.vue
+++ /dev/null
@@ -1,16 +0,0 @@
-<template>
-  <div>
-    <div class="tdesign-demo-block">
-      <t-navbar>
-        导航栏 - 带icon
-        <template #right>
-          <sound-icon></sound-icon>
-        </template>
-      </t-navbar>
-    </div>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { SoundIcon } from 'tdesign-icons-vue-next';
-</script>
diff --git a/src/navbar/demos/left-icon.vue b/src/navbar/demos/left-icon.vue
new file mode 100644
index 00000000..c5c25836
--- /dev/null
+++ b/src/navbar/demos/left-icon.vue
@@ -0,0 +1,27 @@
+<template>
+  <t-navbar title="标题" :fixed="false">
+    <template #left-icon>
+      <t-icon size="24px" name="chevron-left" class="btn-left" @click="handleBack" />
+      <t-icon size="24px" name="close" @click="handleClose" />
+    </template>
+    <template #right-icon>
+      <t-icon size="24px" name="ellipsis" @click="handleShowMore" />
+    </template>
+  </t-navbar>
+</template>
+
+<script lang="ts" setup>
+import { Icon as TIcon } from 'tdesign-icons-vue-next';
+
+const handleBack = () => {
+  console.log('back-icon-click');
+};
+
+const handleClose = () => {
+  console.log('close-icon-click');
+};
+
+const handleShowMore = () => {
+  console.log('more-icon-click');
+};
+</script>
diff --git a/src/navbar/demos/mobile.vue b/src/navbar/demos/mobile.vue
index 7e4a49f7..f6420bb9 100644
--- a/src/navbar/demos/mobile.vue
+++ b/src/navbar/demos/mobile.vue
@@ -1,48 +1,25 @@
 <template>
-  <div class="t-navbar-base-demo">
-    <p class="divide-line"></p>
-    <t-navbar :right-show="false">界面标题</t-navbar>
-    <p class="divide-line"></p>
-    <t-navbar :right-show="false">
-      <template #left>
-        <t-icon size="24px" name="close" />
-      </template>
-      界面标题
-      <template #right>
-        <t-icon size="24px" name="app" />
-      </template>
-    </t-navbar>
-    <p class="divide-line"></p>
-    <t-navbar>
-      界面标题
-      <template #right>
-        <t-icon size="24px" name="app" />
-      </template>
-    </t-navbar>
+  <div class="tdesign-mobile-demo">
+    <h1 class="title">NavBar 导航栏</h1>
+    <p class="summary">用于不同页面之间切换或者跳转，位于内容区的上方，系统状态栏的下方。</p>
+    <tdesign-demo-block title="01 类型" summary="基础导航栏">
+      <base-demo />
+    </tdesign-demo-block>
+
+    <tdesign-demo-block summary="左侧双操作导航栏">
+      <left-icon-demo />
+    </tdesign-demo-block>
+
+    <tdesign-demo-block summary="右侧双操作导航栏">
+      <right-icon-demo />
+    </tdesign-demo-block>
   </div>
 </template>
 
-<script lang="ts">
-import { defineComponent } from 'vue';
-import { Icon as TIcon } from 'tdesign-icons-vue-next';
-import Toast from '../../toast/index';
-
-export default defineComponent({
-  components: { TIcon },
-  setup() {
-    return {};
-  },
-  methods: {
-    onClickMore() {
-      Toast('Click More');
-      console.log('on click more');
-    },
-    onClickLeft() {
-      Toast('Click close');
-      console.log('on click left');
-    },
-  },
-});
+<script lang="ts" setup>
+import baseDemo from './base.vue';
+import leftIconDemo from './left-icon.vue';
+import rightIconDemo from './right-icon.vue';
 </script>
 
 <style lang="less" scoped>
@@ -51,4 +28,8 @@ export default defineComponent({
   height: 24px;
   background: #f9f9f9;
 }
+
+.btn-left {
+  margin-right: 8px;
+}
 </style>
diff --git a/src/navbar/demos/right-icon.vue b/src/navbar/demos/right-icon.vue
new file mode 100644
index 00000000..d884e298
--- /dev/null
+++ b/src/navbar/demos/right-icon.vue
@@ -0,0 +1,24 @@
+<template>
+  <t-navbar title="标题" left-icon :fixed="false" @left-click="handleBack">
+    <template #right-icon>
+      <t-icon size="24px" name="notification" class="btn-left" @click="handleNotify" />
+      <t-icon size="24px" name="ellipsis" @click="handleShowMore" />
+    </template>
+  </t-navbar>
+</template>
+
+<script lang="ts" setup>
+import { Icon as TIcon } from 'tdesign-icons-vue-next';
+
+const handleBack = () => {
+  console.log('left-click');
+};
+
+const handleNotify = () => {
+  console.log('notification-icon-click');
+};
+
+const handleShowMore = () => {
+  console.log('more-icon-click');
+};
+</script>
diff --git a/src/navbar/navbar.en-US.md b/src/navbar/navbar.en-US.md
new file mode 100644
index 00000000..d49ce9db
--- /dev/null
+++ b/src/navbar/navbar.en-US.md
@@ -0,0 +1,25 @@
+:: BASE_DOC ::
+
+## API
+### Navbar Props
+
+name | type | default | description | required
+-- | -- | -- | -- | --
+animation | Boolean | true |【developing】 | N
+background | String | - | background | N
+fixed | Boolean | true | \- | N
+homeIcon | Boolean / Slot / Function | - | homeIcon。Typescript：`boolean \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
+leftIcon | Boolean / Slot / Function | false | Typescript：`boolean \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
+rightIcon | Slot / Function | - | Typescript：`TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
+title | String / Slot / Function | - | page title。Typescript：`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
+titleMaxLength | Number | - | \- | N
+visible | Boolean | true | \- | N
+onLeftClick | Function |  | Typescript：`(trigger: NavBarTrigger) => void`<br/>[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/navbar/type.ts)。<br/>`type NavBarTrigger = 'home-icon' \| 'left-icon';`<br/> | N
+onRightClick | Function |  | Typescript：`() => void`<br/> | N
+
+### Navbar Events
+
+name | params | description
+-- | -- | --
+left-click | `(trigger: NavBarTrigger)` | [see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/navbar/type.ts)。<br/>`type NavBarTrigger = 'home-icon' \| 'left-icon';`<br/>
+right-click | \- | \-
diff --git a/src/navbar/navbar.md b/src/navbar/navbar.md
index 4c7b0968..b04106fe 100644
--- a/src/navbar/navbar.md
+++ b/src/navbar/navbar.md
@@ -1,25 +1,25 @@
 :: BASE_DOC ::
 
 ## API
+### Navbar Props
 
-| 属性      | 类型    | 默认值 | 必传 | 说明                        |
-| --------- | ------- | ------ | ---- | --------------------------- |
-| title     | String  | 导航栏 | N    | 标题文字                    |
-| leftArrow | Boolean | true   | N    | 是否展示左箭头              |
-| maxLen    | Number  | 6      | N    | 标题文字长度，多余展示`...` |
-| rightShow | Boolean  | true    | N    | 是否展示右侧更多按钮 |
+名称 | 类型 | 默认值 | 说明 | 必传
+-- | -- | -- | -- | --
+animation | Boolean | true | 【开发中】是否添加动画效果 | N
+background | String | - | 背景 | N
+fixed | Boolean | true | 是否固定在顶部 | N
+homeIcon | Boolean / Slot / Function | - | 首页图标。值为 true 表示显示默认返回图标，值为 false 表示不显示首页图标，值为其他表示自定义图标。TS 类型：`boolean \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
+leftIcon | Boolean / Slot / Function | false | 左侧图标。值为 true 表示显示默认返回图标，值为 false 表示不显示左侧图标，值为其他表示自定义图标。TS 类型：`boolean \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
+rightIcon | Slot / Function | - | 右侧图标，可自定义。TS 类型：`TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
+title | String / Slot / Function | - | 页面标题。TS 类型：`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
+titleMaxLength | Number | - | 标题文字最大长度，超出的范围使用 `...` 表示 | N
+visible | Boolean | true | 是否显示 | N
+onLeftClick | Function |  | TS 类型：`(trigger: NavBarTrigger) => void`<br/>点击左侧按钮时触发。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/navbar/type.ts)。<br/>`type NavBarTrigger = 'home-icon' \| 'left-icon';`<br/> | N
+onRightClick | Function |  | TS 类型：`() => void`<br/>点击右侧图标时触发 | N
 
-## Event
+### Navbar Events
 
-| 事件名      | 说明              | 回调参数 |
-| ----------- | ----------------- | -------- |
-| click-right | 点击右侧更多 icon | event    |
-| click-text  | 点击标题文字      | event    |
-
-## Slot
-
-| 插槽名 | 说明             |
-| ------ | ---------------- |
-| left   | 自定义左侧关闭按钮 |
-| right   | 自定义右侧icon |
-| -   | 默认title文案 |
+名称 | 参数 | 描述
+-- | -- | --
+left-click | `(trigger: NavBarTrigger)` | 点击左侧按钮时触发。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/navbar/type.ts)。<br/>`type NavBarTrigger = 'home-icon' \| 'left-icon';`<br/>
+right-click | \- | 点击右侧图标时触发
diff --git a/src/navbar/navbar.vue b/src/navbar/navbar.vue
index daae45fe..b3885a95 100644
--- a/src/navbar/navbar.vue
+++ b/src/navbar/navbar.vue
@@ -1,82 +1,85 @@
 <template>
-  <div :class="name">
-    <div :class="`${name}__back`">
-      <span v-if="leftArrow" :class="`${name}__back--arrow`" @click="handleBack">
+  <div v-show="visible" :class="name" :style="`${navStyle}`">
+    <div v-if="homeContent || leftContent" :class="`${name}__back`">
+      <span v-if="leftIcon === true" :class="`${name}__back--arrow`" @click="handleLeftClick">
         <t-chevron-left-icon />
       </span>
-      <slot name="left"> </slot>
+      <span v-if="homeIcon === true" :class="`${name}__back--arrow`">
+        <t-home-icon />
+      </span>
+      <t-node :content="homeContent"></t-node>
+      <t-node :content="leftContent"></t-node>
     </div>
 
-    <div :class="`${name}__text`" @click="clickText">
-      <slot>{{ nTitleContent }}</slot>
+    <div :class="`${name}__text`">
+      <t-node :content="titleContent"></t-node>
     </div>
 
-    <div :class="`${name}__right`">
-      <slot name="right"> </slot>
-      <i v-if="rightShow" :class="`${name}__right--more`" @click="handleMore">
-        <svg
-          t="1614321969302"
-          class="icon"
-          viewBox="0 0 1024 1024"
-          version="1.1"
-          xmlns="http://www.w3.org/2000/svg"
-          p-id="2091"
-          width="24"
-          height="24"
-        >
-          <path
-            d="M512 449.749333a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m-318.805333-1.109333a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m638.677333 0a64 64 0 1 1 0 128 64 64 0 0 1 0-128z"
-            fill="#444444"
-            p-id="2092"
-          ></path>
-        </svg>
-      </i>
+    <div :class="`${name}__right`" @click="handleRightClick">
+      <t-node :content="rightContent"></t-node>
     </div>
   </div>
 </template>
 <script lang="ts">
-import { computed, defineComponent, SetupContext } from 'vue';
-import { ChevronLeftIcon as TChevronLeftIcon } from 'tdesign-icons-vue-next';
+import { computed, defineComponent, getCurrentInstance, SetupContext, toRefs } from 'vue';
+import { ChevronLeftIcon as TChevronLeftIcon, HomeIcon as THomeIcon } from 'tdesign-icons-vue-next';
 import config from '../config';
-import { NavbarProps } from './navbar.interface';
+import { renderTNode, TNode, useEmitEvent } from '../shared';
+import NavbarProps from './props';
 
 const { prefix } = config;
 const name = `${prefix}-navbar`;
 
 export default defineComponent({
   name,
-  components: { TChevronLeftIcon },
+  components: { TChevronLeftIcon, TNode, THomeIcon },
   props: NavbarProps,
-  emits: ['click-right', 'click-text'],
+  emits: ['left-click', 'right-click'],
   setup(props, context: SetupContext) {
-    const nTitleContent = computed(() => {
-      const { title, maxLen } = props;
-      if (title && title.trim().length > maxLen) {
-        return `${title.slice(0, maxLen)}...`;
+    const internalInstance = getCurrentInstance();
+    const { title, titleMaxLength, fixed, background } = toRefs(props);
+
+    const navStyle = computed(
+      () => `position: ${fixed.value ? 'fixed' : 'relative'}; background: ${background.value || ''};`,
+    );
+
+    const titleContent = computed(() => {
+      if (titleMaxLength.value != null && title.value) {
+        if (titleMaxLength.value <= 0) {
+          console.warn('titleMaxLength must be greater than 0');
+        } else {
+          return title.value.length <= titleMaxLength.value
+            ? props.title
+            : `${(title.value as string).slice(0, titleMaxLength.value)}...`;
+        }
       }
-      return title;
+
+      return renderTNode(internalInstance, 'title');
     });
 
-    const handleBack = () => {
-      if (history.length > 1) {
-        history.back();
-      }
-    };
+    const leftContent = computed(() => renderTNode(internalInstance, 'left-icon'));
+    const rightContent = computed(() => renderTNode(internalInstance, 'right-icon'));
+    const homeContent = computed(() => renderTNode(internalInstance, 'home-icon'));
+
+    const emitEvent = useEmitEvent(props, context.emit);
 
-    const handleMore = (evt: MouseEvent) => {
-      context.emit('click-right', evt);
+    const handleLeftClick = () => {
+      emitEvent('left-click');
     };
 
-    const clickText = (evt: MouseEvent) => {
-      context.emit('click-text', evt);
+    const handleRightClick = () => {
+      emitEvent('right-click');
     };
 
     return {
       name,
-      nTitleContent,
-      handleBack,
-      handleMore,
-      clickText,
+      titleContent,
+      leftContent,
+      rightContent,
+      navStyle,
+      homeContent,
+      handleLeftClick,
+      handleRightClick,
     };
   },
 });
diff --git a/src/navbar/props.ts b/src/navbar/props.ts
new file mode 100644
index 00000000..346c2845
--- /dev/null
+++ b/src/navbar/props.ts
@@ -0,0 +1,56 @@
+/* eslint-disable */
+
+/**
+ * 该文件为脚本自动生成文件，请勿随意修改。如需修改请联系 PMC
+ * */
+
+import { TdNavbarProps } from './type';
+import { PropType } from 'vue';
+
+export default {
+  /** 是否添加动画效果 */
+  animation: {
+    type: Boolean,
+    default: true,
+  },
+  /** 背景 */
+  background: {
+    type: String,
+    default: '',
+  },
+  /** 是否固定在顶部 */
+  fixed: {
+    type: Boolean,
+    default: true,
+  },
+  /** 首页图标。值为 true 表示显示默认返回图标，值为 false 表示不显示首页图标，值为其他表示自定义图标 */
+  homeIcon: {
+    type: [Boolean, Function] as PropType<TdNavbarProps['homeIcon']>,
+  },
+  /** 左侧图标。值为 true 表示显示默认返回图标，值为 false 表示不显示左侧图标，值为其他表示自定义图标 */
+  leftIcon: {
+    type: [Boolean, Function] as PropType<TdNavbarProps['leftIcon']>,
+    default: false,
+  },
+  /** 右侧图标，可自定义 */
+  rightIcon: {
+    type: Function as PropType<TdNavbarProps['rightIcon']>,
+  },
+  /** 页面标题 */
+  title: {
+    type: [String, Function] as PropType<TdNavbarProps['title']>,
+  },
+  /** 标题文字最大长度，超出的范围使用 `...` 表示 */
+  titleMaxLength: {
+    type: Number,
+  },
+  /** 是否显示 */
+  visible: {
+    type: Boolean,
+    default: true,
+  },
+  /** 点击左侧按钮时触发 */
+  onLeftClick: Function as PropType<TdNavbarProps['onLeftClick']>,
+  /** 点击右侧图标时触发 */
+  onRightClick: Function as PropType<TdNavbarProps['onRightClick']>,
+};
diff --git a/src/navbar/type.ts b/src/navbar/type.ts
new file mode 100644
index 00000000..7a3fcb9a
--- /dev/null
+++ b/src/navbar/type.ts
@@ -0,0 +1,61 @@
+/* eslint-disable */
+
+/**
+ * 该文件为脚本自动生成文件，请勿随意修改。如需修改请联系 PMC
+ * */
+
+import { TNode } from '../common';
+
+export interface TdNavbarProps {
+  /**
+   * 是否添加动画效果
+   * @default true
+   */
+  animation?: boolean;
+  /**
+   * 背景
+   * @default ''
+   */
+  background?: string;
+  /**
+   * 是否固定在顶部
+   * @default true
+   */
+  fixed?: boolean;
+  /**
+   * 首页图标。值为 true 表示显示默认返回图标，值为 false 表示不显示首页图标，值为其他表示自定义图标
+   */
+  homeIcon?: boolean | TNode;
+  /**
+   * 左侧图标。值为 true 表示显示默认返回图标，值为 false 表示不显示左侧图标，值为其他表示自定义图标
+   * @default false
+   */
+  leftIcon?: boolean | TNode;
+  /**
+   * 右侧图标，可自定义
+   */
+  rightIcon?: TNode;
+  /**
+   * 页面标题
+   */
+  title?: string | TNode;
+  /**
+   * 标题文字最大长度，超出的范围使用 `...` 表示
+   */
+  titleMaxLength?: number;
+  /**
+   * 是否显示
+   * @default true
+   */
+  visible?: boolean;
+  /**
+   * 点击左侧按钮时触发
+   */
+  onLeftClick?: (trigger: NavBarTrigger) => void;
+  /**
+   * 点击右侧图标时触发
+   */
+  onRightClick?: () => void;
+}
+
+export type NavBarTrigger = 'home-icon' | 'left-icon';
diff --git a/src/slider/demos/base.vue b/src/slider/demos/base.vue
index aa14586e..f3ae9617 100644
--- a/src/slider/demos/base.vue
+++ b/src/slider/demos/base.vue
@@ -1,12 +1,11 @@
 <template>
-  <t-slider v-model="value" :label="label" :on-change="onChange" />
+  <t-slider v-model="value" :label="false" :on-change="onChange" />
 </template>
 
 <script lang="ts" setup>
 import { ref } from 'vue';
 
-const value = ref(60);
-const label = ref(false);
+const value = ref(0);
 const onChange = ($event: number | number[]) => {
   console.log(`change to ${$event}`);
 };
diff --git a/src/slider/demos/disable.vue b/src/slider/demos/disable.vue
index 29c442ea..f3a2fb2a 100644
--- a/src/slider/demos/disable.vue
+++ b/src/slider/demos/disable.vue
@@ -1,34 +1,3 @@
 <template>
-  <div class="section">
-    <t-slider :default-value="60" disabled />
-  </div>
-  <div class="section">
-    <t-slider :default-value="30" :min="30" disabled />
-  </div>
-  <div class="section">
-    <t-slider :default-value="50" :label="label" :marks="marks" disabled />
-  </div>
-  <div class="section">
-    <t-slider :default-value="[30, 70]" range disabled />
-  </div>
+  <t-slider :default-value="30" :min="30" disabled :label="false" />
 </template>
-
-<script lang="ts" setup>
-import { ref } from 'vue';
-
-const marks = ref({ 0: '小', 50: '中', 100: '大' });
-const label = ref(false);
-</script>
-
-<style lang="less" scoped>
-.section {
-  // display: flex;
-  align-items: center;
-  padding-top: 16px;
-  padding-bottom: 16px;
-
-  & + .section {
-    margin-top: 16px;
-  }
-}
-</style>
diff --git a/src/slider/demos/mark.vue b/src/slider/demos/mark.vue
index 04471ed0..01c3c53b 100644
--- a/src/slider/demos/mark.vue
+++ b/src/slider/demos/mark.vue
@@ -1,5 +1,5 @@
 <template>
-  <t-slider v-model="value" :label="label" :marks="marks" />
+  <t-slider v-model="value" :label="label" :marks="marks" :step="50" />
 </template>
 
 <script lang="ts" setup>
@@ -8,10 +8,4 @@ import { ref } from 'vue';
 const value = ref(50);
 const label = ref(false);
 const marks = ref({ 0: '小', 50: '中', 100: '大' });
-// const marks = ref([0, 50, 100]);
-// const marks = ref({
-//   0: (val: number) => `${val}%`,
-//   50: (val: number) => `${val}%`,
-//   100: (val: number) => `${val}%`,
-// });
 </script>
diff --git a/src/slider/demos/mobile.vue b/src/slider/demos/mobile.vue
index 2446a359..7a5c2d1a 100644
--- a/src/slider/demos/mobile.vue
+++ b/src/slider/demos/mobile.vue
@@ -1,7 +1,7 @@
 <template>
   <div class="tdesign-mobile-demo">
     <h1 class="title">Slider 滑动选择器</h1>
-    <p class="summary">滑动滑块来选择一个数值，在具体场景中也可以增加来刻度和展示数值来方便用户使用</p>
+    <p class="summary">用于选择横轴上的数值、区间、档位</p>
     <tdesign-demo-block title="01 类型" summary="基础滑动选择器">
       <div class="slider-demo">
         <BaseDemo />
@@ -14,7 +14,7 @@
     </tdesign-demo-block>
     <tdesign-demo-block summary="起始非零滑动选择器">
       <div class="slider-demo">
-        <t-slider :default-value="30" :min="30"> </t-slider>
+        <UnZeroDemo />
       </div>
     </tdesign-demo-block>
     <tdesign-demo-block summary="带刻度滑动选择器">
@@ -32,6 +32,16 @@
         <DisableDemo />
       </div>
     </tdesign-demo-block>
+    <tdesign-demo-block title="03 规格" summary="无标题滑动选择器">
+      <div class="slider-demo">
+        <BaseDemo />
+      </div>
+    </tdesign-demo-block>
+    <tdesign-demo-block summary="有标题滑动选择器">
+      <div class="slider-demo">
+        <TitleDemo />
+      </div>
+    </tdesign-demo-block>
   </div>
 </template>
 
@@ -41,6 +51,8 @@ import MarkDemo from './mark.vue';
 import ValueDemo from './value.vue';
 import RangeDemo from './range.vue';
 import DisableDemo from './disable.vue';
+import UnZeroDemo from './unZero.vue';
+import TitleDemo from './title.vue';
 </script>
 
 <style scoped>
diff --git a/src/slider/demos/title.vue b/src/slider/demos/title.vue
new file mode 100644
index 00000000..2b88f959
--- /dev/null
+++ b/src/slider/demos/title.vue
@@ -0,0 +1,18 @@
+<template>
+  <div class="flex">
+    <span :style="{ width: '120px', 'margin-right': '10px' }"> 选择器标题 </span>
+    <t-slider v-model="value" :label="false" />
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref } from 'vue';
+
+const value = ref(0);
+</script>
+<style>
+.flex {
+  display: flex;
+  align-items: center;
+}
+</style>
diff --git a/src/slider/demos/unZero.vue b/src/slider/demos/unZero.vue
new file mode 100644
index 00000000..a6c8b4db
--- /dev/null
+++ b/src/slider/demos/unZero.vue
@@ -0,0 +1,3 @@
+<template>
+  <t-slider :default-value="30" :min="30" :max="200" :label="false"> </t-slider>
+</template>
diff --git a/src/slider/demos/value.vue b/src/slider/demos/value.vue
index e6ac6488..13caa023 100644
--- a/src/slider/demos/value.vue
+++ b/src/slider/demos/value.vue
@@ -5,5 +5,5 @@
 <script lang="ts" setup>
 import { ref } from 'vue';
 
-const value = ref(60);
+const value = ref(50);
 </script>


Test patch:
diff --git a/src/navbar/__test__/__snapshots__/demo.test.jsx.snap b/src/navbar/__test__/__snapshots__/demo.test.jsx.snap
index 4d247958..8a8c7fe1 100644
--- a/src/navbar/__test__/__snapshots__/demo.test.jsx.snap
+++ b/src/navbar/__test__/__snapshots__/demo.test.jsx.snap
@@ -1,12 +1,132 @@
 // Vitest Snapshot v1
 
 exports[`Navbar > Navbar baseVue demo works fine 1`] = `
-<div>
+<div
+  class="t-navbar"
+>
+  <div
+    class="t-navbar__back"
+  >
+    <span
+      class="t-navbar__back--arrow"
+    >
+      <svg
+        class="t-icon t-icon-chevron-left"
+        fill="none"
+        height="1em"
+        viewBox="0 0 16 16"
+        width="1em"
+      >
+        <path
+          d="M9.54 3.54l.92.92L6.92 8l3.54 3.54-.92.92L5.08 8l4.46-4.46z"
+          fill="currentColor"
+          fill-opacity="0.9"
+        />
+      </svg>
+    </span>
+    <!--v-if-->
+    <!---->
+    <!---->
+  </div>
+  <div
+    class="t-navbar__text"
+  >
+    标题
+  </div>
+  <div
+    class="t-navbar__right"
+  >
+    <!---->
+  </div>
+</div>
+`;
+
+exports[`Navbar > Navbar leftIconVue demo works fine 1`] = `
+<div
+  class="t-navbar"
+>
+  <div
+    class="t-navbar__back"
+  >
+    <!--v-if-->
+    <!--v-if-->
+    <!---->
+    
+    <svg
+      class="t-icon t-icon-chevron-left btn-left"
+      style="font-size: 24px;"
+    >
+      <use
+        href="#t-icon-chevron-left"
+      />
+    </svg>
+    <svg
+      class="t-icon t-icon-close"
+      style="font-size: 24px;"
+    >
+      <use
+        href="#t-icon-close"
+      />
+    </svg>
+    
+  </div>
+  <div
+    class="t-navbar__text"
+  >
+    标题
+  </div>
+  <div
+    class="t-navbar__right"
+  >
+    
+    <svg
+      class="t-icon t-icon-ellipsis"
+      style="font-size: 24px;"
+    >
+      <use
+        href="#t-icon-ellipsis"
+      />
+    </svg>
+    
+  </div>
+</div>
+`;
+
+exports[`Navbar > Navbar mobileVue demo works fine 1`] = `
+<div
+  class="tdesign-mobile-demo"
+  data-v-16defdf7=""
+>
+  <h1
+    class="title"
+    data-v-16defdf7=""
+  >
+    NavBar 导航栏
+  </h1>
+  <p
+    class="summary"
+    data-v-16defdf7=""
+  >
+    用于不同页面之间切换或者跳转，位于内容区的上方，系统状态栏的下方。
+  </p>
   <div
-    class="tdesign-demo-block"
+    class="tdesign-mobile-demo-block"
+    data-v-16defdf7=""
   >
+    <h2
+      class="tdesign-mobile-demo-block__title"
+    >
+      01 类型
+    </h2>
+    <p
+      class="tdesign-mobile-demo-block__summary"
+    >
+      基础导航栏
+    </p>
+    
     <div
       class="t-navbar"
+      data-v-16defdf7=""
     >
       <div
         class="t-navbar__back"
@@ -28,126 +148,99 @@ exports[`Navbar > Navbar baseVue demo works fine 1`] = `
             />
           </svg>
         </span>
-        
-        
+        <!--v-if-->
+        <!---->
+        <!---->
       </div>
       <div
         class="t-navbar__text"
       >
-        
-         界面标题 
-        
+        标题
       </div>
       <div
         class="t-navbar__right"
       >
-        
-        
-        <i
-          class="t-navbar__right--more"
-        >
-          <svg
-            class="icon"
-            height="24"
-            p-id="2091"
-            t="1614321969302"
-            version="1.1"
-            viewBox="0 0 1024 1024"
-            width="24"
-            xmlns="http://www.w3.org/2000/svg"
-          >
-            <path
-              d="M512 449.749333a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m-318.805333-1.109333a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m638.677333 0a64 64 0 1 1 0 128 64 64 0 0 1 0-128z"
-              fill="#444444"
-              p-id="2092"
-            />
-          </svg>
-        </i>
+        <!---->
       </div>
     </div>
+    
   </div>
-</div>
-`;
-
-exports[`Navbar > Navbar eventVue demo works fine 1`] = `
-<div>
   <div
-    class="tdesign-demo-block"
+    class="tdesign-mobile-demo-block"
+    data-v-16defdf7=""
   >
+    <!--v-if-->
+    <p
+      class="tdesign-mobile-demo-block__summary"
+    >
+      左侧双操作导航栏
+    </p>
+    
     <div
       class="t-navbar"
+      data-v-16defdf7=""
     >
       <div
         class="t-navbar__back"
       >
-        <span
-          class="t-navbar__back--arrow"
-        >
-          <svg
-            class="t-icon t-icon-chevron-left"
-            fill="none"
-            height="1em"
-            viewBox="0 0 16 16"
-            width="1em"
-          >
-            <path
-              d="M9.54 3.54l.92.92L6.92 8l3.54 3.54-.92.92L5.08 8l4.46-4.46z"
-              fill="currentColor"
-              fill-opacity="0.9"
-            />
-          </svg>
-        </span>
+        <!--v-if-->
+        <!--v-if-->
+        <!---->
         
-        <t-icon
-          name="close"
-        />
+        <svg
+          class="t-icon t-icon-chevron-left btn-left"
+          style="font-size: 24px;"
+        >
+          <use
+            href="#t-icon-chevron-left"
+          />
+        </svg>
+        <svg
+          class="t-icon t-icon-close"
+          style="font-size: 24px;"
+        >
+          <use
+            href="#t-icon-close"
+          />
+        </svg>
         
       </div>
       <div
         class="t-navbar__text"
       >
-        
-         界面标题 
-        
+        标题
       </div>
       <div
         class="t-navbar__right"
       >
         
-        
-        <i
-          class="t-navbar__right--more"
+        <svg
+          class="t-icon t-icon-ellipsis"
+          style="font-size: 24px;"
         >
-          <svg
-            class="icon"
-            height="24"
-            p-id="2091"
-            t="1614321969302"
-            version="1.1"
-            viewBox="0 0 1024 1024"
-            width="24"
-            xmlns="http://www.w3.org/2000/svg"
-          >
-            <path
-              d="M512 449.749333a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m-318.805333-1.109333a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m638.677333 0a64 64 0 1 1 0 128 64 64 0 0 1 0-128z"
-              fill="#444444"
-              p-id="2092"
-            />
-          </svg>
-        </i>
+          <use
+            href="#t-icon-ellipsis"
+          />
+        </svg>
+        
       </div>
     </div>
+    
   </div>
-</div>
-`;
-
-exports[`Navbar > Navbar iconVue demo works fine 1`] = `
-<div>
   <div
-    class="tdesign-demo-block"
+    class="tdesign-mobile-demo-block"
+    data-v-16defdf7=""
   >
+    <!--v-if-->
+    <p
+      class="tdesign-mobile-demo-block__summary"
+    >
+      右侧双操作导航栏
+    </p>
+    
     <div
       class="t-navbar"
+      data-v-16defdf7=""
     >
       <div
         class="t-navbar__back"
@@ -169,253 +262,97 @@ exports[`Navbar > Navbar iconVue demo works fine 1`] = `
             />
           </svg>
         </span>
-        
-        
+        <!--v-if-->
+        <!---->
+        <!---->
       </div>
       <div
         class="t-navbar__text"
       >
-        
-         导航栏 - 带icon 
-        
+        标题
       </div>
       <div
         class="t-navbar__right"
       >
         
         <svg
-          class="t-icon t-icon-sound"
-          fill="none"
-          height="1em"
-          viewBox="0 0 16 16"
-          width="1em"
+          class="t-icon t-icon-notification btn-left"
+          style="font-size: 24px;"
         >
-          <path
-            d="M4 11l4.24 2.55a.5.5 0 00.76-.43V2.88a.5.5 0 00-.76-.43L4 5H2.1a.6.6 0 00-.6.6v4.8c0 .33.27.6.6.6H4zm1-5.43l3-1.8v8.46l-3-1.8V5.57zM4 10H2.5V6H4v4zM13.52 5.73a6 6 0 00-1.4-1.95l.68-.73c.7.65 1.25 1.42 1.63 2.27a6.6 6.6 0 01-1.63 7.63l-.68-.73a6 6 0 001.4-1.95 5.6 5.6 0 000-4.54z"
-            fill="currentColor"
-            fill-opacity="0.9"
+          <use
+            href="#t-icon-notification"
           />
-          <path
-            d="M11.5 8c0-.87-.36-1.75-1.07-2.45l.7-.72c.9.88 1.37 2.02 1.37 3.17 0 1.16-.48 2.29-1.38 3.17l-.7-.72A3.44 3.44 0 0011.5 8z"
-            fill="currentColor"
-            fill-opacity="0.9"
+        </svg>
+        <svg
+          class="t-icon t-icon-ellipsis"
+          style="font-size: 24px;"
+        >
+          <use
+            href="#t-icon-ellipsis"
           />
         </svg>
         
-        <i
-          class="t-navbar__right--more"
-        >
-          <svg
-            class="icon"
-            height="24"
-            p-id="2091"
-            t="1614321969302"
-            version="1.1"
-            viewBox="0 0 1024 1024"
-            width="24"
-            xmlns="http://www.w3.org/2000/svg"
-          >
-            <path
-              d="M512 449.749333a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m-318.805333-1.109333a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m638.677333 0a64 64 0 1 1 0 128 64 64 0 0 1 0-128z"
-              fill="#444444"
-              p-id="2092"
-            />
-          </svg>
-        </i>
       </div>
     </div>
+    
   </div>
 </div>
 `;
 
-exports[`Navbar > Navbar mobileVue demo works fine 1`] = `
+exports[`Navbar > Navbar rightIconVue demo works fine 1`] = `
 <div
-  class="t-navbar-base-demo"
-  data-v-16defdf7=""
+  class="t-navbar"
 >
-  <p
-    class="divide-line"
-    data-v-16defdf7=""
-  />
   <div
-    class="t-navbar"
-    data-v-16defdf7=""
+    class="t-navbar__back"
   >
-    <div
-      class="t-navbar__back"
-    >
-      <span
-        class="t-navbar__back--arrow"
-      >
-        <svg
-          class="t-icon t-icon-chevron-left"
-          fill="none"
-          height="1em"
-          viewBox="0 0 16 16"
-          width="1em"
-        >
-          <path
-            d="M9.54 3.54l.92.92L6.92 8l3.54 3.54-.92.92L5.08 8l4.46-4.46z"
-            fill="currentColor"
-            fill-opacity="0.9"
-          />
-        </svg>
-      </span>
-      
-      
-    </div>
-    <div
-      class="t-navbar__text"
-    >
-      
-      界面标题
-      
-    </div>
-    <div
-      class="t-navbar__right"
+    <span
+      class="t-navbar__back--arrow"
     >
-      
-      
-      <!--v-if-->
-    </div>
-  </div>
-  <p
-    class="divide-line"
-    data-v-16defdf7=""
-  />
-  <div
-    class="t-navbar"
-    data-v-16defdf7=""
-  >
-    <div
-      class="t-navbar__back"
-    >
-      <span
-        class="t-navbar__back--arrow"
-      >
-        <svg
-          class="t-icon t-icon-chevron-left"
-          fill="none"
-          height="1em"
-          viewBox="0 0 16 16"
-          width="1em"
-        >
-          <path
-            d="M9.54 3.54l.92.92L6.92 8l3.54 3.54-.92.92L5.08 8l4.46-4.46z"
-            fill="currentColor"
-            fill-opacity="0.9"
-          />
-        </svg>
-      </span>
-      
-      <svg
-        class="t-icon t-icon-close"
-        data-v-16defdf7=""
-        style="font-size: 24px;"
-      >
-        <use
-          href="#t-icon-close"
-        />
-      </svg>
-      
-    </div>
-    <div
-      class="t-navbar__text"
-    >
-      
-       界面标题 
-      
-    </div>
-    <div
-      class="t-navbar__right"
-    >
-      
       <svg
-        class="t-icon t-icon-app"
-        data-v-16defdf7=""
-        style="font-size: 24px;"
+        class="t-icon t-icon-chevron-left"
+        fill="none"
+        height="1em"
+        viewBox="0 0 16 16"
+        width="1em"
       >
-        <use
-          href="#t-icon-app"
+        <path
+          d="M9.54 3.54l.92.92L6.92 8l3.54 3.54-.92.92L5.08 8l4.46-4.46z"
+          fill="currentColor"
+          fill-opacity="0.9"
         />
       </svg>
-      
-      <!--v-if-->
-    </div>
+    </span>
+    <!--v-if-->
+    <!---->
+    <!---->
   </div>
-  <p
-    class="divide-line"
-    data-v-16defdf7=""
-  />
   <div
-    class="t-navbar"
-    data-v-16defdf7=""
+    class="t-navbar__text"
   >
-    <div
-      class="t-navbar__back"
+    标题
+  </div>
+  <div
+    class="t-navbar__right"
+  >
+    
+    <svg
+      class="t-icon t-icon-notification btn-left"
+      style="font-size: 24px;"
     >
-      <span
-        class="t-navbar__back--arrow"
-      >
-        <svg
-          class="t-icon t-icon-chevron-left"
-          fill="none"
-          height="1em"
-          viewBox="0 0 16 16"
-          width="1em"
-        >
-          <path
-            d="M9.54 3.54l.92.92L6.92 8l3.54 3.54-.92.92L5.08 8l4.46-4.46z"
-            fill="currentColor"
-            fill-opacity="0.9"
-          />
-        </svg>
-      </span>
-      
-      
-    </div>
-    <div
-      class="t-navbar__text"
+      <use
+        href="#t-icon-notification"
+      />
+    </svg>
+    <svg
+      class="t-icon t-icon-ellipsis"
+      style="font-size: 24px;"
     >
-      
-       界面标题 
-      
-    </div>
-    <div
-      class="t-navbar__right"
-    >
-      
-      <svg
-        class="t-icon t-icon-app"
-        data-v-16defdf7=""
-        style="font-size: 24px;"
-      >
-        <use
-          href="#t-icon-app"
-        />
-      </svg>
-      
-      <i
-        class="t-navbar__right--more"
-      >
-        <svg
-          class="icon"
-          height="24"
-          p-id="2091"
-          t="1614321969302"
-          version="1.1"
-          viewBox="0 0 1024 1024"
-          width="24"
-          xmlns="http://www.w3.org/2000/svg"
-        >
-          <path
-            d="M512 449.749333a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m-318.805333-1.109333a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m638.677333 0a64 64 0 1 1 0 128 64 64 0 0 1 0-128z"
-            fill="#444444"
-            p-id="2092"
-          />
-        </svg>
-      </i>
-    </div>
+      <use
+        href="#t-icon-ellipsis"
+      />
+    </svg>
+    
   </div>
 </div>
 `;
diff --git a/src/navbar/__test__/demo.test.jsx b/src/navbar/__test__/demo.test.jsx
index e739e0f6..4ef34268 100644
--- a/src/navbar/__test__/demo.test.jsx
+++ b/src/navbar/__test__/demo.test.jsx
@@ -4,15 +4,15 @@
 
 import { mount } from '@vue/test-utils';
 import baseVue from '@/navbar/demos/base.vue';
-import eventVue from '@/navbar/demos/event.vue';
-import iconVue from '@/navbar/demos/icon.vue';
+import leftIconVue from '@/navbar/demos/left-icon.vue';
 import mobileVue from '@/navbar/demos/mobile.vue';
+import rightIconVue from '@/navbar/demos/right-icon.vue';
 
 const mapper = {
   baseVue,
-  eventVue,
-  iconVue,
+  leftIconVue,
   mobileVue,
+  rightIconVue,
 };
 
 describe('Navbar', () => {
diff --git a/src/navbar/__test__/index.test.jsx b/src/navbar/__test__/index.test.jsx
new file mode 100644
index 00000000..9f351adf
--- /dev/null
+++ b/src/navbar/__test__/index.test.jsx
@@ -0,0 +1,129 @@
+import { mount } from '@vue/test-utils';
+import { describe, it, expect } from 'vitest';
+import NavBar from '../navbar.vue';
+
+describe('navbar', () => {
+  describe('props', () => {
+    it('fixed', async () => {
+      const navbar = mount(<NavBar title="标题" />);
+      expect(navbar.vm.navStyle).toContain('position: fixed');
+
+      await navbar.setProps({ fixed: false });
+      expect(navbar.vm.navStyle).toContain('position: relative');
+    });
+
+    it('background', () => {
+      const navbar = mount(<NavBar background="red" />);
+      expect(navbar.vm.navStyle).toContain('background: red');
+    });
+
+    it('homeIcon', () => {
+      const navbar = mount(<NavBar title="标题" homeIcon />);
+      expect(navbar.find('.t-icon-home').exists()).toBeTruthy();
+    });
+
+    it('leftIcon', () => {
+      const navbar = mount(<NavBar title="标题" leftIcon />);
+      expect(navbar.find('.t-icon-chevron-left').exists()).toBeTruthy();
+    });
+
+    it('title', () => {
+      const navbar = mount(<NavBar title="标题" />);
+      expect(navbar.text()).toContain('标题');
+    });
+
+    it('titleMaxLength', async () => {
+      const navbar = mount(<NavBar title="标题超过了六个字符" titleMaxLength={6} />);
+      expect(navbar.text()).toContain('标题超过了六...');
+
+      await navbar.setProps({ titleMaxLength: -1 });
+      expect(navbar.text()).toContain('标题超过了六个字符');
+      await navbar.setProps({ titleMaxLength: 10, title: '测试标题' });
+      expect(navbar.text()).toContain('测试标题');
+    });
+
+    it('visible', () => {
+      const navbar = mount(<NavBar title="标题" visible={false} />);
+      expect(navbar.isVisible()).toBe(false);
+    });
+  });
+
+  describe('events', () => {
+    it('left-click', async () => {
+      const fn = vi.fn();
+      const navbar = mount(<NavBar title="标题" leftIcon onLeftClick={fn} />);
+      await navbar.find('.t-icon-chevron-left').trigger('click');
+      expect(fn).toHaveBeenCalled();
+    });
+  });
+
+  describe('functions', () => {
+    it('homeIcon', () => {
+      const test = () => '测试';
+      const navbar = mount(<NavBar title="标题" homeIcon={test} />);
+      expect(navbar.text()).toContain('测试');
+      expect(navbar.find('.t-icon-home').exists()).toBeFalsy();
+    });
+
+    it('leftIcon', () => {
+      const test = () => '测试';
+      const navbar = mount(<NavBar title="标题" leftIcon={test} />);
+      expect(navbar.text()).toContain('测试');
+      expect(navbar.find('.t-icon-chevron-left').exists()).toBeFalsy();
+    });
+
+    it('rightIcon', () => {
+      const test = () => '测试';
+      const navbar = mount(<NavBar title="标题" rightIcon={test} />);
+      expect(navbar.text()).toContain('测试');
+    });
+
+    it('title', () => {
+      const test = () => '测试';
+      const navbar = mount(<NavBar title={test} />);
+      expect(navbar.text()).toContain('测试');
+    });
+  });
+
+  describe('slots', () => {
+    it('homeIcon', () => {
+      const slot = <div>测试</div>;
+      const navbar = mount(<NavBar title="标题" />, {
+        slots: {
+          'home-icon': slot,
+        },
+      });
+      expect(navbar.text()).toContain('测试');
+    });
+
+    it('leftIcon', () => {
+      const slot = <div>测试</div>;
+      const navbar = mount(<NavBar title="标题" />, {
+        slots: {
+          'left-icon': slot,
+        },
+      });
+      expect(navbar.text()).toContain('测试');
+    });
+
+    it('rightIcon', () => {
+      const slot = <div>测试</div>;
+      const navbar = mount(<NavBar title="标题" />, {
+        slots: {
+          'right-icon': slot,
+        },
+      });
+      expect(navbar.text()).toContain('测试');
+    });
+
+    it('title', () => {
+      const slot = <div>测试</div>;
+      const navbar = mount(<NavBar />, {
+        slots: {
+          title: slot,
+        },
+      });
+      expect(navbar.text()).toContain('测试');
+    });
+  });
+});
diff --git a/src/slider/__test__/__snapshots__/demo.test.jsx.snap b/src/slider/__test__/__snapshots__/demo.test.jsx.snap
index 8af47150..77599182 100644
--- a/src/slider/__test__/__snapshots__/demo.test.jsx.snap
+++ b/src/slider/__test__/__snapshots__/demo.test.jsx.snap
@@ -15,13 +15,13 @@ exports[`Slider > Slider baseVue demo works fine 1`] = `
     <!-- 滑块长度 -->
     <div
       class="t-slider__track"
-      style="width: 60%;"
+      style="width: 0%;"
     />
     <!-- 滑块操作 -->
     
     <div
       class="t-slider__handle"
-      style="left: 60%;"
+      style="left: 0%;"
     />
     
     <!-- 刻度内容 -->
@@ -39,200 +39,38 @@ exports[`Slider > Slider baseVue demo works fine 1`] = `
 
 exports[`Slider > Slider disableVue demo works fine 1`] = `
 <div
-  data-v-app=""
+  class="t-slider-wrap t-is-disabled"
 >
-  
+  <!--v-if-->
   <div
-    class="section"
-    data-v-65b1e7f4=""
+    class="t-slider"
   >
+    <!-- 总长度 -->
     <div
-      class="t-slider-wrap t-is-disabled"
-      data-v-65b1e7f4=""
-    >
-      <!--v-if-->
-      <div
-        class="t-slider"
-      >
-        <!-- 总长度 -->
-        <div
-          class="t-slider__bar"
-        />
-        <!-- 滑块长度 -->
-        <div
-          class="t-slider__track"
-          style="width: 60%;"
-        />
-        <!-- 滑块操作 -->
-        
-        <div
-          class="t-slider__handle"
-          style="left: 60%;"
-        />
-        
-        <!-- 刻度内容 -->
-        <div
-          class="t-slider__mark"
-        >
-          
-          
-        </div>
-      </div>
-      <div
-        class="t-slider-wrap__value"
-      >
-        60
-      </div>
-      <!--v-if-->
-    </div>
-  </div>
-  <div
-    class="section"
-    data-v-65b1e7f4=""
-  >
+      class="t-slider__bar"
+    />
+    <!-- 滑块长度 -->
     <div
-      class="t-slider-wrap t-is-disabled"
-      data-v-65b1e7f4=""
-    >
-      <!--v-if-->
-      <div
-        class="t-slider"
-      >
-        <!-- 总长度 -->
-        <div
-          class="t-slider__bar"
-        />
-        <!-- 滑块长度 -->
-        <div
-          class="t-slider__track"
-          style="width: 0%;"
-        />
-        <!-- 滑块操作 -->
-        
-        <div
-          class="t-slider__handle"
-          style="left: 0%;"
-        />
-        
-        <!-- 刻度内容 -->
-        <div
-          class="t-slider__mark"
-        >
-          
-          
-        </div>
-      </div>
-      <div
-        class="t-slider-wrap__value"
-      >
-        30
-      </div>
-      <!--v-if-->
-    </div>
-  </div>
-  <div
-    class="section"
-    data-v-65b1e7f4=""
-  >
+      class="t-slider__track"
+      style="width: 0%;"
+    />
+    <!-- 滑块操作 -->
+    
     <div
-      class="t-slider-wrap t-is-disabled t-is-mark"
-      data-v-65b1e7f4=""
-    >
-      <!--v-if-->
-      <div
-        class="t-slider"
-      >
-        <!-- 总长度 -->
-        <div
-          class="t-slider__bar"
-        />
-        <!-- 滑块长度 -->
-        <div
-          class="t-slider__track"
-          style="width: 50%;"
-        />
-        <!-- 滑块操作 -->
-        
-        <div
-          class="t-slider__handle"
-          style="left: 50%;"
-        />
-        
-        <!-- 刻度内容 -->
-        <div
-          class="t-slider__mark"
-        >
-          
-          <div
-            class="t-slider__mark-text t-is-active"
-            style="left: 0%;"
-          >
-            小
-          </div>
-          <div
-            class="t-slider__mark-text t-is-"
-            style="left: 50%;"
-          >
-            中
-          </div>
-          <div
-            class="t-slider__mark-text t-is-"
-            style="left: 100%;"
-          >
-            大
-          </div>
-          
-        </div>
-      </div>
-      <!--v-if-->
-      <!--v-if-->
-    </div>
-  </div>
-  <div
-    class="section"
-    data-v-65b1e7f4=""
-  >
+      class="t-slider__handle"
+      style="left: 0%;"
+    />
+    
+    <!-- 刻度内容 -->
     <div
-      class="t-slider-wrap t-is-disabled"
-      data-v-65b1e7f4=""
+      class="t-slider__mark"
     >
-      <!--v-if-->
-      <div
-        class="t-slider"
-      >
-        <!-- 总长度 -->
-        <div
-          class="t-slider__bar"
-        />
-        <!-- 滑块长度 -->
-        <div
-          class="t-slider__track"
-          style="left: 30%; width: 40%;"
-        />
-        <!-- 滑块操作 -->
-        
-        <div
-          class="t-slider__handle"
-          style="left: 30%;"
-        />
-        <div
-          class="t-slider__handle"
-          style="left: 70%;"
-        />
-        
-        <!-- 刻度内容 -->
-        <div
-          class="t-slider__mark"
-        >
-          
-          
-        </div>
-      </div>
-      <!--v-if-->
-      <!--v-if-->
+      
+      
     </div>
   </div>
-  
+  <!--v-if-->
+  <!--v-if-->
 </div>
 `;
 
@@ -306,7 +144,7 @@ exports[`Slider > Slider mobileVue demo works fine 1`] = `
     class="summary"
     data-v-98828574=""
   >
-    滑动滑块来选择一个数值，在具体场景中也可以增加来刻度和展示数值来方便用户使用
+    用于选择横轴上的数值、区间、档位
   </p>
   <div
     class="tdesign-mobile-demo-block"
@@ -342,13 +180,13 @@ exports[`Slider > Slider mobileVue demo works fine 1`] = `
           <!-- 滑块长度 -->
           <div
             class="t-slider__track"
-            style="width: 60%;"
+            style="width: 0%;"
           />
           <!-- 滑块操作 -->
           
           <div
             class="t-slider__handle"
-            style="left: 60%;"
+            style="left: 0%;"
           />
           
           <!-- 刻度内容 -->
@@ -395,13 +233,13 @@ exports[`Slider > Slider mobileVue demo works fine 1`] = `
           <!-- 滑块长度 -->
           <div
             class="t-slider__track"
-            style="width: 60%;"
+            style="width: 50%;"
           />
           <!-- 滑块操作 -->
           
           <div
             class="t-slider__handle"
-            style="left: 60%;"
+            style="left: 50%;"
           />
           
           <!-- 刻度内容 -->
@@ -415,7 +253,7 @@ exports[`Slider > Slider mobileVue demo works fine 1`] = `
         <div
           class="t-slider-wrap__value"
         >
-          60
+          50
         </div>
         <!--v-if-->
       </div>
@@ -469,11 +307,7 @@ exports[`Slider > Slider mobileVue demo works fine 1`] = `
             
           </div>
         </div>
-        <div
-          class="t-slider-wrap__value"
-        >
-          30
-        </div>
+        <!--v-if-->
         <!--v-if-->
       </div>
     </div>
@@ -634,160 +468,127 @@ exports[`Slider > Slider mobileVue demo works fine 1`] = `
       class="slider-demo"
       data-v-98828574=""
     >
-      
       <div
-        class="section"
-        data-v-65b1e7f4=""
+        class="t-slider-wrap t-is-disabled"
+        data-v-98828574=""
       >
+        <!--v-if-->
         <div
-          class="t-slider-wrap t-is-disabled"
-          data-v-65b1e7f4=""
+          class="t-slider"
         >
-          <!--v-if-->
+          <!-- 总长度 -->
           <div
-            class="t-slider"
-          >
-            <!-- 总长度 -->
-            <div
-              class="t-slider__bar"
-            />
-            <!-- 滑块长度 -->
-            <div
-              class="t-slider__track"
-              style="width: 60%;"
-            />
-            <!-- 滑块操作 -->
-            
-            <div
-              class="t-slider__handle"
-              style="left: 60%;"
-            />
-            
-            <!-- 刻度内容 -->
-            <div
-              class="t-slider__mark"
-            >
-              
-              
-            </div>
-          </div>
+            class="t-slider__bar"
+          />
+          <!-- 滑块长度 -->
           <div
-            class="t-slider-wrap__value"
-          >
-            60
-          </div>
-          <!--v-if-->
-        </div>
-      </div>
-      <div
-        class="section"
-        data-v-65b1e7f4=""
-      >
-        <div
-          class="t-slider-wrap t-is-disabled"
-          data-v-65b1e7f4=""
-        >
-          <!--v-if-->
+            class="t-slider__track"
+            style="width: 0%;"
+          />
+          <!-- 滑块操作 -->
+          
           <div
-            class="t-slider"
+            class="t-slider__handle"
+            style="left: 0%;"
+          />
+          
+          <!-- 刻度内容 -->
+          <div
+            class="t-slider__mark"
           >
-            <!-- 总长度 -->
-            <div
-              class="t-slider__bar"
-            />
-            <!-- 滑块长度 -->
-            <div
-              class="t-slider__track"
-              style="width: 0%;"
-            />
-            <!-- 滑块操作 -->
             
-            <div
-              class="t-slider__handle"
-              style="left: 0%;"
-            />
             
-            <!-- 刻度内容 -->
-            <div
-              class="t-slider__mark"
-            >
-              
-              
-            </div>
-          </div>
-          <div
-            class="t-slider-wrap__value"
-          >
-            30
           </div>
-          <!--v-if-->
         </div>
+        <!--v-if-->
+        <!--v-if-->
       </div>
+    </div>
+    
+  </div>
+  <div
+    class="tdesign-mobile-demo-block"
+    data-v-98828574=""
+  >
+    <h2
+      class="tdesign-mobile-demo-block__title"
+    >
+      03 规格
+    </h2>
+    <p
+      class="tdesign-mobile-demo-block__summary"
+    >
+      无标题滑动选择器
+    </p>
+    
+    <div
+      class="slider-demo"
+      data-v-98828574=""
+    >
       <div
-        class="section"
-        data-v-65b1e7f4=""
+        class="t-slider-wrap"
+        data-v-98828574=""
       >
+        <!--v-if-->
         <div
-          class="t-slider-wrap t-is-disabled t-is-mark"
-          data-v-65b1e7f4=""
+          class="t-slider"
         >
-          <!--v-if-->
+          <!-- 总长度 -->
           <div
-            class="t-slider"
+            class="t-slider__bar"
+          />
+          <!-- 滑块长度 -->
+          <div
+            class="t-slider__track"
+            style="width: 0%;"
+          />
+          <!-- 滑块操作 -->
+          
+          <div
+            class="t-slider__handle"
+            style="left: 0%;"
+          />
+          
+          <!-- 刻度内容 -->
+          <div
+            class="t-slider__mark"
           >
-            <!-- 总长度 -->
-            <div
-              class="t-slider__bar"
-            />
-            <!-- 滑块长度 -->
-            <div
-              class="t-slider__track"
-              style="width: 50%;"
-            />
-            <!-- 滑块操作 -->
             
-            <div
-              class="t-slider__handle"
-              style="left: 50%;"
-            />
             
-            <!-- 刻度内容 -->
-            <div
-              class="t-slider__mark"
-            >
-              
-              <div
-                class="t-slider__mark-text t-is-active"
-                style="left: 0%;"
-              >
-                小
-              </div>
-              <div
-                class="t-slider__mark-text t-is-"
-                style="left: 50%;"
-              >
-                中
-              </div>
-              <div
-                class="t-slider__mark-text t-is-"
-                style="left: 100%;"
-              >
-                大
-              </div>
-              
-            </div>
           </div>
-          <!--v-if-->
-          <!--v-if-->
         </div>
+        <!--v-if-->
+        <!--v-if-->
       </div>
+    </div>
+    
+  </div>
+  <div
+    class="tdesign-mobile-demo-block"
+    data-v-98828574=""
+  >
+    <!--v-if-->
+    <p
+      class="tdesign-mobile-demo-block__summary"
+    >
+      有标题滑动选择器
+    </p>
+    
+    <div
+      class="slider-demo"
+      data-v-98828574=""
+    >
       <div
-        class="section"
-        data-v-65b1e7f4=""
+        class="flex"
+        data-v-98828574=""
       >
+        <span
+          style="width: 120px; margin-right: 10px;"
+        >
+           选择器标题 
+        </span>
         <div
-          class="t-slider-wrap t-is-disabled"
-          data-v-65b1e7f4=""
+          class="t-slider-wrap"
         >
           <!--v-if-->
           <div
@@ -800,17 +601,13 @@ exports[`Slider > Slider mobileVue demo works fine 1`] = `
             <!-- 滑块长度 -->
             <div
               class="t-slider__track"
-              style="left: 30%; width: 40%;"
+              style="width: 0%;"
             />
             <!-- 滑块操作 -->
             
             <div
               class="t-slider__handle"
-              style="left: 30%;"
-            />
-            <div
-              class="t-slider__handle"
-              style="left: 70%;"
+              style="left: 0%;"
             />
             
             <!-- 刻度内容 -->
@@ -825,7 +622,6 @@ exports[`Slider > Slider mobileVue demo works fine 1`] = `
           <!--v-if-->
         </div>
       </div>
-      
     </div>
     
   </div>
@@ -881,6 +677,89 @@ exports[`Slider > Slider rangeVue demo works fine 1`] = `
 </div>
 `;
 
+exports[`Slider > Slider titleVue demo works fine 1`] = `
+<div
+  class="flex"
+>
+  <span
+    style="width: 120px; margin-right: 10px;"
+  >
+     选择器标题 
+  </span>
+  <div
+    class="t-slider-wrap"
+  >
+    <!--v-if-->
+    <div
+      class="t-slider"
+    >
+      <!-- 总长度 -->
+      <div
+        class="t-slider__bar"
+      />
+      <!-- 滑块长度 -->
+      <div
+        class="t-slider__track"
+        style="width: 0%;"
+      />
+      <!-- 滑块操作 -->
+      
+      <div
+        class="t-slider__handle"
+        style="left: 0%;"
+      />
+      
+      <!-- 刻度内容 -->
+      <div
+        class="t-slider__mark"
+      >
+        
+        
+      </div>
+    </div>
+    <!--v-if-->
+    <!--v-if-->
+  </div>
+</div>
+`;
+
+exports[`Slider > Slider unZeroVue demo works fine 1`] = `
+<div
+  class="t-slider-wrap"
+>
+  <!--v-if-->
+  <div
+    class="t-slider"
+  >
+    <!-- 总长度 -->
+    <div
+      class="t-slider__bar"
+    />
+    <!-- 滑块长度 -->
+    <div
+      class="t-slider__track"
+      style="width: 0%;"
+    />
+    <!-- 滑块操作 -->
+    
+    <div
+      class="t-slider__handle"
+      style="left: 0%;"
+    />
+    
+    <!-- 刻度内容 -->
+    <div
+      class="t-slider__mark"
+    >
+      
+      
+    </div>
+  </div>
+  <!--v-if-->
+  <!--v-if-->
+</div>
+`;
+
 exports[`Slider > Slider valueVue demo works fine 1`] = `
 <div
   class="t-slider-wrap"
@@ -896,13 +775,13 @@ exports[`Slider > Slider valueVue demo works fine 1`] = `
     <!-- 滑块长度 -->
     <div
       class="t-slider__track"
-      style="width: 60%;"
+      style="width: 50%;"
     />
     <!-- 滑块操作 -->
     
     <div
       class="t-slider__handle"
-      style="left: 60%;"
+      style="left: 50%;"
     />
     
     <!-- 刻度内容 -->
@@ -916,7 +795,7 @@ exports[`Slider > Slider valueVue demo works fine 1`] = `
   <div
     class="t-slider-wrap__value"
   >
-    60
+    50
   </div>
   <!--v-if-->
 </div>
diff --git a/src/slider/__test__/demo.test.jsx b/src/slider/__test__/demo.test.jsx
index dc354a25..59bb1a10 100644
--- a/src/slider/__test__/demo.test.jsx
+++ b/src/slider/__test__/demo.test.jsx
@@ -8,6 +8,8 @@ import disableVue from '@/slider/demos/disable.vue';
 import markVue from '@/slider/demos/mark.vue';
 import mobileVue from '@/slider/demos/mobile.vue';
 import rangeVue from '@/slider/demos/range.vue';
+import titleVue from '@/slider/demos/title.vue';
+import unZeroVue from '@/slider/demos/unZero.vue';
 import valueVue from '@/slider/demos/value.vue';
 
 const mapper = {
@@ -16,6 +18,8 @@ const mapper = {
   markVue,
   mobileVue,
   rangeVue,
+  titleVue,
+  unZeroVue,
   valueVue,
 };