Как добавить эффект скольжения вверх при удалении записи в Svelte?
Я работаю над небольшим приложением Svelte в учебных целях (я новичок в Svelte).
Приложение отображает JSON пользователей из API randomuser.me в таблице Bootstrap 4.
у меня есть это
deleteUser()
метод
const deleteUser = (uid) => {
let itemIdx = filteredUsers.findIndex(x => x.id == uid);
filteredUsers.splice(itemIdx,1);
filteredUsers = filteredUsers;
}
Я хочу добавить восходящую анимацию, похожую на одну из jQuery
slideUp()
обеспечивает.
Добавление этого летающего перехода в строку таблицы
<tr transition:fly="{{y:-100, duration:200}}">
не дает желаемого результата (хотя эффект, который я получил , красивый), как это видно в этом REPL.
1 ответ
Нужно сделать 2 шага
Добавить
(user)
в конце{#each
- поэтому цикл связывает сгенерированный элемент сuser
объект в соответствующем циклезаменить
deleteUser(user.id)
с участиемdeleteUser(user)
и обновить реализацию - исправить ошибку, потому что у пользователя нет идентификатора?
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.