JSFiddle - React, Tailwind, and code Playground

by kasheftin

HTML

<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<div id="app">
  <div 
    v-for="item in items" 
    :key="item.id" 
    :class="{'item--selected': item.isSelected}" 
    class="item" 
    @click="selectItem(item)"
  >
    {{ item.name }}
  </div>
  <button @click="shuffle">
    Shuffle items
  </button>
</div>

CSS

body {
  background: #222;
  padding: 20px;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
}

.item {
  cursor: pointer;
  padding: 5px 0;
}
.item--selected {
  font-weight: bold;
  text-decoration: underline;
}

JavaScript

const store = new Vuex.Store({
  state: {
    items: [
    	{id: 1, name: 'First'}, 
      {id: 2, name: 'Second'}, 
      {id: 3, name: 'Third'}, 
      {id: 4, name: 'Fourth'}
    ],
    selectedItemId: 1
  },
  mutations: {
    selectItem (state, item) {
      state.selectedItemId = item.id
    },
    shuffle (state) {
    	const items = [...state.items]
			let j, x, i
    	for (i = items.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1))
        x = items[i]
        items[i] = items[j]
        items[j] = x
      }
      state.items = items
    }
  },
  getters: {
    items (state) {
      return state.items.map(item => ({
        ...item,
        isSelected: item.id === state.selectedItemId
      }))
    }
  }
});

new Vue({
  el: "#app",
  store,
  computed: {
    items () { return this.$store.getters.items },
    itemIds () { return this.items.map(item => item.id) }
  },
  watch: {
    items: {
      deep: true,
      handler (items) {
        console.log('Items watcher run', items)
      }
    },
    itemIds: {
      deep: true,
      handler (itemIds) {
        console.log('ItemsIds watcher run', itemIds)
      }
    }
  },
  methods: {
    selectItem (item) {
      this.$store.commit('selectItem', item)
    },
    shuffle () {
      this.$store.commit('shuffle')
    }
  }
})