Svelte-ToodoListの作成

32151 ワード

プロジェクトの設定


まずプロジェクトを設定します.
npx degit sveltejs/template todo
cd todo
yarn install
次にsvelteでscssを設定します.
yarn add -D svelte-preprocess node-sass
rollup.config.jsで次の変更を行います.
...
plugins: [
		svelte({
			preprocess: sveltePreprocess(),
			compilerOptions: {
				// enable run-time checks when not in production
				dev: !production
			}
		}),
...

store


svelteは、ステータス管理ライブラリを個別にサポートするのではなく、その内部に含まれます.
storeによるスケジュール管理
src/todo.js
import { writable } from "svelte/store";

const createTodo = () => {
    const { subscribe, set, update } = writable([]);

    return {
        subscribe,
        insert: (item) => update(n => [...n, item]),
        delete: (idx) => update(n => n.filter((todo, index) => index !== idx)),
        reset: () => set([])
    }
}

export const todos = createTodo()
まずスケジュールはリストで管理しましょう
内部にスケジュールのinsertを追加し、スケジュールインデックスのdeleteと初期化スケジュールのresetを検索して削除します.

Component


3つのコンポーネントを実装します.
TodoInsert 、
  • スケジュール受信
    TodoItem
  • スケジュールを表示
  • スケジュールを表示するTodoList
  • TodoInsert


    TooInsertを作成する前に、svelte material-insをインストールします.
    yarn add svelte-material-icons
    まずscriptセクションを作成します.
    <script>
        import CalendarPlus from 'svelte-material-icons/CalendarPlus.svelte'
        import { todos } from '../store/todo'
    
        let todo = ''
        function onChange(e) {
            todo = e.target.value
        }
    
        function onSubmit() {
            todos.insert(todo)
            todo = ''
        }
    
    </script>
    まず、ユーザの入力をtodo変数に保存し、コミット時にtodo配列を更新してtodo変数を初期化します.
    component/TodoInsert.svelte
    <script>
        import CalendarPlus from 'svelte-material-icons/CalendarPlus.svelte'
        import { todos } from '../store/todo'
    
        let todo = ''
        function onChange(e) {
            todo = e.target.value
        }
    
        function onSubmit() {
            todos.insert(todo)
            todo = ''
        }
    
    </script>
    
    <form class="TodoInsert" on:submit|preventDefault={onSubmit}>
        <input placeholder="TODO" on:input={onChange} bind:value={todo}/>
        <button>
            <CalendarPlus/>
        </button>
    </form>
    
    <style lang="scss">
        .TodoInsert {
          display: flex;
          background: #495057;
    
          input {
            background: none;
            outline: none;
            border: none;
            padding: 0.5rem;
            font-size: 1.125rem;
            line-height: 1.5;
            color: white;
    
            &::placeholder {
              color: #dee2e6;
            }
    
            flex: 1;
          }
    
          button {
            background: none;
            outline: none;
            border: none;
            background: #868e96;
            color: white;
            padding-left: 1rem;
            padding-right: 1rem;
            font-size: 1.5rem;
            display: flex;
            align-items: center;
            cursor: pointer;
            transition: 0.1s background ease-in;
    
            &:hover {
              background: #adb5bd;
            }
          }
        }
    </style>

    TodoItem


    スケジュールを表示するTodoItemでは、スケジュールを表示したり削除したりするにはtodoとindexが必要です.ユーザーがアイテムを削除する場合は、todos配列からインデックス内のアイテムを削除する必要があります.
    component/TodoItem.svelte
    <script>
        import {todos} from "../store/todo";
    
        export let text
        export let index
    
        function onRemove() {
            todos.delete(index)
        }
    </script>
    
    <div class="TodoItem-virtualized">
        <div class="TodoItem">
            <div class="CheckBox">
                <div class="Text">{text}</div>
            </div>
            <div class="remove" on:click={onRemove}>
                -
            </div>
        </div>
    </div>
    
    <style lang="scss">
        .TodoItem {
          padding: 1rem;
          display: flex;
          justify-content: space-between;
          align-items: center;
          &:nth-child(even) {
            background: #f8f9fa;
          }
          .checkbox {
            cursor: pointer;
            flex: 1;
            display: flex;
            align-items: center;
            svg {
              font-size: 1.5rem;
            }
            .text {
              margin-left: 0.5rem;
            }
            &.checked {
              svg {
                color: #22b8cf;
              }
              .text {
                color: #adb5bd;
                text-decoration: line-through;
              }
            }
          }
          .remove {
            display: flex;
            align-items: center;
            font-size: 1.5rem;
            color: #ff6b6b;
            cursor: pointer;
            &:hover {
              color: #ff8787;
            }
          }
    
          & + & {
            border-top: 1px solid #dee2e6;
          }
        }
    
        .TodoItem-virtualized {
          & + & {
            border-top: 1px solid #dee2e6;
          }
          &:nth-child(even) {
            background: #f8f9fa;
          }
        }
    </style>

    TodoList


    TodoListはtodos配列に基づいてTodoItemを作成する必要があります.
    each blockを使用してTooItemを作成します.
    component/TodoList.svelte
    <script>
        import {todos} from "../store/todo";
        import TodoItem from "./TodoItem.svelte";
    </script>
    
    <div class="TodoList">
        {#each $todos as todo, index}
            <TodoItem text={todo} index={index}/>
        {/each}
    </div>
    
    <style lang="scss">
      .TodoList {
        min-height: 320px;
        max-height: 513px;
        overflow-y: auto;
      }
    </style>

    App.svelte


    作成したコンポーネントを使用してページを整理する必要がありますよね?
    App.svelteでページを整理しましょう.
    App.svelte
    <script>
    	import TodoInsert from './component/TodoInsert.svelte'
        import TodoList from "./component/TodoList.svelte";
    </script>
    
    <main>
        <div class="TodoTemplate">
            <div class="app-title">TODO List</div>
            <div class="content">
                <TodoInsert/>
                <TodoList/>
            </div>
        </div>
    </main>
    
    <style>
        .TodoTemplate {
            width: 512px;
            margin-left: auto;
            margin-right: auto;
            margin-top: 6rem;
            border-radius: 4px;
            overflow: hidden;
        }
    
        .app-title {
            background: #22b8cf;
            color: white;
            height: 4rem;
            font-size: 1.5rem;
            display: flex;
            align-items: center;
            justify-content: center;
        }
    
        .content {
            background: white;
        }
    </style>
    
    これでTodoappが完成
    糸rundevを作ってページを確認しましょうか?