VueJS Storyblok

by delooks

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
<script src="https://app.storyblok.com/f/storyblok-latest.js"></script>
<script src="https://unpkg.com/storyblok-vue@1.0.3/storyblok-vue.js"></script>
<div id="app">

</div>

CSS

body {
  font-family: sans-serif;
}

.teaser,
.column {
  font-size: 2rem;
  text-align: center;
  line-height: 3;
  background: #ebeff2;
  border-radius: 10px;
  margin: 10px 5px;
}

.grid {
  display: flex;
}

.column {
  flex: 1;
}

JavaScript

Vue.component('page', {
  template: `<div><component :key="blok._uid" v-for="blok in blok.body" :blok="blok" :is="blok.component"></component></div>`,
  props: ['blok']
})

Vue.component('teaser', {
  template: `<div v-editable="blok" class="teaser">{{ blok.headline }}</div>`,
  props: ['blok']
})

Vue.component('grid', {
  template: `<div v-editable="blok" class="grid"><component :key="blok._uid" v-for="blok in blok.columns" :blok="blok" :is="blok.component"></component></div>`,
  props: ['blok']
})

Vue.component('feature', {
  template: `<div v-editable="blok" class="column feature">{{ blok.name }}</div>`,
  props: ['blok']
})

new Vue({
  el: '#app',
  template: `<div><component :blok="story.content" :is="story.content.component"></component></div>`,
  data() {
    return {
      story: {
        content: {
          body: []
        }
      }
    }
  },
  created: function() {
    this.$storyblok.init({
      accessToken: 'xfloBjvf2Kbl8led8LI7Nwtt'
    })

    this.$storyblok.on('change', () => { this.loadStory('draft') })
    this.$storyblok.on('published', () => { this.loadStory('draft') })
    this.loadStory('draft')
  },
  methods: {
    loadStory(version) {
      this.$storyblok.get({
        slug: 'home',
        version: version
      }, (data) => {
        this.story = {
          content: {
            body: []
          }
        }
        this.$nextTick(() => {
          this.story = data.story
        })
      })
    }
  }
})