Vue

by khamer

HTML

<main>
    <div class="board">
        <tile v-for="(tile, c) in tiles" :key="c"
              :lit="!!tile"
              @click="clickOn(c)"
              ></tile>
    </div>
    <p>
        Lights left: {{ lightsLeft }}
    </p>
    <p v-if="lightsLeft == 0">
        Congratulations, you've won!!
    </p>
</main>

SCSS

.board {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    height: 50vh;
    
    .tile {
        box-shadow: 0 0 0 1px inset;
        
        &.lit {
            background: blue;
        }
    }
}

Vue

Vue.component('tile', {
    template: `<div class="tile" @click="click" :class="{lit}"></div>`,
    props: ['lit'],
    methods: {
        click() {
            this.$emit('click');
        }
    }
});

new Vue({
    el: "main",
    data: {
        tiles: Array(25).fill(false),
    },

    created() {
        this.tiles[2] = true;
    },
    
    computed: {
    	lightsLeft() {
        	return this.tiles.filter(t => t).length;
        },
    },

    methods: {
        clickOn(i) {
            this.toggle(i);
            this.toggle(i+5);
            this.toggle(i-5);
            if (i % 5 > 0) {
            	this.toggle(i-1);
            }
            if (i % 5 < 4) {
            	this.toggle(i+1);
            }
        },
        toggle(i) {
        	if (i in this.tiles) {
            	Vue.set(this.tiles, i, !this.tiles[i]);	
            }
        },
    }
});