> For the complete documentation index, see [llms.txt](https://docs.elentra.org/ejs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.elentra.org/ejs/elentra-js-2.0/class-based-components.md).

# Class-Based Components

Alongside the switch to [TypeScript](/ejs/elentra-js-2.0/typescript.md), the components that make up the [**Component Library**](/ejs/design-system/component-library.md) have each been rewritten as class-based components. Interacting with these components in Vue.js template code is the same as before, and passing props and handling events will work the same way, however the script definitions for components are now written as classes with decorators.&#x20;

This is made possible due to a library called [`vue-property-decorator`](https://github.com/kaorun343/vue-property-decorator), which itself makes use of another popular library called [`vue-class-component`](https://github.com/vuejs/vue-class-component). This switch to a class structure for our components comes with all the obvious benefits that come with object-oriented design, and will result in enhanced readability and better organization of our Vue.js component code.

A brief example of a class-based component using decorators may be found below.

{% code title="ExampleComponent.vue" %}

```typescript
<template>
    <EjsButton type="info" @click="toggleMessageVisibility()">
        {{ buttonLabel }}
    </EjsButton>
    <div v-if="messageVisible" class="message">
        {{ message }}
    </div>
</template>
<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator'

import {
    EjsButton,
} from '@/components';

@Component({
    components: {
        EjsButton,
    }
})
export default class ExampleComponent extends Vue {

    /* --------------- Data --------------- */
    private messageVisible!: boolean = false;
    private target!: string = 'World';

    /* --------------- Props --------------- */
    @Prop()
    private greeting: string = 'Hello';

    /* --------------- Computed --------------- */
    get buttonLabel() {
        return this.messageVisible
        ? 'Hide Message' 
        : 'Show Message';
    }
        
    get message() {
        return `${this.greeting}, ${this.target}`;
    }
    
    /* --------------- Methods --------------- */    
    private toggleMessageVisibility(visibleState?: boolean) {
        visibleState === undefined
        ? this.messageVisible = !this.messageVisible        // Toggle
        : this.messageVisible = visibleState;               // Set To Arg
    }
}
</script>
```

{% endcode %}
