|
2 | 2 | <div class="post-list-container" tabindex="1" @blur="activePost = null"> |
3 | 3 | <!-- 筛选控件 --> |
4 | 4 | <div class="filter-controls"> |
5 | | - <div class="filter-row" style="width: 20%;"> |
6 | | - <Autofill |
7 | | - v-model="searchQuery" |
8 | | - :options="posts.map(p => p.title)" |
9 | | - placeholder="搜索文章标题..." |
10 | | - @select="searchQuery = $event as string" |
11 | | - /> |
12 | | - </div> |
13 | | - |
14 | | - <div class="filter-row"> |
15 | | - <Autofill |
16 | | - v-model="selectedCategory" |
17 | | - :options="['所有分类', ...allCategories]" |
18 | | - placeholder="选择分类" |
19 | | - @select="selectedCategory = $event == '所有分类' ? null : $event as string" |
20 | | - /> |
21 | | - </div> |
22 | | - |
23 | | - <div class="filter-row"> |
24 | | - <Autofill |
25 | | - v-model="tagQuery" |
26 | | - :options="allTags" |
27 | | - placeholder="选择标签" |
28 | | - @select="selectedTags.includes($event as string) || selectedTags.push($event as string); tagQuery = ''" |
29 | | - /> |
| 5 | + <div class="filter-col"> |
| 6 | + <div class="filter-row" style="width: 20%;"> |
| 7 | + <Autofill |
| 8 | + v-model="searchQuery" |
| 9 | + :options="posts.map(p => p.title)" |
| 10 | + placeholder="搜索文章标题..." |
| 11 | + @select="searchQuery = $event as string" |
| 12 | + /> |
| 13 | + </div> |
| 14 | + |
| 15 | + <div class="filter-row"> |
| 16 | + <Autofill |
| 17 | + v-model="selectedCategory" |
| 18 | + :options="['所有分类', ...allCategories]" |
| 19 | + placeholder="选择分类" |
| 20 | + @select="selectedCategory = $event == '所有分类' ? null : $event as string" |
| 21 | + /> |
| 22 | + </div> |
| 23 | + |
| 24 | + <div class="filter-row"> |
| 25 | + <Autofill |
| 26 | + v-model="tagQuery" |
| 27 | + :options="allTags" |
| 28 | + placeholder="选择标签" |
| 29 | + @select="selectedTags.includes($event as string) || selectedTags.push($event as string); tagQuery = ''" |
| 30 | + /> |
| 31 | + </div> |
30 | 32 | </div> |
31 | 33 |
|
32 | 34 | <div v-if="selectedTags.length" class="selected-tags"> |
|
52 | 54 | <div class="post-header"> |
53 | 55 | <h3 class="post-title">{{ post.title }}</h3> |
54 | 56 | <div class="post-meta"> |
55 | | - <button class="delete-btn" @click.stop="handleDelete(post.name)">删除</button> |
| 57 | + <button class="delete-btn" @click.stop="handleDelete(post.name, $event)">删除</button> |
56 | 58 | <span class="post-date">{{ formatDate(post.created) }}</span> |
57 | 59 | <span v-if="post.category" class="post-category">{{ post.category }}</span> |
58 | 60 | </div> |
59 | 61 | </div> |
60 | 62 |
|
61 | 63 | <transition name="slide-fade"> |
62 | 64 | <div v-show="activePost === post.name" class="post-details"> |
63 | | - <p v-if="post.outline" class="post-outline">{{ post.outline }}</p> |
| 65 | + <p v-if="post.outline" class="post-outline">{{ post.outline }} ...</p> |
64 | 66 | <div v-if="post.tags && post.tags.length" class="post-tags"> |
65 | 67 | <span v-for="tag in post.tags" :key="tag" class="tag">{{ tag }}</span> |
66 | 68 | </div> |
|
155 | 157 | } |
156 | 158 | }) |
157 | 159 |
|
158 | | - const handleDelete = (postName: string) => { |
| 160 | + const handleDelete = (postName: string, ev: Event) => { |
159 | 161 | if(confirm('确定要删除这篇文章吗?')) { |
160 | 162 | emit('delete', postName) |
| 163 | +
|
| 164 | + // remove element |
| 165 | + let el = ev.target as HTMLElement; |
| 166 | + while(!el.classList.contains('post-item')){ |
| 167 | + el = el.parentElement as HTMLElement; |
| 168 | + } |
| 169 | + el.remove(); |
161 | 170 | } |
162 | 171 | } |
163 | 172 |
|
|
191 | 200 | padding: 1.5rem; |
192 | 201 | background-color: #f8f9fa; |
193 | 202 | border-radius: 0.8rem; |
| 203 | + } |
| 204 | +
|
| 205 | + .filter-controls .filter-col { |
194 | 206 | display: flex; |
195 | 207 | gap: 1.2rem; |
196 | 208 | } |
|
0 commit comments