一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情。
前言
大家好,在上一篇文章圈子广场的分享中我们实现了圈子的分类展示功能。而关于圈子列表的部分代码是我们从“我加入的圈子”中直接复制过来的,也就是说有一部分代码是高度相同(冗余)的,为了追求代码质量还是决定对这部分代码进行抽取和封装, 另外还遗留了一个搜索功能尚未实现,因此我们将利用此次分享专门实现一下这两点功能:
- 圈子列表部分代码抽取封装
- 圈子广场中圈子搜索功能实现
列表封装
为了尽可能的减少代码的冗余,最终还是决定将列表两个tab页中的列表部分封装一下,既然是要封装成公用组件,那么就必须要考虑到封装后的组件必须要同时能够满足两个tab页的功能需求。虽然说两个tab页中列表代码是高度相同,但仔细分析下来还是有不同的地方,比如我加入的圈子列表中最后面显示的是三个点(...)点击后会弹出一个popup可以取消加入对应的圈子;而广场中的圈子后面是一个圈子加入状态(加入或已加入)。另外数据源也不能写死应该是动态的,因此封装时需要考虑到这两点。下面来分析一下大概实现思路:
- 在views下新建一个TopicList.vue文件
- 将Topic.vue中class为topic-box下的所有代码拷贝到TopicList.vue(并将对应的js和css一同拷贝过来)
- 定义一个data属性(props)类型为Array 必选,用来接收父组件传过来的数据
- 定义一个isJoin属性(props)类型为Boolean 默认为true,用于区分是我加入的圈子还是圈子广场
- 最后在Topic.vue中导入TopicList.vue并使用
核心代码及效果图如下:
<!--TopicList.vue-->
<div class="topic-box">
<!--省略...-->
<div class="topic-opt" @click="showPopup" v-if="isJoin">
<van-icon name="ellipsis" size="20px" />
</div>
<div
v-else
class="topic-join"
:class="{ 'join-in': !item.user_interact.is_follow }"
>
<div class="join" v-if="item.user_interact.is_follow">已加入</div>
<div class="join" v-else>加入</div>
</div>
<van-popup v-model:show="show" position="bottom">
<div class="cancel-follow" @click="cancelFollow(item.topic.topic_id)">
取消加入
</div>
<div class="close" @click="closePop">取消</div>
</van-popup>
</div>
复制代码
props: {
data: {
type: Array,
required: true,
},
isJoin: {
type: Boolean,
default: true,
},
},
复制代码
圈子搜索
在官方的圈子广场中,当点击顶部的搜索栏后并不是立即能输入内容,而是将原来所有的内容全部隐藏,并在页面的最顶部显示一个真正的搜索框和取消按钮,而在这个搜索框中才能够实现真正的搜索功能(如下图),整个流程看上去像是跳到了一个新的页面,但实际上貌似是在同一个页面中的不同盒子切换,为了简单起见我们就用一个弹出层来代替了 大概思路如下:
- 在Topic.vue的圈子广场的顶部分别添加一个div盒子和一个van-popup组件
- div盒子样式设置成一个灰色的文本框样式
- van-popup充当弹出层角色用于展示真正的搜搜框和搜索结果
- 在van-popup中添加一个van-field组件,真正的搜索框,用于模糊匹配圈子名称
- 接着在文本框下面添加我们上面封装好的topic-list组件(又派上用场了)用于展示搜素结果
- 在setup中请求后端搜索接口:tag_api/v1/topic/list_by_search_cursor,并将文本框输入的内容作为参数传入
- 最后将搜索结果邦定到topic-list组件上即可
核心代码及效果图:
<div class="topic-search" @click="showSearch">搜索圈子</div>
<van-popup v-model:show="show" position="top" @closed="closePop">
<div class="search-result">
<div class="topic-search">
<van-field
v-model="search"
placeholder="搜索圈子"
@update:model-value="valueChange"
/>
</div>
<topic-list :data="topicList" :isJoin="false" />
</div>
</van-popup>
复制代码
const tabChange = (tab) => {
if (tab.name === 0) {
loadMyTopics();
} else {
lodeTopicsByCate(0, 0);
}
};
if (state.active === 0) {
loadMyTopics();
} else {
lodeTopicsByCate(0, 0);
}
const showSearch = () => {
state.show = true;
state.topicList = [];
};
const valueChange = () => {
api.listBySearchCursor("0", state.search, 30).then((res) => {
state.topicList = res.data;
});
};
const closePop = () => {
lodeTopicsByCate(0, 0);
};
复制代码
总结
本次分享我们对圈子列表相关代码进行了抽取和封装,实现了代码的重复利用。另外还实现了圈子广场中圈子的模糊搜索功能,整体下来也基本没有什么技术难点。今天的分享就到这里了,欢迎小伙伴点赞关注加评论哦!感谢!