x-show 显示隐藏 #
什么是 x-show? #
x-show 指令根据表达式的真假值来显示或隐藏元素。与 x-if 不同,x-show 只是切换元素的 CSS display 属性,元素始终存在于 DOM 中。
基本语法 #
html
<div x-show="表达式"></div>
当表达式为真值时显示元素,为假值时隐藏元素。
基本用法 #
简单切换 #
html
<div x-data="{ show: false }">
<button @click="show = !show">切换</button>
<div x-show="show">
这段内容会显示或隐藏
</div>
</div>
条件显示 #
html
<div x-data="{ count: 0 }">
<button @click="count++">增加</button>
<p x-show="count > 5">计数大于 5</p>
<p x-show="count <= 5">计数小于等于 5</p>
</div>
使用布尔值 #
html
<div x-data="{
isLoggedIn: false,
isAdmin: true
}">
<div x-show="isLoggedIn">欢迎回来</div>
<div x-show="isAdmin">管理员面板</div>
</div>
表达式用法 #
比较运算 #
html
<div x-data="{ score: 75 }">
<p x-show="score >= 90">优秀</p>
<p x-show="score >= 60 && score < 90">及格</p>
<p x-show="score < 60">不及格</p>
</div>
逻辑运算 #
html
<div x-data="{
hasPermission: true,
isActive: true
}">
<div x-show="hasPermission && isActive">可以访问</div>
<div x-show="hasPermission || isActive">部分可访问</div>
<div x-show="!hasPermission">无权限</div>
</div>
函数调用 #
html
<div x-data="{
items: [],
isEmpty() {
return this.items.length === 0
}
}">
<div x-show="isEmpty()">暂无数据</div>
</div>
计算属性 #
html
<div x-data="{
firstName: 'John',
lastName: '',
get hasFullName() {
return this.firstName && this.lastName
}
}">
<input x-model="firstName" placeholder="名">
<input x-model="lastName" placeholder="姓">
<p x-show="hasFullName">完整姓名: <span x-text="firstName + ' ' + lastName"></span></p>
</div>
x-show vs x-if #
| 特性 | x-show | x-if |
|---|---|---|
| DOM 存在 | 始终存在 | 条件为真时存在 |
| 切换方式 | CSS display | 添加/移除 DOM |
| 性能 | 切换快,初始渲染多 | 初始渲染少,切换慢 |
| 适用场景 | 频繁切换 | 条件很少改变 |
| 过渡动画 | 支持 | 支持 |
使用 x-show 的场景 #
html
<div x-data="{ active: false }">
<button @click="active = !active">切换</button>
<div x-show="active">
频繁切换的内容
</div>
</div>
使用 x-if 的场景 #
html
<div x-data="{ showDetails: false }">
<button @click="showDetails = true">显示详情</button>
<template x-if="showDetails">
<div>
大量内容,很少需要显示
</div>
</template>
</div>
过渡动画 #
x-show 可以配合 x-transition 添加过渡效果:
html
<div x-data="{ show: false }">
<button @click="show = !show">切换</button>
<div x-show="show" x-transition>
带过渡动画的内容
</div>
</div>
自定义过渡 #
html
<div x-data="{ show: false }">
<button @click="show = !show">切换</button>
<div
x-show="show"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 transform scale-90"
>
自定义过渡效果
</div>
</div>
实用示例 #
模态框 #
html
<div x-data="{ open: false }">
<button @click="open = true">打开模态框</button>
<div
x-show="open"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
class="modal-overlay"
@click="open = false"
>
<div class="modal-content" @click.stop>
<h2>模态框标题</h2>
<p>模态框内容</p>
<button @click="open = false">关闭</button>
</div>
</div>
</div>
<style>
.modal-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
}
.modal-content {
background: white;
padding: 20px;
border-radius: 8px;
max-width: 500px;
}
</style>
下拉菜单 #
html
<div x-data="{ open: false }" class="dropdown">
<button @click="open = !open">
菜单
<span x-show="!open">▼</span>
<span x-show="open">▲</span>
</button>
<div x-show="open" @click.away="open = false" class="dropdown-menu">
<a href="#">选项 1</a>
<a href="#">选项 2</a>
<a href="#">选项 3</a>
</div>
</div>
<style>
.dropdown {
position: relative;
}
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
background: white;
border: 1px solid #ddd;
border-radius: 4px;
padding: 8px 0;
min-width: 150px;
}
.dropdown-menu a {
display: block;
padding: 8px 16px;
text-decoration: none;
color: #333;
}
.dropdown-menu a:hover {
background: #f5f5f5;
}
</style>
加载状态 #
html
<div x-data="{ loading: false, data: null }">
<button @click="loadData()" :disabled="loading">
<span x-show="!loading">加载数据</span>
<span x-show="loading">加载中...</span>
</button>
<div x-show="loading" class="spinner">
加载中...
</div>
<div x-show="data && !loading">
数据内容
</div>
</div>
密码显示切换 #
html
<div x-data="{ showPassword: false }">
<input
:type="showPassword ? 'text' : 'password'"
placeholder="密码"
>
<button @click="showPassword = !showPassword">
<span x-show="!showPassword">显示密码</span>
<span x-show="showPassword">隐藏密码</span>
</button>
</div>
标签页 #
html
<div x-data="{ activeTab: 'home' }">
<div class="tabs">
<button
@click="activeTab = 'home'"
:class="{ active: activeTab === 'home' }"
>
首页
</button>
<button
@click="activeTab = 'profile'"
:class="{ active: activeTab === 'profile' }"
>
个人资料
</button>
<button
@click="activeTab = 'settings'"
:class="{ active: activeTab === 'settings' }"
>
设置
</button>
</div>
<div class="content">
<div x-show="activeTab === 'home'">首页内容</div>
<div x-show="activeTab === 'profile'">个人资料内容</div>
<div x-show="activeTab === 'settings'">设置内容</div>
</div>
</div>
手风琴 #
html
<div x-data="{
items: [
{ title: '问题 1', answer: '答案 1', open: false },
{ title: '问题 2', answer: '答案 2', open: false },
{ title: '问题 3', answer: '答案 3', open: false }
]
}">
<template x-for="item in items">
<div class="accordion-item">
<button
@click="item.open = !item.open"
class="accordion-header"
>
<span x-text="item.title"></span>
<span x-show="!item.open">+</span>
<span x-show="item.open">-</span>
</button>
<div x-show="item.open" x-collapse class="accordion-content">
<p x-text="item.answer"></p>
</div>
</div>
</template>
</div>
消息提示 #
html
<div x-data="{
message: '',
type: 'info',
show: false,
showMessage(msg, type = 'info') {
this.message = msg
this.type = type
this.show = true
setTimeout(() => this.show = false, 3000)
}
}">
<button @click="showMessage('操作成功', 'success')">成功提示</button>
<button @click="showMessage('操作失败', 'error')">错误提示</button>
<button @click="showMessage('请注意', 'warning')">警告提示</button>
<div
x-show="show"
x-transition
:class="'alert alert-' + type"
x-text="message"
></div>
</div>
<style>
.alert {
padding: 12px 20px;
border-radius: 4px;
margin-top: 10px;
}
.alert-info { background: #e6f7ff; color: #1890ff; }
.alert-success { background: #f6ffed; color: #52c41a; }
.alert-error { background: #fff2f0; color: #ff4d4f; }
.alert-warning { background: #fffbe6; color: #faad14; }
</style>
注意事项 #
1. 假值判断 #
以下值会被判断为假:
html
<div x-show="false"></div>
<div x-show="0"></div>
<div x-show=""></div>
<div x-show="null"></div>
<div x-show="undefined"></div>
<div x-show="NaN"></div>
2. 初始闪烁 #
在 Alpine.js 加载前,x-show 元素可能会短暂显示。使用 x-cloak 解决:
html
<style>
[x-cloak] { display: none !important; }
</style>
<div x-show="hidden" x-cloak>
不会闪烁的内容
</div>
3. 与 CSS 冲突 #
x-show 会设置 display: none,可能与现有 CSS 冲突:
html
<div x-show="visible" style="display: flex;">
x-show 会覆盖 display 属性
</div>
解决方案:使用类名控制布局
html
<div x-show="visible" class="flex-container">
内容
</div>
小结 #
x-show 指令要点:
- 通过 CSS
display属性控制显示隐藏 - 元素始终存在于 DOM 中
- 适合频繁切换的场景
- 支持过渡动画
- 注意初始闪烁问题
下一章,我们将学习 x-if 指令进行条件渲染。
最后更新:2026-03-28