JSFiddle - React, Tailwind, and code Playground

by skirtle

HTML

<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
  <button @click="onClick('a')">
    a
  </button>
  <button @click="onClick('b')">
    b
  </button>
<item-view></item-view>
</div>

JavaScript

const store = {
  state: Vue.observable({
  	items: {
      a: { url: 'http://c', title: 'AAA', time: 123, kids: [45, 12], descendants: 5, score: 67, by: 'Liz' },
      b: { url: 'http://d', title: 'BBB', time: 456, kids: [11, 16], descendants: 6, score: 12, by: 'Pat' }
    }
  })
}

const route = {
  params: Vue.observable({
    id: 'a'
  })
}

const ItemView = {
  template: `
  <div class="item-view" v-if="item">
    <template v-if="item">
      <div class="item-view-header">
        <a :href="item.url" target="_blank">
          <h1>{{ item.title }}</h1>
        </a>
        <span v-if="item.url" class="host">
          ({{ item.url | host }})
        </span>
        <p class="meta">
          {{ item.score }} points
          | by <router-link :to="'/user/' + item.by">{{ item.by }}</router-link>
          {{ item.time | timeAgo }} ago
        </p>
      </div>
      <div class="item-view-comments">
        <p class="item-view-comments-header">
          {{ item.kids ? item.descendants + ' comments' : 'No comments yet.' }}
          <spinner :show="loading"></spinner>
        </p>
        <ul v-if="!loading" class="comment-children">
          <comment v-for="id in item.kids" :key="id" :id="id"></comment>
        </ul>
      </div>
    </template>
  </div>
  `,
  
  name: 'item-view',

  components: {
    RouterLink: {
      template: '<div><slot/></div>'
    },
    Spinner: {
      props: ['show'],
      template: '<div v-if="show">I am a spinner!!!</div>'
    },
    Comment: {
      props: ['id'],
      template: `<div>Comment {{ id }}</div>`
    }
  },

  data: () => ({
    loading: true
  }),

  computed: {
    item () {
      console.log('evaluating: ' + route.params.id)
      return store.state.items[route.params.id]
    }
  },

  title () {
    return this.item.title
  },

  // Fetch comments when mounted on the client
  beforeMount () {
    this.fetchComments()
  },

  // refetch comments if item changed
  watch: {
    item: 'fetchComments'
 ...