Important
本库使用了2025最新的CSS特性,不适合用于生产环境。
This library uses the latest 2025 CSS features and is not suitable for production environments.
本库功能仍有部分功能未完成文档尚未完成。
This library has some features that are not finished yet.
后续将提供机器翻译的英文版。
A machine-translated English version will be provided later.
Tips component for displaying extra info on the interface in Nuogz Web App, based on CSS Anchor Positioning and Vue 3
贴纸用于在界面中显示额外的信息,提供即时的指引或补充说明,以辅助用户理解和使用功能。用于Nuogz Web App,基于CSS Anchor Positioning、Vue3、UnoCSS
经过一系列的迭代,从原来的提示组件vue-tip升级重构为全新的web-app-tip
web-app-tip已弃用tippy.js,改为使用最新的CSS锚点定位(CSS Anchor Positioning)语法作为核心实现。
额外功能与Vue内置的功能进行结合,最大程度地不影响Vue的渲染逻辑
基础示例:
<!-- index.vue -->
<template>
<AppOrbit>...</AppOrbit>
<AppTip />
</template>
<script setup>
import AppTip, { install as installAppTip } from '@nuogz/web-app-tip';
// 需要createApp后通过provide()提供app实例
// 在createApp后立即install也是可以的
const app = inject('app');
installAppTip(app);
</script>贴纸分为两部分,自定义指令v-tip与组件<AppTip>。
v-tip指令通过install函数安装。
<AppTip>组件用于动态渲染展示贴纸所需要的HTML元素。
请将<AppTip>置于app的根元素下
- body
- app (index.vue)
- (module.vue)
- app-tip-box
- app-tip (或teleport模板内容)
- app-tip-shadow (用于自动位置功能的相交检测)
- app (index.vue)
如果app使用天轨Orbit组件,那么DOM结构如下:
- body
- app (index.vue)
- app-moon
- app-main
- (module.vue)
- app-moon
- app-tip-box
- app-tip (或teleport模板内容)
- app-tip-shadow (用于自动位置功能的相交检测)
- app (index.vue)
注意:相关元素会根据实际调用次数增多,一个指令对应一套元素。并不是单例模式
根据Vue指令的语法设计,我们可以通过三种途径配置app-tip
<button v-tip:[arg].modifier="value">Im a button</button>指定Tip的显示内容。传入的内容最终会在模板中以{{ value }}的形式展示
修饰符用于指定启用/禁用某个特性。具体修饰符的功能请继续查看下面各项功能的说明
利用Vue指令中的动态参数语法,我们可以传入一个TipArg对象来更详细地配置各项tip特性
在Vue的文档和types中,arg的类型一直是string。但经过实测向arg传递object是有效。
不排除以后此途径会失效。届时需要迁移到其他路径
显示额外内容是贴纸的核心基础功能,支持多种来源
基础用法
<button v-tip="'Im a tip'">Im a button</button>通过TipArg.value传入
<template>
<button v-tip:[arg]>Im a button</button>
</template>
<script setup>
const arg = ref({ value: 'Im a tip' });
</script>此功能用于显示实时渲染的Vue模板
为了避免入侵Vue的渲染逻辑,其核心功能将使用Vue内置的<Teleport>组件实现
由于<Teleport>的目标元素必须与<Teleport>在同一个挂载/更新周期内渲染。
要使用该功能,必须向v-tip传递一个TipArg,且TipArg.teleport设置为true。
当对应的<app-tip-box>渲染后,贴纸会将<app-tip-box>传递到TipArg.teleportTo中。
在渲染前,仍需向<Teleport>的to属性提供有效值以过渡,如body
最佳实践:
<template>
<button v-tip:[arg]>Im a button</button>
<Teleport :to="$tip.teleportTo || 'body'">
<span>Im a template tip</span>
</Teleport>
</template>
<script setup>
const arg = ref({ teleport: true });
</script>在一般情况下,将<Teleport>的to属性短暂地设置为其他过渡用元素(如body)并不会造成闪烁。
但在极端情况下,渲染效率低,待传送的内容仍可能会因为停留在过渡用元素太久,
导致传送内容被渲染到视口中,最后造成产生闪烁。
若过渡用元素本身是隐藏的,则不受影响
此时可以通过对<Teleport>追加disabled和defer属性来避免闪烁:
<Teleport :to="..."
defer :disabled="$tip.teleportTo ? false : true"
>...</Teleport>area 默认值:top center
| 值 | 作用 | 修饰符 |
|---|---|---|
top |
居上 | .top |
bottom |
居下 | .bottom |
center |
居中 | .center |
left |
居左 | .left |
right |
居右 | .right |
位置功能依赖于CSS的position-area。因此area也可以组合地使用span-*,如设置为top span-right。
通常情况下显示的位置是正确的。但是自动位置功能是代码实时检后测调整的,并未对span-*进行完整的兼容,可能会意外的行为。
autoArea 默认值:true
当检测到Tip开始离开视口时,会自动调整Tip位置到新的位置,以尝试完成显示Tip
| 特性 | 作用 | 修饰符 |
|---|---|---|
true |
离开视口时自动调整位置 | - |
false |
什么都不做 | .noAutoArea |
CSS anchor positioning有提供
position-try等属性用于自动调整位置。
但目前相关属性的效果并不理想,因此没有将其纳入此次重构中,转为通过IntersectionObserver实现
hover 默认值:show
| 值 | 作用 | 修饰符 |
|---|---|---|
false |
什么都不做 | .noHoverShow |
show |
显示Tip(离开隐藏) | - |
pin |
显示Tip(离开不隐藏) | .hoverPin |
click 默认值:false
| 特性 | 作用 | 修饰符 |
|---|---|---|
false |
什么都不做 | - |
pin-flip |
切换Tip(离开不隐藏) | .clickPinFlip |
pin |
显示Tip(离开不隐藏) | .clickPin |
show-flip |
切换Tip(离开隐藏) | .clickShowFlip |
show |
显示Tip(离开隐藏) | .clickShow |
click:show-flip|show适用于hover:false的情况,否则行为会被hover:show覆盖
hide$clickGlobal 默认值:true
当Tip固定时,默认全局其他任意元素点击后隐藏Tip,以模拟离开且失焦
- 按下后触发滚动,不会导致解除
- 当点击是目标元素或Tip元素时,不会导致解除
| 特性 | 作用 | 修饰符 |
|---|---|---|
true |
固定后全局任意点击解除固定 | - |
false |
什么都不做 | .noUnpinGlobal |
watchArg 默认值:false
当指令的arg部分传入一个对象,对象内部变化后,不会触发指令的update事件(即使传入的是一个reactive对象)。
在当前的Vue版本中,当指令的参数部分v-tip:[arg]是一个对象时,即使该对象是响应式的,其内部属性的变化也不会触发指令的update钩子函数。
此时可配置watchArg:true或修饰符.watchArg,对arg对象进行深度侦听。
| 特性 | 作用 | 修饰符 |
|---|---|---|
true |
对arg对象进行深度侦听 | .watchArg |
false |
什么都不做 | - |
intangible 默认值:false
| 特性 | 作用 | 修饰符 |
|---|---|---|
false |
什么都不做 | - |
true或tip |
禁止app-tip进行交互 | .intang |
box |
禁止与app-tip-box进行交互 | .intangBox |
可否与内在元素交互
theme 默认值:base
支持自定义主题,通过[theme=主题名]定义
默认主题通过CSS变量--app-tip-back: var(--contrast)来定义背景,你随时可以覆盖这个变量
主题不适用于模板内容
| 特性 | 作用 | 修饰符 |
|---|---|---|
base |
默认主题 | - |
base-nowarp |
默认主题(不换行) | .nowrap |
<template>
<button v-tip:[arg]>Im a button</button>
</template>
<script setup>
const arg = ref({ theme: 'test' });
</script>
<style lang="sass" scoped>
:global(app-tip[theme=test])
@apply p-2 py-1.5 bg-green-4 rounded-lg shadow-d1-md ws-pre
</style>因为贴纸是<app>子元素,所以需要将主题提升到全局。
建议将主题样式放置在全局位置,或者使用足够独特的名字。不要像演示这样在某个单文件组件中定义
offset 默认值:4
贴纸与目标元素的间隔。会位置自动调整间隔的位置
本质是css长度单位。
如果是number类型,会自动补全px单位。
如果是string类型,则不会做任何修改
arrow 默认值:true
在贴纸和目标元素之间显示指向目标元素的三角箭头
已支持在四角位置、span位置显示三角箭头
| 特性 | 作用 | 修饰符 |
|---|---|---|
true |
在贴纸和目标元素之间显示三角箭头 | - |
false |
不显示三角箭头 | .noArrow |
refInstance 默认值:null
在一些需要手动控制贴纸显示的常见下,需要直接访问实例。此时可以TipArg.refInstance传递true或一个回调函数,当实例初始化完毕后,会返回Tip实例:
| 特性 | 回调方式 |
|---|---|
true |
TipArg.instance = tip; |
(tip) => {} |
调用函数 |
贴纸抽象了设计了CSS变量,以方便调整显示
| CSS变量 | 作用 | 默认值 |
|---|---|---|
--app-tip-text |
base主题下的文字颜色 | var(--main-back) |
--app-tip-back |
base主题下的背景颜色 | var(--main-solid) |
--app-tip-arrow-size |
箭头尺寸 | 4px |