uni-appDay02

1.首页-通用轮播组件

轮播图组件需要再首页和分类页使用,封装成通用组件

  1. 准备组件

  2. 自动导入组件

    <script setup lang="ts"> import XtxSwiper from '@/components/XtxSwiper.vue' import CustomNavbar from './components/CustomNavbar.vue' </script> <template> <CustomNavbarom /> <XtxSwiper /> <view class="index">index</view> </template> <style lang="scss"> // </style>
  3. 添加组件类型声明

    import XtxSwiper from './XtxSwiper.vue'
    declare module '@vue/runtime-core' {
    export interface GlobalComponents {
    // 确认类型,全局定义
    XtxSwiper: typeof XtxSwiper
    }
    }

2.轮播图-指示点

@change="onChange"

复制代码
<script setup lang="ts">
import { ref } from 'vue'

const activeIndex = ref(0)
// 当swiper下标变化时触发
const onChange: UniHelper.SwiperOnChange = (ev) => {
  // 非空断言用!. 主观上排除掉空值情况
  activeIndex.value = ev.detail!.current
}
</script>
3.轮播图-获取轮播图数据
  1. 封装获取轮播图数据API

    import { http } from '@/utils/http'

    export const getHomeBannerAPI = (distributionSite = 1) => {
    return http({
    method: 'GET',
    url: '/home/banner',
    data: {
    distributionSite,
    },
    })
    }

  2. 页面初始化API

    <script setup lang="ts"> import XtxSwiper from '@/components/XtxSwiper.vue' import { getHomeBannerAPI } from '@/services/home' import CustomNavbar from './components/CustomNavbar.vue' import { onLoad } from '@dcloudio/uni-app'

    const bannerList = ref([])
    const getHomeBannerData = async () => {
    const res = await getHomeBannerAPI()
    bannerList.value = res.result
    }

    onLoad(() => {
    getHomeBannerData()
    })
    </script>

    <template> <CustomNavbarom /> <XtxSwiper /> <view class="index">index</view> </template> <style lang="scss"> // </style>
4.首页-轮播图数据类型并渲染
  1. 定义轮播图数据类型

    /** 首页-广告区域数据类型 /
    export type BannerItem = {
    /
    * 跳转链接 /
    hrefUrl: string
    /
    * id /
    id: string
    /
    * 图片链接 /
    imgUrl: string
    /
    * 跳转类型 */
    type: number
    }

  2. 指定类型并传值给子组件

    import { http } from '@/utils/http'
    import { BannerItem } from '@/types/home'

    export const getHomeBannerAPI = (distributionSite = 1) => {
    return http<BannerItem[]>({
    method: 'GET',
    url: '/home/banner',
    data: {
    distributionSite,
    },
    })
    }

    <script setup lang="ts"> import { BannerItem } from '@/types/home' import { ref } from 'vue'

    const activeIndex = ref(0)
    // 当swiper下标变化时触发
    const onChange: UniHelper.SwiperOnChange = (ev) => {
    // 非空断言用!. 主观上排除掉空值情况
    activeIndex.value = ev.detail!.current
    }
    defineProps<{
    list: BannerItem[]
    }>()
    </script>

  3. 渲染数据

    <template> <view class="carousel"> <swiper :circular="true" :autoplay="false" :interval="3000" @change="onChange"> <swiper-item v-for="item in list" :key="item.id"> <navigator url="/pages/index/index" hover-class="none" class="navigator"> <image mode="aspectFill" class="image" :src="item.imgUrl"></image> </navigator> </swiper-item> </swiper> <view class="indicator"> <text v-for="(item, index) in list" :key="item.id" class="dot" :class="{ active: index === activeIndex }" ></text> </view> </view> </template>
5.前台分类-组件封装
  1. 准备组件(只有首页使用)

  2. 导入并使用组件

  3. 设置首页底色为#F7F7F7

    // 导入

    <script setup lang="ts"> import CategoryPanel from './components/CategoryPanel.vue' </script> <template> <CategoryPanel /> <view class="index">index</view> </template> <style lang="scss"> page { background-color: #f7f7f7; } </style>
6.前台分类数据
  1. 封装获取前台分类数据API

    export const getHomeCategoryAPI = () => {
    return http({
    method: 'GET',
    url: '/home/category/mutli',
    })
    }

  2. 页面初始化调用API

    <script setup lang="ts"> import XtxSwiper from '@/components/XtxSwiper.vue' import { getHomeBannerAPI, getHomeCategoryAPI } from '@/services/home' import CustomNavbar from './components/CustomNavbar.vue' import { onLoad } from '@dcloudio/uni-app' import { ref } from 'vue' import type { BannerItem } from '@/types/home' import CategoryPanel from './components/CategoryPanel.vue'

    // 获取轮播图数据
    const bannerList = ref<BannerItem[]>([])
    const getHomeBannerData = async () => {
    const res = await getHomeBannerAPI()
    bannerList.value = res.result
    }

    const getHomeCategoryData = async () => {
    const res = await getHomeCategoryAPI()
    }
    // 页面加载
    onLoad(() => {
    getHomeBannerData()
    getHomeCategoryData()
    })
    </script>

7.前台分类数据类型并渲染
  1. 定义前台分类数据类型

    export const getHomeCategoryAPI = () => {
    return http<CategoryItem[]>({
    method: 'GET',
    url: '/home/category/mutli',
    })
    }

  2. 指定类型并传值给子组件

    const categoryList = ref<CategoryItem[]>([])
    const getHomeCategoryData = async () => {
    const res = await getHomeCategoryAPI()
    categoryList.value = res.result
    }

  3. 渲染前台分类数据

    <script setup lang="ts"> import { CategoryItem } from '@/types/home'

    defineProps<{
    list: CategoryItem[]
    }>()
    </script>

    <template> <view class="category"> <navigator class="category-item" hover-class="none" url="/pages/index/index" v-for="item in list" :key="item.id" > <image class="icon" :src="item.icon"></image> <text class="text">{{ item.name }}</text> </navigator> </view> </template>
8.首页-热门推荐
  1. 准备组件(只有首页使用)

  2. 导入并使用组件

  3. 封装获取热门推荐数据API

    export const getHomeHotAPI = () => {
    return http({
    method: 'GET',
    url: '/home/hot/mutli',
    })
    }

  4. 定义热门推荐数据类型并指定

    /** 首页-热门推荐数据类型 /
    export type HotItem = {
    /
    * 说明 /
    alt: string
    /
    * id /
    id: string
    /
    * 图片集合[ 图片路径 ] /
    pictures: string[]
    /
    * 跳转地址 /
    target: string
    /
    * 标题 /
    title: string
    /
    * 推荐类型 */
    type: string
    }

    export const getHomeHotAPI = () => {
    return http<HotItem[]>({
    method: 'GET',
    url: '/home/hot/mutli',
    })
    }

  5. 传递给子组件并渲染

    // 获取热门推荐数据
    const hotList = ref<HotItem[]>([])
    const getHomeHotData = async () => {
    const res = await getHomeHotAPI()
    hotList.value = res.result
    }

    <script setup lang="ts"> import { CategoryItem } from '@/types/home'

    defineProps<{
    list: CategoryItem[]
    }>()
    </script>

    <template> <view class="category"> <navigator class="category-item" hover-class="none" url="/pages/index/index" v-for="item in list" :key="item.id" > <image class="icon" :src="item.icon"></image> <text class="text">{{ item.name }}</text> </navigator> </view> </template>
9.猜你喜欢-组件封装
  1. 准备组件(通用组件)

  2. 定义组件类型

    import XtxSwiper from '../components/XtxSwiper.vue'
    import XtxGuess from '../components/XtxGuess.vue'
    declare module '@vue/runtime-core' {
    export interface GlobalComponents {
    // 确认类型,全局定义
    XtxSwiper: typeof XtxSwiper
    XtxGuess: typeof XtxGuess
    }
    }

  3. 准备scroll-view滚动容器

    <template> <CustomNavbarom /> <scroll-view class="scroll-view" scroll-y> <XtxSwiper :list="bannerList" /> <CategoryPanel :list="categoryList" /> <HotPanel :list="hotList" /> <XtxGuess /> </scroll-view> </template>
  4. 设置page和scroll-view样式

    <style lang="scss"> page { background-color: #f7f7f7; height: 100%; display: flex; flex-direction: column; } .scroll-view { flex: 1; } </style>
10.获取猜你喜欢数据
  1. 封装获取猜你喜欢数据API

    export const getHomeGoodsGuessLikeAPI = () => {
    return http({
    method: 'GET',
    url: '/home/goods/guessLike',
    })
    }

  2. 组件挂载完毕调用API

    <script setup lang="ts"> import { getHomeGoodsGuessLikeAPI } from '@/services/home' import { onMounted } from 'vue' //获取猜你喜欢数据 const getHomeGoodsGuessLikeData = async () => { const res = await getHomeGoodsGuessLikeAPI() } // 页面挂载完成后调用 onMounted(() => { getHomeGoodsGuessLikeData() }) </script>
11.猜你喜欢-类型定义和列表渲染
  1. 定义:

    export const getHomeGoodsGuessLikeAPI = () => {
    return http<PageResult<GuessItem>>({
    method: 'GET',
    url: '/home/goods/guessLike',
    })
    }

    <script setup lang="ts"> import { getHomeGoodsGuessLikeAPI } from '@/services/home' import { GuessItem } from '@/types/home' import { onMounted } from 'vue' import { ref } from 'vue'

    // 猜你喜欢的列表
    const geussList = ref<GuessItem[]>([])
    //获取猜你喜欢数据
    const getHomeGoodsGuessLikeData = async () => {
    const res = await getHomeGoodsGuessLikeAPI()
    geussList.value = res.result.items
    }
    // 页面挂载完成后调用
    onMounted(() => {
    getHomeGoodsGuessLikeData()
    })
    </script>

  2. 渲染:

    <template> <view class="caption"> <text class="text">猜你喜欢</text> </view> <view class="guess"> <navigator class="guess-item" v-for="item in geussList" :key="item.id" :url="`/pages/goods/goods?id=4007498`" > <image class="image" mode="aspectFill" :src="item.picture"></image> <view class="name"> {{ item.name }} </view> <view class="price"> <text class="small">¥</text> <text>{{ item.price }}</text> </view> </navigator> </view> <view class="loading-text"> 正在加载... </view> </template>
12.分页准备

监听事件

复制代码
<template>
  <!-- 自定义导航栏 -->
  <CustomNavbarom />
  <!-- 滚动 -->
  <scroll-view @scrolltolower="onScrolltoLower" class="scroll-view" scroll-y>
    <!-- 自定义轮播图 -->
    <XtxSwiper :list="bannerList" />
    <!-- 分类面板 -->
    <CategoryPanel :list="categoryList" />
    <!-- 热门推荐 -->
    <HotPanel :list="hotList" />
    <!-- 猜你喜欢 -->
    <XtxGuess ref="GuessRef" />
  </scroll-view>
</template>

模板ref

复制代码
const GuessRef = ref<XtxGuessInstance>()
const onScrolltoLower = () => {
  GuessRef.value?.getMore()
}

写模板类型
export type XtxGuessInstance = InstanceType<typeof XtxGuess>

暴露方法

复制代码
// 暴露出来
defineExpose({
  getMore: getHomeGoodsGuessLikeData,
})

const onScrolltoLower = () => {
// 调用
  GuessRef.value?.getMore()
}
13.猜你喜欢分页加载

在页码累加的时候要注意排除掉undefine的情况。将可选转换为必选

复制代码
export const getHomeGoodsGuessLikeAPI = (data?: PageParams) => {
  return http<PageResult<GuessItem>>({
    method: 'GET',
    url: '/home/goods/guessLike',
    data,
  })
}

//分页参数
//将可选换为必选
const pageParams: Required<PageParams> = {
  page: 1,
  pageSize: 10,
}
// 猜你喜欢的列表
const geussList = ref<GuessItem[]>([])
//获取猜你喜欢数据
const getHomeGoodsGuessLikeData = async () => {
  const res = await getHomeGoodsGuessLikeAPI()
  // geussList.value = res.result.items
  // 数据追加
  // 要将原数组解构,再追加
  geussList.value.push(...res.result.items)
  // 页码追加
  pageParams.page++
}
14.猜你喜欢分页条件
复制代码
//分页参数
//将可选换为必选
const pageParams: Required<PageParams> = {
  page: 30,
  pageSize: 10,
}
// 猜你喜欢的列表
const geussList = ref<GuessItem[]>([])
// 已结束标记
const finish = ref(false)
//获取猜你喜欢数据
const getHomeGoodsGuessLikeData = async () => {
  // 退出判断
  if (finish.value === true) {
    return wx.showToast({ icon: 'none', title: '没有更多数据~' })
  }
  const res = await getHomeGoodsGuessLikeAPI()
  // geussList.value = res.result.items
  // 数据追加
  geussList.value.push(...res.result.items)
  // 页码小于页总数
  if (pageParams.page < res.result.pages) {
    // 页码追加
    pageParams.page++
  } else {
    // =赋值   ===比较
    finish.value = true
  }
}
15.首页-下拉刷新

开启下拉刷新,监听事件

复制代码
 <!-- 滚动 -->
  <scroll-view
    refresher-enabled
    @refresherrefresh="onRefreshrefresh"
    :refresher-triggered="isTriggered"
    @scrolltolower="onScrolltoLower"
    class="scroll-view"
    scroll-y
  >

加载数据

复制代码
// 自定义下拉刷新
const onRefreshrefresh = async () => {
  isTriggered.value = true
  getHomeBannerData()
  getHomeCategoryData()
  getHomeHotData()

关闭动画

复制代码
// 当前下拉刷新状态
const isTriggered = ref(false)
// 自定义下拉刷新
const onRefreshrefresh = async () => {
  isTriggered.value = true
  // getHomeBannerData()
  // getHomeCategoryData()
  // getHomeHotData()
  // 同时请求
  await Promise.all([getHomeBannerData(), getHomeCategoryData(), getHomeHotData()])
  // 关闭动画
  isTriggered.value = false
}
16.下拉刷新-猜你喜欢组件

重置数据, 暴露出来

复制代码
// 重置数据
const resetData = () => {
  pageParams.page = 1
  geussList.value = []
  finish.value = false
}
// 暴露出来
defineExpose({
  resetData,
  getMore: getHomeGoodsGuessLikeData,
})

重置后调用

复制代码
// 自定义下拉刷新
const onRefreshrefresh = async () => {
  isTriggered.value = true
  // 重置猜你喜欢组件
  GuessRef.value?.resetData()
  // getHomeBannerData()
  // getHomeCategoryData()
  // getHomeHotData()
  // 同时请求
  // 重置后调用
  await Promise.all([
    getHomeBannerData(),
    getHomeCategoryData(),
    getHomeHotData(),
    GuessRef.value?.getMore(),
  ])

  // 关闭动画
  isTriggered.value = false
}
17.骨架屏
复制代码
//template
  <PageSkeleon v-if="isLoading" />
    <template v-else>
      <!-- 自定义轮播图 -->
      <XtxSwiper :list="bannerList" />
      <!-- 分类面板 -->
      <CategoryPanel :list="categoryList" />
      <!-- 热门推荐 -->
      <HotPanel :list="hotList" />
      <!-- 猜你喜欢 -->
      <XtxGuess ref="GuessRef" />
    </template>
  </scroll-view>

//script
const isLoading = ref(false)
// 页面加载
onLoad(async () => {
  isLoading.value = true
  await Promise.all([getHomeBannerData(), getHomeCategoryData(), getHomeHotData()])
  isLoading.value = false
})
相关推荐
Point5 分钟前
[LeetCode] 最长连续序列
前端·javascript·算法
趣多多代言人20 分钟前
20分钟学会TypeScript
前端·javascript·typescript
90后的晨仔20 分钟前
⚙️ 《响应式原理》— Vue 是怎么做到自动更新的?
前端·vue.js
90后的晨仔35 分钟前
🧮《计算属性》— 自动根据其它响应式数据得出结果
前端·vue.js
雲墨款哥44 分钟前
一个前端开发者的救赎之路——JS基础回顾(二)
前端·javascript
baozj1 小时前
html2canvas + jspdf 前端PDF分页优化方案:像素级分析解决文字、表格内容截断问题
前端·vue.js·开源
可乐拌花菜1 小时前
Vue3 + Pinia:子组件修改 Pinia 数据,竟然影响了原始数据?
前端·vue.js
90后的晨仔1 小时前
🧱 《响应式基础》— Vue 如何追踪你的数据变化?
前端·vue.js
smile boy1 小时前
个人财务记录应用
前端·javascript·css·css3·html5
90后的晨仔1 小时前
🚀 Vue 声明式渲染:让 HTML 跟着数据走(超详解)
前端·vue.js