JSFiddle - React, Tailwind, and code Playground

by arzo

HTML

<!--add new item template-->
<template id="add-item-template">
  <div class="input-group">
    <input
      v-model="newItem"
      placeholder="add shopping list item"
      type="text"
      class="form-control"
    />
    <span class="input-group-btn">
      <button class="btn btn-default" type="button">Add!</button>
    </span>
  </div>
</template>

<!--list item template-->
<template id="item-template">
  <li :class="{ 'removed': item.checked }">
    <input v-model="item.checked" type="checkbox" />
    <span>{{ item.text }}</span>
  </li>
</template>

<!--items list template-->
<template id="items-template">
<!-- <div></div> -->
  <item-component v-for="item in items" :item="item"></item-component>


</template>

<!--change title template-->
<template id="change-title-template">
  <em>Change the title of your shopping list here</em>
  <input v-model="title" />
</template>

<!--main container markup-->
<html>
  <head>
    <link rel="stylesheet" href="index.css" />
  </head>
  <body>
    <div id="app" class="container">
      <h2>{{ title }}</h2>
      <add-item-component :items="items"></add-item-component>
      <items-component :items="items"></items-component>
      <div class="footer">
        <hr />
        <change-title-component :title="title"></change-title-component>
      </div>
    </div>
  </body>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
  <script src="script.js"></script>
</html>

CSS

.container {
  width: 40%;
  margin: 20px auto 0px auto;
}

.removed {
  color: gray;
}

.removed span {
  text-decoration: line-through;
}

ul li {
  list-style-type: none;
}

ul li span {
  margin-left: 5px;
}

.footer {
  font-size: 0.7em;
  margin-top: 40vh;
}

JavaScript

var data = {
    items: [{ text: "Bananas", checked: true }, { text: "Apples", checked: false }],
    title: "My Shopping List",
    newItem: ""
};
//add item compoennt
Vue.component("add-item-component", {
    template: "#add-item-template",
    props: ["items", "newItem"]
});
//item component
Vue.component("item-component", {
    template: "#item-template",
    props: ["item"]
});
//items component
Vue.component("items-component", {
    template: "#items-template",
    props: ["items"]
});
//change title component
Vue.component("change-title-component", {
    template: "#change-title-template",
    props: ["title"]
});

new Vue({
    el: "#app",
    data: data,
    methods: {
        addItem: function () {
            var text;

            text = this.newItem.trim();
            if (text) {
                this.items.push({
                    text: text,
                    checked: false
                });
                this.newItem = "";
            }
        }
    }
});