如何在 Svelte 中为删除记录添加向上滑动效果?

How can I add a slide up effect to deleting a record in Svelte?

我正在开发一个小型 Svelte 应用程序,用于学习目的(我是 Svelte 的新手)。

应用程序在 Bootstrap 4 table.

中显示来自 randomuser.me API 的 JSON 用户

我有这个deleteUser()方法

const deleteUser = (uid) => {
    let itemIdx = filteredUsers.findIndex(x => x.id == uid);
    filteredUsers.splice(itemIdx,1);
    filteredUsers = filteredUsers;
}

我想添加一个类似于 jQuery 的 slideUp() 提供的向上动画。

在 table 行 <tr transition:fly="{{y:-100, duration:200}}"> 添加这个飞行过渡没有得到想要的结果(虽然我得到的效果 漂亮),因为它可见于此REPL.

需要完成 2 个步骤

  1. {#each 末尾添加 (user) -- 这样循环将生成的元素与相应循环

    上的 user 对象相关联
  2. deleteUser(user.id) 替换为 deleteUser(user) 并更新实现 -- 修正错误,因为用户没有 id?

const deleteUser = (user) => {
    let itemIdx = filteredUsers.findIndex(x => user == x);
    filteredUsers.splice(itemIdx,1);
    filteredUsers = filteredUsers;
}

所以结束代码应该是这样的:

<script>
    import { onMount } from "svelte";
    import { fade, fly } from 'svelte/transition';
    import { flip } from 'svelte/animate';

    const apiURL = "https://randomuser.me/api/";
    let stringToMatch = '';
    let users = [];
    let filteredUsers = [];
    $:filteredUsers = users;
    
        onMount(() => {
            getUsers();
            filterUsers();
        });
    
    const   getUsers = () => {
        let getFrom = "&results=20&inc=name,location,email,cell,picture";
        fetch(`${apiURL}?${getFrom}`)
            .then(res => res.json())
            .then((data) => users = data.results);
    };
    
    const filterUsers = () => {
        filteredUsers = users;

        if(stringToMatch){
            filteredUsers = users.filter(user => {
                return user.name.first.toLowerCase().includes(stringToMatch.toLowerCase())
                    || user.name.last.toLowerCase().includes(stringToMatch.toLowerCase())
                    || user.location.city.toLowerCase().includes(stringToMatch.toLowerCase());
            });
        }
    }
    
    const deleteUser = (user) => {
        let itemIdx = filteredUsers.findIndex(x => x == user);
        filteredUsers.splice(itemIdx,1);
        filteredUsers = filteredUsers;
    }
</script>

<div class="container-fluid">
    <div class="card bg-light mb-2 overflow-hidden">
        <div class="card-header px-2 py-0 d-flex">
            <h6 class="text-dark m-0 align-self-center">Members Area</h6>
        </div>
    <div class="card-body bg-white p-0">
                <div class="search p-2">
                    <input class="form-control" type="text" placeholder="Search..." bind:value="{stringToMatch}" on:input="{filterUsers}">
                </div>
            {#if filteredUsers.length > 0}
                <table class="table users-table m-0">
                    <thead>
                        <tr>
                            <th class="text-right">#</th>
                            <th>Name</th>
                            <th>Lives in</th>
                            <th class="text-right">Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        {#each filteredUsers as user,index (user)}
                            <tr transition:fly="{{y:-100, duration:200}}">
                                <td class="text-right">{index + 1}</td>
                                <td>
                                    <img src="{user.picture.thumbnail}" alt="{user.name.first} {user.name.last}" class="rounded-circle">    
                                    {user.name.first} {user.name.last}
                                </td>
                                <td>{user.location.city}</td>
                                <td class="text-right">
                                    <button class="btn btn-sm btn-secondary" on:click="{deleteUser(user)}">
                                        <i class="fa fa-trash" aria-hidden="true"></i> 
                                    </button>
                                </td>
                            </tr>
                        {/each}
                    </tbody>
                </table>
            {:else}
                <p class="text-center text-muted my-3">No members found</p>
            {/if}
        </div>
    </div>
</div>

<style>
    
    .card-header h6 {
        padding: 10px 0;
    }
    
    .users-table th:first-child {
        width: 30px;
    }
    
    .users-table td {
        padding-top: .25rem;
        padding-bottom: .25rem
    }
    
    .users-table img {
        max-height: 32px;
        width: auto;
        border: 1px solid #c7c7c7;
        margin-right: 10px;
    }
</style>

<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" crossorigin="anonymous">

看看REPL