JSFiddle - React, Tailwind, and code Playground

by kurotanshi

HTML

<script src="https://unpkg.com/vue@next"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<div id="app">
  <h3 class="title">Todo App</h3>  
  <todo-list></todo-list>    
  <todo-list></todo-list>
</div>

CSS

#app {
  display: block;
  overflow: hidden;
  width: 680px;
  margin-left: 1rem;
  margin-bottom: 1rem;
}

.todo-list {
  display: block;
  float: left;
  width: 220px;
  margin-right: 50px;
}

.title {
  margin-top: 1em;
  font-size: 2em;
}
.container {
  margin-top: 3em;
  display: flex;
  justify-content: center;
}
.comp + .comp {
  margin-left: 2em;
}
.comp p {
  font-weight: 900;
  font-size: 1.2em;
}

JavaScript

const {
  ref,
  onMounted,
  createApp
} = Vue;

const toDo = title => {
  const todo = ref('');
  const items = ref(['Vue', 'is', 'Awesome']);

  // Add: Click Handler Function
  const add = () => {
    if (todo.value) {
      items.value.push(todo.value);
      todo.value = '';
    }
  };

  // Remove: Click Handler Function
  const remove = item => {
    items.value = items.value.filter(v => v !== item);
  };

  // mounted hook
  onMounted(() => {
    console.log(`onMounted ! ${ title } `);
  });

  return {
    todo,
    items,
    add,
    remove
  };
};

const app = createApp({});

app.component('todo-list', {
  props: {
    title: String
  },
  setup(props, context) {
    const todo = toDo(props.title);
    return todo;
  },
  template: `<div class="todo-list">
    <p>{{ title }}</p>
    <div class="form-group d-flex">
      <input v-model="todo" @keyup.enter="add" type="text" class="form-control shadow-none rounded-0">
      <button class="btn btn-primary shadow-none border-0 rounded-0" @click="add">Add</button>
    </div>
    <div class="list-group">
      <div class="list-group-item d-flex justify-content-between align-items-center"
          v-for="item in items"
          :key="item">
        <span>{{ item }}</span>
        <button class="close shadow-none border-0" @click="remove(item)">
          <span>&times;</span>
        </button>
      </div>
    </div>
  </div>`,
});

app.mount('#app');