1
\$\begingroup\$

It's an exercise from a Vue.js course I'm enrolled into. The aim is to get comfortable with the Vue.js features Slots and Dynamic components. By clicking on the buttons one shall be able to change the currently selected and rendered component.

With green button clicked:

Screenshot of the App 1

With the red button clicked:

enter image description here

The four main files with the styling where provided by the instructor. I had to write the JavaScript code.

// -- App.vue ------------------------------------------------------------
<template>
    <div class="container">
        <div class="row">
            <div class="col-xs-12">
                <h2>Currently active component: {{ selected }}</h2>
                <br>
                <button class="btn btn-primary" @click="onClick($event, 'blue')">Load Blue Template</button>
                <button class="btn btn-success" @click="onClick($event, 'green')">Load Green Template</button>
                <button class="btn btn-danger" @click="onClick($event, 'red')">Load Red Template</button>
                <hr>
                <component :is="selected">
                    <h1 slot="blue-headline">Nicht von im verschwand so deiner und weiter. Liebe sonder.</h1>
                    <p slot="blue-text">Youth weary his high he might, heart a his ever his</p>

                    <h3 slot="green-headline">Bonan viroj por dum la kun la al mangxu hispanujo</h3>
                    <p slot="green-text">Tempor sed kasd et rebum dolor ipsum vero ipsum invidunt. Erat est sed dolores gubergren.</p>

                    <h2 slot="red-headline">Intendo cose vita con</h2>
                    <p slot="red-text">Bist ich dahinten zurück du der der deiner liebe.</p>
                </component>
            </div>
        </div>
    </div>
</template>

<script>
    import Blue from './components/Blue.vue';
    import Green from './components/Green.vue';
    import Red from './components/Red.vue';

    export default {
        components: {
            appBlue: Blue,
            appGreen: Green,
            appRed: Red
        },
        data: function() {
            return {
                selected: "appBlue"
            }
        },
        methods: {
            onClick: function(event, selection) {
                switch (selection) {
                    case "blue":
                        this.selected = "appBlue";
                        break;
                    case "green":
                        this.selected = "appGreen";
                        break;
                    case "red":
                        this.selected = "appRed";
                        break;
                    default:
                        this.selected = "appBlue";
                }
            }
        }
    }
</script>

<style>
</style>

// -- Blue.vue -----------------------------------------------------------
<template>
    <div>
        <slot name="blue-headline"></slot>
        <slot name="blue-text"></slot>
    </div>
</template>

<script>

</script>

<style scoped>
    div {
        border: 1px solid blue;
        background-color: lightblue;
        padding: 30px;
        margin: 20px auto;
        text-align: center
    }
</style>

// -- Green.vue ----------------------------------------------------------
<template>
    <div>
        <slot name="green-headline"></slot>
        <slot name="green-text"></slot>
    </div>
</template>

<script>

</script>

<style scoped>
    div {
        border: 1px solid green;
        background-color: lightgreen;
        padding: 30px;
        margin: 20px auto;
        text-align: center
    }
</style>

// -- Red.vue ------------------------------------------------------------
<template>
    <div>
        <slot name="red-headline"></slot>
        <slot name="red-text"></slot>
    </div>
</template>

<script>

</script>

<style scoped>
    div {
        border: 1px solid red;
        background-color: lightcoral;
        padding: 30px;
        margin: 20px auto;
        text-align: center
    }
</style>

Full project-directory here on GitHub.

What do you think about my solution? What would you have done differently and why?

\$\endgroup\$
3
\$\begingroup\$

Your code is overall very neat and clean and easily readable, I think you're ready for the next level!


This switch maps from one string to another:

switch (selection) {
    case "blue":
        this.selected = "appBlue";
        break;
    case "green":
        this.selected = "appGreen";
        break;
    case "red":
        this.selected = "appRed";
        break;
    default:
        this.selected = "appBlue";
}

This could either be changed into using a lookup dictionary:

let mappedComponents = { red: "appRed", blue: "appBlue", green: "appGreen" };
this.selected = mappedComponents[selection];

Or you could just skip that remapping and change the names of the components so that they directly match the selection value:

components: {
    blue: Blue,
    green: Green,
    red: Red
},

this.selected = selection;

Other notes that might not have been in your control for the assignment:

  • The CSS is duplicated. You could extract padding, margin and text-align to a separate CSS class.
  • I would recommend having just one component for all three different colors and use a property to inject its colors.
\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.