JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuex-persistedstate.min.js"></script>
<div id="app">
  <router-view></router-view>
</div>

CSS

* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

a {
  display: block;
  text-decoration: none;
  font-size: 20px;
  color: #fff;
  background: purple;
  margin-bottom: 5px;
  padding: 10px;
}

input,
textarea {
  display: block;
  width: 100%;
  padding: 10px;
}

textarea {
  height: 200px;
}

.columns {
  display: flex;
}

.column {
  flex: 1 0 50%;
  width: 50%;
  padding: 10px;
  word-break: break-word;
}

.page h1 {
  font-family: tahoma;
}

.page > div {
  background: #eee;
  padding: 40px 10px;
  margin-bottom: 20px;
  white-space: pre-wrap;
}

Babel + JSX

axios.defaults.baseURL = 'https://jsonplaceholder.typicode.com'

BackendAPI = {
	getPages() {
  	return axios.get('/posts')
    	.then(resp => resp.data)
  },
  getPage(id) {
  	return axios.get('/posts/' + id)
    	.then(resp => resp.data)
  },
  putPage(post) {
  	return axios.put('/posts/' + post.id, post)
    	.then(resp => resp.data)
  }
}

const Home = {
	template: `
  	<div>
    	<h1> pages </h1>
    	<router-link v-for="page in pages" :to="{name: 'page', params: {id: page.id}}" :key="page.id">
    		{{ page.title }}
    	</router-link>
    </div>
  `,
	data() {
  	return {
    	pages: []
    }
  },
	created() {
  	BackendAPI.getPages().then(pages => (this.pages = pages))
  }
}

const PageForm = {
	template: `
  	<form @submit.prevent="savePage">
    <p>
      <label for="title">title</label>
      <input id="title" type="text" v-model="title">
    </p>
    <p>
      <label for="content">content</label>
      <textarea id="content" v-model="body"></textarea>
    </p>
    <p>
      <button type="submit">send</button>
    </p>
  </form>
  `,
  computed: {
    title: {
      set(title) {
        this.$store.commit('SET_PAGE', { title })
      },
      get() {
        return this.$store.state.page.title
      }
    },
    body: {
      set(body) {
        this.$store.commit('SET_PAGE', { body })
      },
      get() {
        return this.$store.state.page.body
      }
    }
  },
  methods: {
    savePage() {
      this.$store.dispatch('PUT_PAGE')
        .then(() => this.$emit('saved'))
    }
  }
}

const Page = {
	template: `
  	<div class="columns">
      <section class="page column">
        <h1>{{ page.title }}</h1>

        <div>{{ page.body }}</div>

        <button @click="is_editing = true">EDIT</button>
      </section>

      <page-form v-if="is_editing" @saved="is_editing = false" class="column" />
    </div>
  `,
  components: {
    PageForm
  },
  data() {
    return { is_editing: false }
  },
  computed: Vuex.mapState(['page']),
  created() {
   ...