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