<div id="app" :style="background">
  <div class="center column">
  <color-input v-for="(color,index) in colors" :colorp="color" :key="index" v-on:new-color="updateColors"></color-input>
    <button @click="randomColors">random</button>
  </div>
</div>
@import url('https://fonts.googleapis.com/css?family=Roboto:400,700');

body{
  height:100vh;
  width:100vw;
}

#app{
  height:100%;
  display:flex;
}

.center {
  display:flex;
  justify-content:center;
  align-items:center;
  width:400px;
  margin:auto;
  padding: 25px 0px;
}

.column{
  flex-direction: column
}

input{
  display: block;
    width: 100%;
    font-family: "Roboto", sans-serif;
  font-weight: 700;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    color: inherit;
    background-color: transparent;
    -webkit-appearance: none;
    appearance: none;
    outline: none;
  font-size: 4.5rem;
  text-align:center;
  color:#ffffff
}

button{
  font-family: "Roboto", sans-serif;
  font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    padding: 8px;
    border-radius: 3px;
    border: 0px;
  background: #000000;
  color:#ffffff;
  text-transform: uppercase;
  cursor:pointer;
  margin-top:8px;
}

button:focus{
  outline:none;
}
API('PyzBqo')

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

Vue.component("color-input", {
  props: ["colorp"],
  template:
    '<div><input type="text" v-model="color"></div>',
  data() {
    return {
      color: this.colorp,
      tweenedColor: this.colorp,
      randomColor:''
    };
  },
  methods: {
    changeColor() {
      this.color = this.randomColor = randomHex()
      
    }
  },
  watch: {
    color() {
      TweenLite.to(this.$data, 1, { tweenedColor: this.color });
    },
    animatedColor() {
      this.$emit('new-color',{index : this.$vnode.key,color: this.animatedColor})
    }
  },
  computed: {
    animatedColor() {
      return this.tweenedColor;
    },

    backgroundStyle() {
      return {
        background: this.animatedColor
      };
    }
  },
  created() {
  }
});

function randomHex() {
  return (
    "#" +
    (
      "000000" +
      Math.random()
        .toString(16)
        .slice(2, 8)
        .toUpperCase()
    ).slice(-6)
  );
}

new Vue({
  el: "#app",
  data: {
      color: "",
      tweenedColor: "",
      colors: Array ,
      animatedColors: Array
  },
  created() {
    let colors = ['#009FFF', '#EC2F4B']
    this.colors = this.animatedColors = colors
  },
  methods: {
    updateColors(e) {
      this.animatedColors.splice(e.index,1 , e.color)
    },
    randomColors() {
      this.$children.forEach((color) => {
        color.changeColor()
      })
    }
  },
  computed: {
    gradient() {
      return JSON.stringify(this.animatedColors).replaceAll('"','').replace('[','').replace(']','')
    },
    background() {
      return {
        background: 'linear-gradient(45deg,' + this.gradient + ')'
      }
    }
  }
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js
  4. https://codepen.io/ClementRoche/pen/OrGaMg.js