开发预览 更新于 2026-05-10

Tooltip 文字提示

轻量浮层提示 —— 4 种 placement、自动避让视口边缘、hover/focus 双触发。

基础用法

包裹任意触发元素。鼠标悬停或键盘聚焦时显示,鼠标移出或失焦时隐藏。Tooltip 通过 Teleport / Portal 渲染到 <body>,不受父容器 overflow 影响。

背景 视口
src/App.vue
<script setup lang="ts">
import { CfButton, CfTooltip } from '@chufix-design/vue';
</script>
<template>
  <CfTooltip content="鼠标悬停或键盘聚焦都会显示">
    <CfButton variant="tertiary">悬停我</CfButton>
  </CfTooltip>
</template>
<script setup>
import { CfButton, CfTooltip } from '@chufix-design/vue';
</script>
<template>
  <CfTooltip content="鼠标悬停或键盘聚焦都会显示">
    <CfButton variant="tertiary">悬停我</CfButton>
  </CfTooltip>
</template>
import { CfButton, CfTooltip } from '@chufix-design/react';

export default function Demo() {
return (
  <CfTooltip content="鼠标悬停或键盘聚焦都会显示">
    <CfButton variant="tertiary">悬停我</CfButton>
  </CfTooltip>
);
}
import { CfButton, CfTooltip } from '@chufix-design/react';

export default function Demo() {
return (
  <CfTooltip content="鼠标悬停或键盘聚焦都会显示">
    <CfButton variant="tertiary">悬停我</CfButton>
  </CfTooltip>
);
}

4 种方向

placement 控制首选方向。当首选方向放不下(贴近视口边缘)时,会自动翻到对侧。

背景 视口
src/App.vue
<script setup lang="ts">
import { CfButton, CfTooltip } from '@chufix-design/vue';
</script>
<template>
  <!-- 3×3 grid: each direction has its own quadrant so auto-flip doesn't fire. -->
  <div class="tt-grid">
    <span></span>
    <CfTooltip content="顶部" placement="top">
      <CfButton variant="tertiary">Top</CfButton>
    </CfTooltip>
    <span></span>
    <CfTooltip content="左侧" placement="left">
      <CfButton variant="tertiary">Left</CfButton>
    </CfTooltip>
    <span></span>
    <CfTooltip content="右侧" placement="right">
      <CfButton variant="tertiary">Right</CfButton>
    </CfTooltip>
    <span></span>
    <CfTooltip content="底部" placement="bottom">
      <CfButton variant="tertiary">Bottom</CfButton>
    </CfTooltip>
    <span></span>
  </div>
</template>
<style scoped>
.tt-grid {
  display: grid;
  grid-template-columns: repeat(3, auto);
  justify-content: center;
  gap: 56px 80px;
  padding: 56px 0;
}
</style>
<script setup>
import { CfButton, CfTooltip } from '@chufix-design/vue';
</script>
<template>
  <!-- 3×3 grid: each direction has its own quadrant so auto-flip doesn't fire. -->
  <div class="tt-grid">
    <span></span>
    <CfTooltip content="顶部" placement="top">
      <CfButton variant="tertiary">Top</CfButton>
    </CfTooltip>
    <span></span>
    <CfTooltip content="左侧" placement="left">
      <CfButton variant="tertiary">Left</CfButton>
    </CfTooltip>
    <span></span>
    <CfTooltip content="右侧" placement="right">
      <CfButton variant="tertiary">Right</CfButton>
    </CfTooltip>
    <span></span>
    <CfTooltip content="底部" placement="bottom">
      <CfButton variant="tertiary">Bottom</CfButton>
    </CfTooltip>
    <span></span>
  </div>
</template>
<style scoped>
.tt-grid {
  display: grid;
  grid-template-columns: repeat(3, auto);
  justify-content: center;
  gap: 56px 80px;
  padding: 56px 0;
}
</style>
import { CfButton, CfTooltip } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfTooltip content="顶部" placement="top"><CfButton>Top</CfButton></CfTooltip>
      <CfTooltip content="底部" placement="bottom"><CfButton>Bottom</CfButton></CfTooltip>
      <CfTooltip content="左侧" placement="left"><CfButton>Left</CfButton></CfTooltip>
      <CfTooltip content="右侧" placement="right"><CfButton>Right</CfButton></CfTooltip>
    </>
  );
}
import { CfButton, CfTooltip } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfTooltip content="顶部" placement="top"><CfButton>Top</CfButton></CfTooltip>
      <CfTooltip content="底部" placement="bottom"><CfButton>Bottom</CfButton></CfTooltip>
      <CfTooltip content="左侧" placement="left"><CfButton>Left</CfButton></CfTooltip>
      <CfTooltip content="右侧" placement="right"><CfButton>Right</CfButton></CfTooltip>
    </>
  );
}

延迟与长文本

delay 控制显示前的等待时间(毫秒)。maxWidth 限制最大宽度,超出换行。

背景 视口
src/App.vue
<script setup lang="ts">
import { CfButton, CfTooltip } from '@chufix-design/vue';
</script>
<template>
  <div class="demo-row" style="gap: 1rem;">
    <CfTooltip content="0 延迟显示" :delay="0">
      <CfButton variant="tertiary">无延迟</CfButton>
    </CfTooltip>
    <CfTooltip content="500ms 延迟" :delay="500">
      <CfButton variant="tertiary">500ms</CfButton>
    </CfTooltip>
    <CfTooltip
      content="内容比较长会自动换行,限制最大宽度避免一行甩到屏幕外去;超出视口边缘也会自动翻转方向。"
      :max-width="220"
    >
      <CfButton variant="tertiary">长文本</CfButton>
    </CfTooltip>
  </div>
</template>
<script setup>
import { CfButton, CfTooltip } from '@chufix-design/vue';
</script>
<template>
  <div class="demo-row" style="gap: 1rem;">
    <CfTooltip content="0 延迟显示" :delay="0">
      <CfButton variant="tertiary">无延迟</CfButton>
    </CfTooltip>
    <CfTooltip content="500ms 延迟" :delay="500">
      <CfButton variant="tertiary">500ms</CfButton>
    </CfTooltip>
    <CfTooltip
      content="内容比较长会自动换行,限制最大宽度避免一行甩到屏幕外去;超出视口边缘也会自动翻转方向。"
      :max-width="220"
    >
      <CfButton variant="tertiary">长文本</CfButton>
    </CfTooltip>
  </div>
</template>
import { CfButton, CfTooltip } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <div className="demo-row" style={{ gap: "1rem" }}>
          <CfTooltip content="0 延迟显示" delay={0}>
            <CfButton variant="tertiary">无延迟</CfButton>
          </CfTooltip>
          <CfTooltip content="500ms 延迟" delay={500}>
            <CfButton variant="tertiary">500ms</CfButton>
          </CfTooltip>
          <CfTooltip content="内容比较长会自动换行,限制最大宽度避免一行甩到屏幕外去;超出视口边缘也会自动翻转方向。" maxWidth={220} >
            <CfButton variant="tertiary">长文本</CfButton>
          </CfTooltip>
        </div>
    </>
  );
}
import { CfButton, CfTooltip } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <div className="demo-row" style={{ gap: "1rem" }}>
          <CfTooltip content="0 延迟显示" delay={0}>
            <CfButton variant="tertiary">无延迟</CfButton>
          </CfTooltip>
          <CfTooltip content="500ms 延迟" delay={500}>
            <CfButton variant="tertiary">500ms</CfButton>
          </CfTooltip>
          <CfTooltip content="内容比较长会自动换行,限制最大宽度避免一行甩到屏幕外去;超出视口边缘也会自动翻转方向。" maxWidth={220} >
            <CfButton variant="tertiary">长文本</CfButton>
          </CfTooltip>
        </div>
    </>
  );
}

富文本内容 (slot)

content prop 只能传字符串。需要在浮层里渲染加粗、<kbd>、链接、表格等富内容时用 #content 具名插槽(React 端:content 直接接收 ReactNode)。

背景 视口
src/App.vue
<script setup lang="ts">
import { CfButton, CfTooltip } from '@chufix-design/vue';
</script>
<template>
  <CfTooltip placement="bottom" :max-width="260">
    <CfButton variant="tertiary">富文本内容</CfButton>
    <template #content>
      <div class="adm-rich">
        <strong>键盘快捷键</strong>
        <kbd>⌘</kbd> + <kbd>K</kbd> 打开命令面板
      </div>
    </template>
  </CfTooltip>
  <CfTooltip placement="bottom" :max-width="220">
    <CfButton variant="tertiary">多行说明</CfButton>
    <template #content>
      <div class="adm-rich">
        <span class="adm-title">同步状态</span>
        最近同步:<span class="adm-mono">2026-05-12 14:30</span>
        <br />
        下次同步:<span class="adm-mono">14:45</span>
      </div>
    </template>
  </CfTooltip>
</template>
<style scoped>
.adm-rich {
  display: flex;
  flex-direction: column;
  gap: 4px;
  line-height: 1.55;
}
.adm-title { font-weight: 600; }
.adm-mono { font-family: var(--font-mono); font-size: 0.9em; }
kbd {
  font-family: var(--font-mono);
  background: rgb(255 255 255 / 0.14);
  border-radius: 3px;
  padding: 0 4px;
  font-size: 0.9em;
}
</style>
<script setup>
import { CfButton, CfTooltip } from '@chufix-design/vue';
</script>
<template>
  <CfTooltip placement="bottom" :max-width="260">
    <CfButton variant="tertiary">富文本内容</CfButton>
    <template #content>
      <div class="adm-rich">
        <strong>键盘快捷键</strong>
        <kbd>⌘</kbd> + <kbd>K</kbd> 打开命令面板
      </div>
    </template>
  </CfTooltip>
  <CfTooltip placement="bottom" :max-width="220">
    <CfButton variant="tertiary">多行说明</CfButton>
    <template #content>
      <div class="adm-rich">
        <span class="adm-title">同步状态</span>
        最近同步:<span class="adm-mono">2026-05-12 14:30</span>
        <br />
        下次同步:<span class="adm-mono">14:45</span>
      </div>
    </template>
  </CfTooltip>
</template>
<style scoped>
.adm-rich {
  display: flex;
  flex-direction: column;
  gap: 4px;
  line-height: 1.55;
}
.adm-title { font-weight: 600; }
.adm-mono { font-family: var(--font-mono); font-size: 0.9em; }
kbd {
  font-family: var(--font-mono);
  background: rgb(255 255 255 / 0.14);
  border-radius: 3px;
  padding: 0 4px;
  font-size: 0.9em;
}
</style>
import { CfButton, CfTooltip } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfTooltip
      placement="bottom"
      maxWidth={260}
      content={<>
        <strong>键盘快捷键</strong>
        <kbd>⌘</kbd> + <kbd>K</kbd> 打开命令面板
      </>}
      >
      <CfButton variant="tertiary">富文本内容</CfButton>
      </CfTooltip>
    </>
  );
}
import { CfButton, CfTooltip } from '@chufix-design/react';

export default function Demo() {
  return (
    <>
      <CfTooltip
      placement="bottom"
      maxWidth={260}
      content={<>
        <strong>键盘快捷键</strong>
        <kbd>⌘</kbd> + <kbd>K</kbd> 打开命令面板
      </>}
      >
      <CfButton variant="tertiary">富文本内容</CfButton>
      </CfTooltip>
    </>
  );
}

禁用 tooltip

disabled 让 tooltip 完全不显示 —— 用于按条件屏蔽提示(如某些表单字段已 valid 时不再提示规则)。和 v-show="false" 包裹触发器不同,触发器本身依然渲染、可点击。

背景 视口
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfButton, CfTooltip } from '@chufix-design/vue';

const disabled = ref<boolean>(false);
</script>
<template>
  <div class="demo-row">
    <CfTooltip content="hover 才会出现" :disabled="disabled">
      <CfButton variant="tertiary">悬停我</CfButton>
    </CfTooltip>
    <CfButton size="sm" variant="ghost" @click="disabled = !disabled">
      {{ disabled ? '启用 tooltip' : '禁用 tooltip' }}
    </CfButton>
    <span class="adm-hint">当前 disabled = {{ disabled }}</span>
  </div>
</template>
<style scoped>
.adm-hint { color: var(--fg-3); font-size: var(--t-12); }
</style>
<script setup>
import { ref } from 'vue';
import { CfButton, CfTooltip } from '@chufix-design/vue';

const disabled = ref<boolean>(false);
</script>
<template>
  <div class="demo-row">
    <CfTooltip content="hover 才会出现" :disabled="disabled">
      <CfButton variant="tertiary">悬停我</CfButton>
    </CfTooltip>
    <CfButton size="sm" variant="ghost" @click="disabled = !disabled">
      {{ disabled ? '启用 tooltip' : '禁用 tooltip' }}
    </CfButton>
    <span class="adm-hint">当前 disabled = {{ disabled }}</span>
  </div>
</template>
<style scoped>
.adm-hint { color: var(--fg-3); font-size: var(--t-12); }
</style>
import { useState } from 'react';
import { CfButton, CfTooltip } from '@chufix-design/react';

export default function Demo() {
  const [disabled, setDisabled] = useState(false);
  const [disabled, setDisabled] = useState(false);
  return (
    <>
      <CfTooltip content="只在启用时才出现" disabled={disabled}>
      <CfButton variant="tertiary">悬停我</CfButton>
      </CfTooltip>
      <CfButton size="sm" variant="ghost" onClick={() => setDisabled(!disabled)}>
      {disabled ? '启用' : '禁用'} tooltip
      </CfButton>
    </>
  );
}
import { useState } from 'react';
import { CfButton, CfTooltip } from '@chufix-design/react';

export default function Demo() {
  const [disabled, setDisabled] = useState(false);
  const [disabled, setDisabled] = useState(false);
  return (
    <>
      <CfTooltip content="只在启用时才出现" disabled={disabled}>
      <CfButton variant="tertiary">悬停我</CfButton>
      </CfTooltip>
      <CfButton size="sm" variant="ghost" onClick={() => setDisabled(!disabled)}>
      {disabled ? '启用' : '禁用'} tooltip
      </CfButton>
    </>
  );
}

API

Props

Prop类型默认值说明
contentstring(Vue)/ ReactNode(React)浮层内容;Vue 还可用 #content 插槽
placement'top' | 'bottom' | 'left' | 'right''top'首选方向,溢出时自动翻转到对侧
delaynumber100显示前延迟(毫秒)
hideDelaynumber80隐藏前延迟,避免抖动
disabledbooleanfalse完全不显示
offsetnumber8触发器与浮层之间的间距(像素)
maxWidthnumber | string限制最大宽度,超出换行

Slots

Slot作用域参数说明
default触发元素(React 端:children
content浮层富文本内容(覆盖 content prop)

反馈与讨论

Tooltip 文字提示 的讨论

0
0 / 600
正在加载评论...