Skip to content

Conditional Rendering

In uni-app development, conditional rendering is a common requirement that allows you to display different content based on different conditions. This guide will introduce various conditional rendering methods and best practices.

Basic Conditional Rendering

v-if Directive

The v-if directive is the most basic conditional rendering method, which conditionally renders elements based on expression values.

vue
<template>
  <view>
    <text v-if="isLogin">Welcome back!</text>
    <text v-else>Please log in</text>
  </view>
</template>

<script>
export default {
  data() {
    return {
      isLogin: false
    }
  }
}
</script>

v-show Directive

The v-show directive controls element visibility by toggling CSS display property.

vue
<template>
  <view>
    <text v-show="isVisible">This text can be shown or hidden</text>
    <button @click="toggleVisible">Toggle</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      isVisible: true
    }
  },
  methods: {
    toggleVisible() {
      this.isVisible = !this.isVisible
    }
  }
}
</script>

Difference Between v-if and v-show

Featurev-ifv-show
Rendering methodConditional renderingAlways rendered, controls visibility
PerformanceHigher switching costHigher initial rendering cost
Suitable scenariosInfrequent condition changesFrequent condition changes
Lifecycle hooksTriggered on condition changeNot triggered

Complex Conditional Rendering

Multiple Conditions

vue
<template>
  <view>
    <text v-if="userType === 'admin'">Administrator Panel</text>
    <text v-else-if="userType === 'user'">User Panel</text>
    <text v-else-if="userType === 'guest'">Guest Panel</text>
    <text v-else>Unknown User Type</text>
  </view>
</template>

<script>
export default {
  data() {
    return {
      userType: 'user'
    }
  }
}
</script>

Template Conditional Rendering

Use <template> tag for conditional rendering of multiple elements:

vue
<template>
  <view>
    <template v-if="showUserInfo">
      <text>Username: {{ username }}</text>
      <text>Email: {{ email }}</text>
      <text>Phone: {{ phone }}</text>
    </template>
  </view>
</template>

<script>
export default {
  data() {
    return {
      showUserInfo: true,
      username: 'John',
      email: 'john@example.com',
      phone: '123-456-7890'
    }
  }
}
</script>

List Conditional Rendering

Filtering Lists

vue
<template>
  <view>
    <input v-model="searchKeyword" placeholder="Search users" />
    <view v-for="user in filteredUsers" :key="user.id">
      <text>{{ user.name }}</text>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      searchKeyword: '',
      users: [
        { id: 1, name: 'Alice', status: 'active' },
        { id: 2, name: 'Bob', status: 'inactive' },
        { id: 3, name: 'Charlie', status: 'active' }
      ]
    }
  },
  computed: {
    filteredUsers() {
      return this.users.filter(user => 
        user.name.toLowerCase().includes(this.searchKeyword.toLowerCase()) &&
        user.status === 'active'
      )
    }
  }
}
</script>

Conditional List Items

vue
<template>
  <view>
    <view v-for="item in items" :key="item.id">
      <text v-if="item.type === 'text'">{{ item.content }}</text>
      <image v-else-if="item.type === 'image'" :src="item.src" />
      <video v-else-if="item.type === 'video'" :src="item.src" />
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, type: 'text', content: 'This is text content' },
        { id: 2, type: 'image', src: '/static/image.jpg' },
        { id: 3, type: 'video', src: '/static/video.mp4' }
      ]
    }
  }
}
</script>

Platform-Specific Conditional Rendering

Using Compilation Conditions

vue
<template>
  <view>
    <!-- #ifdef MP-WEIXIN -->
    <text>WeChat Mini Program specific content</text>
    <!-- #endif -->
    
    <!-- #ifdef H5 -->
    <text>H5 specific content</text>
    <!-- #endif -->
    
    <!-- #ifdef APP-PLUS -->
    <text>App specific content</text>
    <!-- #endif -->
  </view>
</template>

Runtime Platform Detection

vue
<template>
  <view>
    <text v-if="isWeixin">WeChat Mini Program</text>
    <text v-else-if="isH5">H5 Platform</text>
    <text v-else-if="isApp">App Platform</text>
  </view>
</template>

<script>
export default {
  computed: {
    isWeixin() {
      // #ifdef MP-WEIXIN
      return true
      // #endif
      // #ifndef MP-WEIXIN
      return false
      // #endif
    },
    isH5() {
      // #ifdef H5
      return true
      // #endif
      // #ifndef H5
      return false
      // #endif
    },
    isApp() {
      // #ifdef APP-PLUS
      return true
      // #endif
      // #ifndef APP-PLUS
      return false
      // #endif
    }
  }
}
</script>

Performance Optimization

Using Computed Properties

vue
<template>
  <view>
    <view v-for="item in visibleItems" :key="item.id">
      <text>{{ item.name }}</text>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      items: [],
      showOnlyActive: true
    }
  },
  computed: {
    visibleItems() {
      if (this.showOnlyActive) {
        return this.items.filter(item => item.active)
      }
      return this.items
    }
  }
}
</script>

Avoiding Unnecessary Re-renders

vue
<template>
  <view>
    <!-- Good: Use computed property -->
    <text v-if="isUserLoggedIn">Welcome, {{ userName }}</text>
    
    <!-- Avoid: Complex expressions in template -->
    <!-- <text v-if="user && user.isLogin && user.name">Welcome, {{ user.name }}</text> -->
  </view>
</template>

<script>
export default {
  data() {
    return {
      user: {
        isLogin: true,
        name: 'John'
      }
    }
  },
  computed: {
    isUserLoggedIn() {
      return this.user && this.user.isLogin && this.user.name
    },
    userName() {
      return this.user ? this.user.name : ''
    }
  }
}
</script>

Best Practices

1. Choose Appropriate Conditional Rendering Method

  • Use v-if for infrequent condition changes
  • Use v-show for frequent condition changes
  • Use computed properties for complex logic

2. Avoid Complex Expressions in Templates

vue
<!-- Good -->
<text v-if="shouldShowMessage">{{ message }}</text>

<!-- Avoid -->
<text v-if="user && user.permissions && user.permissions.includes('read') && !user.isBlocked">
  {{ message }}
</text>

3. Use Key Attributes Properly

vue
<template>
  <view>
    <input v-if="loginType === 'username'" key="username" placeholder="Username" />
    <input v-else key="email" placeholder="Email" />
  </view>
</template>

4. Consider Performance Impact

For large lists, use virtual scrolling or pagination instead of hiding elements with v-show.

5. Maintain Code Readability

Use meaningful variable names and extract complex logic into computed properties or methods.

Common Issues and Solutions

Issue 1: v-if and v-for Used Together

vue
<!-- Avoid -->
<view v-for="user in users" v-if="user.active" :key="user.id">
  {{ user.name }}
</view>

<!-- Solution: Use computed property -->
<view v-for="user in activeUsers" :key="user.id">
  {{ user.name }}
</view>

Issue 2: Conditional Rendering Causing Layout Issues

vue
<template>
  <view class="container">
    <!-- Use v-show to maintain layout -->
    <view v-show="showSidebar" class="sidebar">Sidebar</view>
    <view class="content">Main content</view>
  </view>
</template>

<style>
.container {
  display: flex;
}
.sidebar {
  width: 200px;
}
.content {
  flex: 1;
}
</style>

Issue 3: State Not Updating After Condition Change

Ensure reactive data is properly defined and modified:

vue
<script>
export default {
  data() {
    return {
      // Ensure all properties are defined in data
      showModal: false,
      user: {
        isLogin: false
      }
    }
  },
  methods: {
    login() {
      // Use Vue.set for nested properties if needed
      this.$set(this.user, 'isLogin', true)
      // Or use reactive assignment
      this.user = { ...this.user, isLogin: true }
    }
  }
}
</script>

Summary

Conditional rendering is a powerful feature in uni-app that allows you to create dynamic and interactive user interfaces. By understanding the differences between various conditional rendering methods and following best practices, you can build efficient and maintainable applications. Remember to consider performance implications and choose the most appropriate method for your specific use case.

一次开发,多端部署 - 让跨平台开发更简单