条件渲染

在开发中,我们经常需要根据条件来显示不同的内容。Vitarx 提供了多种方式来实现条件渲染。

三元运算符

最常用的条件渲染方式是三元运算符——条件为真显示 A,否则显示 B:

tsx
import { ref, createApp } from 'vitarx'

function App() {
  const isLoggedIn = ref(false)

  return (
    <div>
      {isLoggedIn.value ? <p>欢迎回来!</p> : <p>请先登录</p>}
      <button onClick={() => (isLoggedIn.value = !isLoggedIn.value)}>切换状态</button>
    </div>
  )
}

createApp(App).mount('#app')

逻辑与

当你只需要在条件为真时显示内容,不需要 else 分支时,使用逻辑与 &&

tsx
import { ref, createApp } from 'vitarx'

function App() {
  const showMessage = ref(true)

  return (
    <div>
      {showMessage.value && <p>这条消息可以切换显示</p>}
      <button onClick={() => (showMessage.value = !showMessage.value)}>切换显示</button>
    </div>
  )
}

createApp(App).mount('#app')

WARNING

避免在 && 左侧使用可能为 0 或空字符串的值,因为它们会被渲染出来:

tsx
// 如果 count 是 0,页面会显示 "0" 而不是什么都不显示
{
  count.value && <p>有数据</p>
}

// 正确写法:使用显式布尔判断
{
  count.value > 0 && <p>有数据</p>
}

v-if / v-else 指令

Vitarx 的编译器支持 v-ifv-else-ifv-else 指令,写法更接近模板语法:

tsx
import { ref, createApp } from 'vitarx'

function App() {
  const type = ref<'admin' | 'user' | 'guest'>('guest')

  return (
    <div>
      <div v-if={type.value === 'admin'}>管理员面板</div>
      <div v-else-if={type.value === 'user'}>用户中心</div>
      <div v-else>访客页面</div>

      <div style={{ marginTop: '12px' }}>
        <button onClick={() => (type.value = 'admin')}>管理员</button>
        <button onClick={() => (type.value = 'user')}>用户</button>
        <button onClick={() => (type.value = 'guest')}>访客</button>
      </div>
    </div>
  )
}

createApp(App).mount('#app')

INFO

v-if / v-else 是编译器指令,由 @vitarx/plugin-vite 在编译阶段处理。条件为假的分支不会创建 DOM,切换时会销毁和重建 DOM 元素。

三种方式的选择建议

方式适用场景特点
三元运算符两种状态切换最常用,简单直观
逻辑与 &&只需要"显示/隐藏"简洁,无需 else
v-if / v-else多条件分支写法接近模板,适合复杂条件

实际开发中,三元运算符和逻辑与已经能满足大部分需求。v-if 系列指令适合条件分支较多的场景。

完整示例

下面是一个根据用户状态显示不同界面的完整示例:

tsx
import { ref, createApp } from 'vitarx'

function App() {
  const status = ref<'loading' | 'success' | 'error'>('loading')

  const simulateLoad = () => {
    status.value = 'loading'
    setTimeout(() => {
      status.value = Math.random() > 0.3 ? 'success' : 'error'
    }, 1500)
  }

  return (
    <div style={{ padding: '20px', maxWidth: '400px', margin: '0 auto' }}>
      <h2>条件渲染示例</h2>

      {/* 使用三元运算符 */}
      <div
        style={{
          padding: '20px',
          textAlign: 'center',
          borderRadius: '8px',
          background:
            status.value === 'loading'
              ? '#fff3cd'
              : status.value === 'success'
                ? '#d4edda'
                : '#f8d7da'
        }}
      >
        {status.value === 'loading' ? (
          <p>加载中,请稍候...</p>
        ) : status.value === 'success' ? (
          <div>
            <p style={{ color: '#155724', fontWeight: 'bold' }}>加载成功!</p>
            <p>数据已就绪</p>
          </div>
        ) : (
          <div>
            <p style={{ color: '#721c24', fontWeight: 'bold' }}>加载失败</p>
            <p>请重试</p>
          </div>
        )}
      </div>

      {/* 使用逻辑与 */}
      {status.value === 'error' && (
        <p style={{ color: '#721c24', marginTop: '12px' }}>提示:点击下方按钮重新加载</p>
      )}

      <button
        onClick={simulateLoad}
        style={{
          marginTop: '16px',
          padding: '8px 16px',
          cursor: 'pointer'
        }}
      >
        {status.value === 'loading' ? '加载中...' : '重新加载'}
      </button>
    </div>
  )
}

createApp(App).mount('#app')

下一步