登录 主页

vue - v-if 的使用

2025-06-13 09:28PM

在Vue.js中,v-if 是一个常用的指令,用于根据表达式的值条件性地渲染一块内容。当表达式的值为真(truthy)时,元素会被渲染;当为假(falsy)时,元素不会被渲染。

可以把下面的代码复制到一个 .html 文件中,在浏览器打开进行调试和学习

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue v-if 指令使用指南</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <style>
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      line-height: 1.6;
      background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
      color: #333;
      padding: 20px;
      min-height: 100vh;
    }
    .container {
      max-width: 1000px;
      margin: 0 auto;
      padding: 20px;
    }
    header {
      text-align: center;
      margin-bottom: 30px;
      padding: 20px;
      background: rgba(255, 255, 255, 0.8);
      border-radius: 15px;
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
    }
    h1 {
      color: #2c3e50;
      margin-bottom: 10px;
      font-size: 2.5rem;
    }
    .subtitle {
      color: #7f8c8d;
      font-size: 1.2rem;
      margin-bottom: 20px;
    }
    .card-container {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      gap: 25px;
      margin-bottom: 30px;
    }
    .card {
      background: white;
      border-radius: 15px;
      padding: 25px;
      box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
      transition: transform 0.3s ease, box-shadow 0.3s ease;
    }
    .card:hover {
      transform: translateY(-5px);
      box-shadow: 0 12px 30px rgba(0, 0, 0, 0.15);
    }
    .card h2 {
      color: #3498db;
      margin-bottom: 15px;
      padding-bottom: 10px;
      border-bottom: 2px solid #f0f0f0;
    }
    .example {
      padding: 20px;
      background: #f8f9fa;
      border-radius: 10px;
      margin: 15px 0;
    }
    .output {
      padding: 20px;
      background: #e8f4fc;
      border-radius: 10px;
      margin: 15px 0;
      min-height: 80px;
    }
    .controls {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
      margin: 20px 0;
    }
    button {
      background: #3498db;
      color: white;
      border: none;
      padding: 10px 20px;
      border-radius: 5px;
      cursor: pointer;
      font-weight: 600;
      transition: background 0.3s;
    }
    button:hover {
      background: #2980b9;
    }
    .toggle-btn {
      background: #2ecc71;
    }
    .toggle-btn:hover {
      background: #27ae60;
    }
    .reset-btn {
      background: #e74c3c;
    }
    .reset-btn:hover {
      background: #c0392b;
    }
    select, input {
      padding: 10px;
      border: 2px solid #ddd;
      border-radius: 5px;
      font-size: 1rem;
      width: 100%;
      margin: 10px 0;
    }
    .highlight {
      background: #fff9c4;
      padding: 2px 5px;
      border-radius: 3px;
    }
    .notes {
      background: white;
      border-radius: 15px;
      padding: 25px;
      box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
      margin-top: 30px;
    }
    .notes h2 {
      color: #e74c3c;
      margin-bottom: 15px;
    }
    .notes ul {
      padding-left: 20px;
    }
    .notes li {
      margin: 10px 0;
    }
    .comparison {
      display: flex;
      flex-wrap: wrap;
      gap: 20px;
      margin-top: 20px;
    }
    .comparison div {
      flex: 1;
      min-width: 300px;
    }
    code {
      background: #2c3e50;
      color: #f8f9fa;
      padding: 2px 6px;
      border-radius: 4px;
      font-family: monospace;
    }
    @media (max-width: 768px) {
      .card-container {
        grid-template-columns: 1fr;
      }
    }
  </style>
</head>
<body>
  <div id="app" class="container">
    <header>
      <h1>Vue v-if 指令使用指南</h1>
      <p class="subtitle">掌握条件渲染的核心概念</p>
    </header>

    <div class="card-container">
      <div class="card">
        <h2>1. 基础用法</h2>
        <div class="example">
          <p>控制元素是否渲染:</p>
          <div class="controls">
            <button @click="isVisible = !isVisible" class="toggle-btn">
              {{ isVisible ? '隐藏元素' : '显示元素' }}
            </button>
          </div>
        </div>
        <div class="output">
          <div v-if="isVisible" style="background: #2ecc71; padding: 20px; border-radius: 10px; color: white;">
            <h3>元素已显示!</h3>
            <p>这个元素在 isVisible 为 true 时渲染</p>
          </div>
          <div v-else style="background: #e74c3c; padding: 20px; border-radius: 10px; color: white;">
            <h3>元素已隐藏</h3>
            <p>这个元素在 isVisible 为 false 时渲染</p>
          </div>
        </div>
      </div>

      <div class="card">
        <h2>2. v-else 和 v-else-if</h2>
        <div class="example">
          <p>多条件分支:</p>
          <select v-model="userRole">
            <option value="guest">游客</option>
            <option value="user">普通用户</option>
            <option value="editor">编辑</option>
            <option value="admin">管理员</option>
          </select>
        </div>
        <div class="output">
          <div v-if="userRole === 'guest'" style="background: #95a5a6; padding: 20px; border-radius: 10px; color: white;">
            <h3>游客视图</h3>
            <p>您只有浏览权限</p>
          </div>
          <div v-else-if="userRole === 'user'" style="background: #3498db; padding: 20px; border-radius: 10px; color: white;">
            <h3>普通用户视图</h3>
            <p>您可以评论和收藏内容</p>
          </div>
          <div v-else-if="userRole === 'editor'" style="background: #9b59b6; padding: 20px; border-radius: 10px; color: white;">
            <h3>编辑视图</h3>
            <p>您可以创建和编辑内容</p>
          </div>
          <div v-else style="background: #f39c12; padding: 20px; border-radius: 10px; color: white;">
            <h3>管理员视图</h3>
            <p>您有系统完全访问权限</p>
          </div>
        </div>
      </div>

      <div class="card">
        <h2>3. 组合使用</h2>
        <div class="example">
          <p>复杂条件渲染:</p>
          <div class="controls">
            <label>
              <input type="checkbox" v-model="isLoggedIn"> 用户已登录
            </label>
            <label>
              <input type="checkbox" v-model="hasSubscription"> 拥有订阅
            </label>
          </div>
        </div>
        <div class="output">
          <div v-if="isLoggedIn">
            <div v-if="hasSubscription" style="background: #27ae60; padding: 20px; border-radius: 10px; color: white;">
              <h3>欢迎回来!</h3>
              <p>您拥有高级订阅,可以访问所有内容。</p>
            </div>
            <div v-else style="background: #f39c12; padding: 20px; border-radius: 10px; color: white;">
              <h3>欢迎回来!</h3>
              <p>您使用的是免费账户,考虑升级订阅。</p>
            </div>
          </div>
          <div v-else style="background: #e74c3c; padding: 20px; border-radius: 10px; color: white;">
            <h3>请登录</h3>
            <p>您需要登录才能访问此内容。</p>
          </div>
        </div>
      </div>
    </div>

    <div class="notes">
      <h2>关键概念</h2>
      <ul>
        <li><span class="highlight">v-if</span>:根据表达式的真假值条件性地渲染元素</li>
        <li><span class="highlight">v-else</span>:表示 v-if 的 "else" 块,不需要表达式</li>
        <li><span class="highlight">v-else-if</span>:充当 v-if 的 "else if" 块,可以链式调用</li>
        <li>与 <code>v-show</code> 的区别:<code>v-if</code> 是条件渲染(元素被创建/销毁),而 <code>v-show</code> 只是切换 CSS 的 display 属性</li>
        <li>使用 <code>key</code> 属性可以管理元素复用:当 key 改变时,Vue 会重新创建元素而不是复用</li>
        <li>在 <code>&lt;template&gt;</code> 元素上使用 v-if 可以分组渲染多个元素</li>
      </ul>
      
      <div class="comparison">
        <div>
          <h3>v-if 示例代码</h3>
          <pre><code>&lt;div v-if="isVisible"&gt;
  条件为真时显示
&lt;/div&gt;
&lt;div v-else&gt;
  条件为假时显示
&lt;/div&gt;</code></pre>
        </div>
        <div>
          <h3>v-show 示例代码</h3>
          <pre><code>&lt;div v-show="isVisible"&gt;
  总是存在于 DOM 中
&lt;/div&gt;</code></pre>
        </div>
      </div>
    </div>
  </div>

  <script>
    const { createApp, ref } = Vue
    
    createApp({
      setup() {
        const isVisible = ref(true)
        const userRole = ref('guest')
        const isLoggedIn = ref(false)
        const hasSubscription = ref(false)
        
        return {
          isVisible,
          userRole,
          isLoggedIn,
          hasSubscription
        }
      }
    }).mount('#app')
  </script>
</body>
</html>

在浏览器打开,页面显示内容如下:

 

返回>>

登录

请登录后再发表评论。

评论列表:

目前还没有人发表评论