Help us understand the problem. What is going on with this article?

Alpine.jsでTODO

概要

遅ればせながらAlpine.jsというものの存在を知ったので触りがてらTODOサンプルアプリを作ってみました。

完成

Screen Shot 2020-10-21 at 20.21.29.png

コード

index.html
<body>
    <main class="w-10/12 m-auto text-gray-700">
        <h1 class="p-1 font-bold">Alpine.js TODO</h1>
        <div class="todo-list" x-data="{ 
                todoList: [],
                newTodo: ''
            }" x-init="getToDo()
                    .then(response => response.json())
                    .then(list => todoList = list)">
            <ul>
                <template x-for="todo in todoList" :key="todo.id">
                    <li
                        class="w-auto flex text-center text-gray-700 bg-gray-200 hover:bg-gray-300 p-4 outline-none hover:shadow-outline mt-1">
                        <div class="w-1/2 flex-1 break-words" x-text="todo.title"></div>
                        <div class="w-20 flex-1">
                            <label>Done</label>
                            <input type="checkbox" class="form-checkbox bg-teal-500 mt-1" :checked="todo.done">
                        </div>
                        <div class="w-20 flex-1">
                            <button
                                class="h-8 bg-pink-300 hover:bg-pink-600 focus:outline-none focus:shadow-outline rounded pr-1 pl-1 pb-1"
                                @click="todoList = todoList.filter(t => t.id !== todo.id)">remove</button>
                        </div>
                    </li>
                </template>
            </ul>
            <div class="add-todo flex justify-end mt-1">
                <input type="text" placeholder="write a thing to do" x-model="newTodo"
                    class="bg-gray-200 hover:bg-gray-300 hover:border-gray-300 outline-none hover:shadow-outline rounded-lg mr-1 pl-2" />
                <button class="bg-teal-500 hover:bg-teal-600 focus:outline-none focus:shadow-outline rounded p-1"
                    @click="if (!newTodo) return;
                                todoList.push({
                                    id: Math.max.apply(null, todoList.map(t => t.id)) + 1,
                                    title: newTodo,
                                    done: false    
                                });
                                newTodo = '';
                            ">Add</button>
            </div>
        </div>
    </main>
</body>

Vue.jsと似てるのでそれほど苦もなく使えそうです。
難点はHTML直書きなのでロジックが追い辛い点ですかね。

ポイントとしては
・ 外出しした関数などはGlobalに置く
・ x-dataのネストには未対応
という点だと思いました。

サンプルコードをあげているのでよかったらどうぞ。link

参考

Alpine.js
Alpine.js - nested components

nannou
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away