Dynamic Layouts with Vue jsx: A Guide to Flexible and Maintainable UIs

For complex and data-driven UIs in Vue, JSX offers a powerful alternative to templates by embedding markup directly within JavaScript logic. Using JSX for dynamic layouts allows for more programmatic control over your UI, leading to flexible and maintainable components that adapt to changing data and user interactions. If you're looking to build scalable and highly interactive applications, hiring Vue.js developers with expertise in JSX can help you achieve optimal results.



Why use JSX for dynamic layouts?

  • Enhanced programmatic control: Embed if/else statements, ternary operators, and loops directly within your UI structure, eliminating the need for Vue directives like v-if and v-for.

  • Logical readability: For developers familiar with React, or those who prefer logic and markup together, JSX offers a cohesive block of code that is often easier to parse.

  • Maintainable code: Define your UI based on data and conditions, so changes to your data automatically update the layout, reducing manual and repetitive HTML edits.

  • Seamless integration: You don't have to choose between JSX and templates. Use JSX only where it adds the most value, like for complex dynamic components, and stick to standard templates for simpler cases. 

How to set up and use JSX in a Vue project

First, you need to ensure your build process can handle JSX. Both create-vue (using Vite) and Vue CLI offer project scaffolding options with pre-configured JSX support. 

Vite setup for JSX/TSX

If you are using Vite, JSX support is built-in. For TypeScript (TSX), ensure your tsconfig.json has the correct settings: 

json

{

  "compilerOptions": {

    "jsx": "preserve",

    "jsxImportSource": "vue"

  }

}

Writing a component with JSX

In your component file (e.g., DynamicLayout.jsx or DynamicLayout.tsx), use the setup function to declare reactive state and return a render function that uses JSX: 

javascript

// DynamicLayout.jsx

import { ref } from 'vue';


export default {

  setup() {

    const isEditing = ref(false);


    return () => (

      <div>

        <h2>A Dynamic Layout with JSX</h2>

        <button onClick={() => isEditing.value = !isEditing.value}>

          { isEditing.value ? 'Cancel Edit' : 'Edit Profile' }

        </button>

        {isEditing.value ? (

          <div class="edit-form">

            <input type="text" placeholder="Name" />

          </div>

        ) : (

          <div class="profile-details">

            <p>User details displayed here.</p>

          </div>

        )}

      </div>

    );

  }

};

Implementing key dynamic layout patterns

Conditional rendering

Using a simple ternary operator inside your JSX is the most straightforward way to conditionally render elements, similar to the example above. 

List rendering with .map()

To render a list of items, you can use the JavaScript .map() method on an array. This is the JSX equivalent of Vue's v-for directive. 

javascript

// DashboardWidget.jsx

import { ref } from 'vue';


export default {

  setup() {

    const widgets = ref([

      { id: 1, title: 'Profile', component: 'ProfileCard' },

      { id: 2, title: 'Stats', component: 'StatsPanel' },

      { id: 3, title: 'Recent Activity', component: 'ActivityFeed' },

    ]);


    const components = {

      ProfileCard: () => <div>Profile Card Content</div>,

      StatsPanel: () => <div>Stats Panel Content</div>,

      ActivityFeed: () => <div>Activity Feed Content</div>,

    };


    return () => (

      <div class="dashboard">

        {widgets.value.map(widget => {

          const Comp = components[widget.component];

          return <Comp key={widget.id} title={widget.title} />;

        })}

      </div>

    );

  }

};

Dynamic components with <component :is="...">

The <component> tag with the is prop is a powerful Vue feature that lets you swap out components at runtime. You can use this within your JSX to render a different component based on a variable. 

Note: For more complex dynamic components, you may find the standard template approach with <component :is="..."/> more idiomatic, especially when passing children via slots. 

javascript

// App.vue (can mix template with JSX)

<template>

  <div class="app">

    <button @click="currentView = 'list'">List View</button>

    <button @click="currentView = 'grid'">Grid View</button>

    <component :is="currentView === 'list' ? ListView : GridView" />

  </div>

</template>


<script setup>

import { ref } from 'vue';

import ListView from './ListView.jsx';

import GridView from './GridView.jsx';


const currentView = ref('list');

</script>

Creating reusable layout components

Just like with templates, you can use JSX to build reusable components that accept props and slots. A common pattern is creating a "wrapper" layout component that receives content through a default slot. 

javascript

// BaseLayout.jsx

export default {

  props: {

    title: String,

  },

  setup(props, { slots }) {

    return () => (

      <div class="base-layout">

        <header>

          <h1>{props.title}</h1>

        </header>

        <main>{slots.default && slots.default()}</main>

      </div>

    );

  }

};

Using the reusable layout

You can then use this BaseLayout component in any other component, passing in the desired content for the slot as children. 

javascript

// UserProfile.jsx

import BaseLayout from './BaseLayout.jsx';


export default {

  setup() {

    return () => (

      <BaseLayout title="User Profile">

        <div class="user-details">

          <p>This is the profile content.</p>

        </div>

      </BaseLayout>

    );

  }

};

Conclusion

Vue JSX enables the creation of dynamic, flexible, and maintainable UIs with cleaner, more scalable code. It simplifies complex layouts while providing greater control over rendering logic. For state management, both Vuex and Pinia offer robust solutions, with Vuex being a tried-and-true option for larger projects and Pinia excelling in simplicity and modern features for new or smaller projects. By combining JSX with the right state management tool, you can build efficient, future-proof applications with ease.

Comments

Popular posts from this blog

5 Ways an ERP System Can Streamline Your Business Operations

Next.js vs Gatsby: Which Framework Should You Use?

User Centered Design: Principles, Processes, And Examples