JSFiddle - React, Tailwind, and code Playground

by shubhampokhriyal

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div id="app">
  <demo></demo>
</div>

JavaScript

var BaseFieldMixin = {
        data: function () {
            return {
                beforeEditCache: '',
                value: null,
                isEditing: false,
            }
        },
        props:{
            propName: {
                type: [String,Number],
                required: true,
            },
            isEditable: {
                type: Boolean,
                default: true,
            }
        },
        methods: {
            doneEdit(){
                this.isEditing = false
                if(this.value === this.beforeEditCache) {
                    return
                }
                this.$emit('update',{propName:this.propName,value:this.value})
            },
            edit(){
                if (this.isEditable) {
                    this.isEditing = true
                    this.beforeEditCache = this.value
                }
            },
            cancelEdit(){
                this.value = this.beforeEditCache
                this.isEditing = false
            },
        }
    }
    
Vue.component('FieldText',{ 
  mixins:[BaseFieldMixin],
  template: `<div @dblclick="edit()">
            <input v-if="isEditing"
                   class="edit"
                   type="text"
                   v-model="value"
                   @blur="doneEdit()"
                   @keyup.enter="doneEdit()"
                   @keyup.esc="cancelEdit()"
            >
            <div v-else class="view">
                {{value}}
            </div>
        </div>`,
        data: function () {
            return {
                value: this.content
            }
        },
        props: {
            content: {
                type: String,
                required: true,
            },
        }
})

Vue.component('FieldArray',{ 
  mixins:[BaseFieldMixin],
  template: `
  <div class="view">
        <ul class="list-group">
            <li class="list-group-item" v-for="(item,i) in value">
                <FieldText
              ...