前言
实战已经开始了!前面两篇文章中我们把详情页的样式和逻辑都写的差不多了,但是在写逻辑的部分,还是把所有的逻辑代码都写在了setup函数中。本篇文章主要是和大家一起使用之前学过的watchEffect方法对逻辑部分的代码进行拆分。
代码拆分
🌀 看到下图中的代码逻辑,其实是分为四个模块:静态数据、定义数据、获取列表数据、点击tab事件。再加上底部的执行方法和结构数据,代码量虽然不算大,但是阅读起来比较麻烦,代码不统一,每次看一段逻辑的时候,可能还需要上下翻动去找。所以就需要拆分代码逻辑,让setup函数更加简洁一点,也让代码更加统一。
静态数据
🌀 对于静态数据,其实可以不用放到setup函数中,直接放在外部也是可以的。
<script> // import部分 const categories = [ { name: '全部商品', tab: 'all' }, { name: '秒杀', tab: 'seckill' }, { name: '新鲜水果', tab: 'fruit' } ] export default { setup(){ // 逻辑部分 return { categories } } } 复制代码
因为categories属于一个常量,也是固定不会变化的,所以直接放在外部也是可以访问的。在setup函数中也是需要return给外部的。
tab栏相关逻辑
🌀 tab栏部分的逻辑根据上面的完整代码截图可以看出,主要就是定义了currentTab的值,并且在点击tab的时候将点击的数据值赋给currenttab。
😲 在点击事件里面其实还调用了获取数据的方法,但是这个获取数据和tab的逻辑并没有直接关系,可以放到获取数据的拆分代码中去。
👉 所以我们拆分出来的tab栏相关逻辑就是定义currentTab和点击tab栏时赋值而已。
// Tab 相关逻辑部分 const useTabEffect = () => { const currentTab = ref(categories[0].tab) const handleTabClick = (tab) => { currentTab.value = tab } return { currentTab, handleTabClick } } 复制代码
👉 在setup函数中还要结构出useTabEffect函数
setup(){ const { currentTab, handleTabClick } = useTabEffect() return { categories, currentTab, handleTabClick } } 复制代码
👉 点击tab的时候调用的方法也得修改一下
@click="handleCategoryClick(item.tab)" ⬇️修改为⬇️ @click="handleTabClick(item.tab)" 复制代码
watchEffect方法拆分出获取列表数据逻辑
🌀 在获取列表的逻辑中,根据上面代码图示可以看出,首先是定义了一个数组用来接收获取的数据。
👉 拆分出定义数据的部分
// 获取数据相关逻辑 const useCurrentListEffect = () => { const content = reactive({ list: [] }) } 复制代码
🌀 在获取数据调用接口的时候,是根据tab的值改变来重新执行的,在我们以前学过的CompositionAPI篇章中有了解过一个侦听器函数:watchEffect
watchEffect:当页面首次加载时,以及它监听的数据发生变化时就会执行的函数。
👉 了解了原理,我们就可以在watchEffect函数中调用获取数据的方法
// 先引入watchEffect import { watchEffect } from 'vue' 复制代码
const useCurrentListEffect = () => { const content = reactive({ list: [] }) const getContentData = async (tab) => { const result = await get('/api/shop/1/products', { tab }) if (result.data.code === 0 && result.data.data.length) { content.list = result.data.data } } // watchEffect函数监听获取数据方法 watchEffect(() => { getContentData() }) } 复制代码
😲 此时watchEffect函数会分析getContentData方法中依赖的数据,如果依赖的数据发生变化或者首屏加载时,那么watchEffect侦听器函数就会重新执行。
🤔 知道了watchEffect函数需要依赖某个数据才能重新执行,那么在getContentData方法中,就需要定义一个可以让watchEffect函数依赖的值,也就是tab栏的数据值。
😲 tab栏的数据值在拆分Tab相关逻辑的时候,已经定义过了,而且在setup函数中结果出来了。所以我们就可以在setup函数中给useCurrentListEffect方法传递currentTab,
这样就可以让watchEffect函数监听到了。
👉 定义依赖数据值
const useCurrentListEffect = (currentTab) => { const content = reactive({ list: [] }) const getContentData = async () => { const result = await get('/api/shop/1/products', { tab: currentTab.value }) if (result.data.code === 0 && result.data.data.length) { content.list = result.data.data } } watchEffect(() => { getContentData() }) const { list } = toRefs(content) return { list } } 复制代码
- 接收到currentTab之后,由于是用ref函数赋值的,所以需要用currentTab.value的方式取值
👉 从setup函数中获取依赖数据值
setup () { const { currentTab, handleTabClick } = useTabEffect() const { list } = useCurrentListEffect(currentTab) return { categories, currentTab, list, handleTabClick } } 复制代码
👉 由于我们重新定义了获取数据的绑定值,所以页面上循环的contentList也需要改成list
v-for="item in contentList" ⬇️修改成⬇️ v-for="item in list" 复制代码
补充
在详情页获取店铺数据时,我们使用了 route.params 的方式获取到列表传递过来的id,那么我们在获取商品列表时,也可以用同样的方法去动态改变店铺id。
👉 引入useRoute
import { useRoute } from 'vue-router' 复制代码
👉 获取id
const route = useRoute() const shopId = route.params.id 复制代码
👉 接口中动态使用id
const getContentData = async () => { const result = await get(`/api/shop/${shopId}/products`, { tab: currentTab }) if (result.data.code === 0 && result.data.data.length) { content.list = result.data.data } } 复制代码
完整拆分代码
总结
本篇文章主要是带着大家一起把详情页中的逻辑代码拆分出来,并且重新回顾了一下watchEffect侦听器的使用方法,结合实战案例之后,相信大家对watchEffect侦听器方法的使用有了进一步的理解。