uniapp 小兔鲜儿 - 首页模块(1)

目录

自定义导航栏

静态结构

安全区域​

通用轮播组件

静态结构

自动导入全局组件

全局组件类型声明

 .d.ts文件

 注册组件

 @vue/runtime-core 

首页 – 轮播图指示点 

首页 – 获取轮播图数据

首页 – 轮播图数据类型并渲染

首页 – 轮播图总结

首页分类

首页 – 前台分类组件

首页 – 获取前台分类数据

首页 – 前台分类数据类型并渲染


自定义导航栏

参考效果:自定义导航栏的样式需要适配不同的机型。

操作步骤

  1. 准备组件

  2. 隐藏默认导航栏,修改文字颜色

  3. 样式适配 -> 安全区域

静态结构

新建业务组件:src/pages/index/componets/CustomNavbar.vue

<script setup lang="ts">
//
</script>

<template>
  <view class="navbar">
    <!-- logo文字 -->
    <view class="logo">
      <image class="logo-image" src="@/static/images/logo.png"></image>
      <text class="logo-text">新鲜 · 亲民 · 快捷</text>
    </view>
    <!-- 搜索条 -->
    <view class="search">
      <text class="icon-search">搜索商品</text>
      <text class="icon-scan"></text>
    </view>
  </view>
</template>

<style lang="scss">
/* 自定义导航条 */
.navbar {
  background-image: url(@/static/images/navigator_bg.png);
  background-size: cover;
  position: relative;
  display: flex;
  flex-direction: column;
  padding-top: 20px;
  .logo {
    display: flex;
    align-items: center;
    height: 64rpx;
    padding-left: 30rpx;
    .logo-image {
      width: 166rpx;
      height: 39rpx;
    }
    .logo-text {
      flex: 1;
      line-height: 28rpx;
      color: #fff;
      margin: 2rpx 0 0 20rpx;
      padding-left: 20rpx;
      border-left: 1rpx solid #fff;
      font-size: 26rpx;
    }
  }
  .search {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 10rpx 0 26rpx;
    height: 64rpx;
    margin: 16rpx 20rpx;
    color: #fff;
    font-size: 28rpx;
    border-radius: 32rpx;
    background-color: rgba(255, 255, 255, 0.5);
  }
  .icon-search {
    &::before {
      margin-right: 10rpx;
    }
  }
  .icon-scan {
    font-size: 30rpx;
    padding: 15rpx;
  }
}
</style>

安全区域​

不同手机的安全区域不同,适配安全区域能防止页面重要内容被遮挡。

可通过 uni.getSystemInfoSync() 获取屏幕边界到安全区的距离。

核心代码参考

自定义导航配置

// src/pages.json
{
  "path": "pages/index/index",
  "style": {
    "navigationStyle": "custom", // 隐藏默认导航
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "首页"
  }
}

组件安全区适配

<!-- src/pages/index/componets/CustomNavbar.vue -->
<script>
// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()
</script>

<template>
  <!-- 顶部占位 -->
  <view class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
    <!-- ...省略 -->
  </view>
</template>

通用轮播组件

参考效果

小兔鲜儿项目中总共有两处广告位,分别位于【首页】和【商品分类页】。

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

静态结构

首页广告布局为独立的组件 XtxSwiper ,位于的 src/components 目录中。

该组件定义了 list 属性接收外部传入的数据,内部通过小程序内置组件 swiper 展示首页广告的数据。

轮播图组件

静态结构:src/components/XtxSwiper.vue

<script setup lang="ts">
import { ref } from 'vue'

const activeIndex = ref(0)
</script>

<template>
  <view class="carousel">
    <swiper :circular="true" :autoplay="false" :interval="3000">
      <swiper-item>
        <navigator url="/pages/index/index" hover-class="none" class="navigator">
          <image
            mode="aspectFill"
            class="image"
            src="https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/uploads/slider_1.jpg"
          ></image>
        </navigator>
      </swiper-item>
      <swiper-item>
        <navigator url="/pages/index/index" hover-class="none" class="navigator">
          <image
            mode="aspectFill"
            class="image"
            src="https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/uploads/slider_2.jpg"
          ></image>
        </navigator>
      </swiper-item>
      <swiper-item>
        <navigator url="/pages/index/index" hover-class="none" class="navigator">
          <image
            mode="aspectFill"
            class="image"
            src="https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/uploads/slider_3.jpg"
          ></image>
        </navigator>
      </swiper-item>
    </swiper>
    <!-- 指示点 -->
    <view class="indicator">
      <text
        v-for="(item, index) in 3"
        :key="item"
        class="dot"
        :class="{ active: index === activeIndex }"
      ></text>
    </view>
  </view>
</template>

<style lang="scss">
:host {
  display: block;
  height: 280rpx;
}
/* 轮播图 */
.carousel {
  height: 100%;
  position: relative;
  overflow: hidden;
  transform: translateY(0);
  background-color: #efefef;
  .indicator {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 16rpx;
    display: flex;
    justify-content: center;
    .dot {
      width: 30rpx;
      height: 6rpx;
      margin: 0 8rpx;
      border-radius: 6rpx;
      background-color: rgba(255, 255, 255, 0.4);
    }
    .active {
      background-color: #fff;
    }
  }
  .navigator,
  .image {
    width: 100%;
    height: 100%;
  }
}
</style>

自动导入全局组件

参考配置

{
  // 组件自动引入规则
  "easycom": {
    // 是否开启自动扫描 @/components/$1/$1.vue 组件
    "autoscan": true,
    // 以正则方式自定义组件匹配规则
    "custom": {
      // uni-ui 规则如下配置
      "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue",
      // 以 Xtx 开头的组件,在 components 目录中查找
      "^Xtx(.*)": "@/components/Xtx$1.vue"
    }
  }
}

全局组件类型声明

 .d.ts文件

在 TypeScript 中,.d.ts 文件是用来描述 JavaScript 模块或库的声明文件。这些声明文件用于提供类型信息,使得 TypeScript 在引用外部 JavaScript 库时可以获得类型检查和代码提示的支持。

声明文件通常以.d.ts为扩展名,并与相应的 JavaScript 文件相对应。它们用于描述库的类型定义和类型推断规则,以及函数、类、接口和变量的声明。

下面是一个用于声明一个简单 JavaScript 模块的 .d.ts 文件的示例:

// myModule.d.ts

// 导出一个函数的声明
export function myFunction(param: string): void;

// 导出一个类的声明
export class MyClass {
  constructor(name: string);
  sayHello(): void;
}

// 导出一个接口的声明
export interface MyInterface {
  id: number;
  name: string;
}

// 导出一个变量的声明
export const myVariable: number;

在上述例子中,我们声明了一个名为myModule的模块,其中包含一个导出函数myFunction,一个导出类MyClass,一个导出接口MyInterface和一个导出变量myVariable

这个声明文件可以被其他 TypeScript 文件引入和使用:

// index.ts

import { myFunction, MyClass, MyInterface, myVariable } from './myModule';

myFunction('Hello'); // 类型检查
const instance = new MyClass('John'); // 类型检查
instance.sayHello(); // 类型检查
const obj: MyInterface = { id: 1, name: 'John' }; // 类型检查
console.log(myVariable); // 类型检查

通过引入声明文件,TypeScript 可以提供类型检查和自动补全的功能,从而帮助开发者在编写代码过程中减少错误,并提高代码的可维护性。

总结来说,.d.ts 文件是用来提供 JavaScript 模块或库的类型信息的。它们描述了函数、类、接口和变量的声明,使得 TypeScript 能够对外部 JavaScript 代码进行类型检查和代码提示。

 注册组件

Volor 插件说明:Vue Language Toolshttps://github.com/vuejs/language-tools

这段代码是一个声明模块的代码,它引入了一个名为XtxSwiper的Vue组件,并将其注册为全局组件。具体来说,代码的功能如下:

  1. import XtxSwiper from './XtxSwiper.vue':这行代码引入了一个名为XtxSwiper的Vue组件,该组件可能是一个图片轮播组件或其他类型的组件。

  2. declare module '@vue/runtime-core':这行代码声明了一个模块,并指定其名称为"@vue/runtime-core"。

  3. { export interface GlobalComponents { XtxSwiper: typeof XtxSwiper } }:这行代码在声明的模块中定义了一个接口GlobalComponents,该接口包含了一个XtxSwiper属性。这个XtxSwiper属性的类型是typeof XtxSwiper,表示它与之前引入的XtxSwiper组件具有相同的类型。

// src/types/components.d.ts
import XtxSwiper from './XtxSwiper.vue’
declare module '@vue/runtime-core' {
  export interface GlobalComponents {
    XtxSwiper: typeof XtxSwiper
  }
}

 @vue/runtime-core 

@vue/runtime-core 是 Vue.js 框架的运行时核心库。在 Vue.js 中,有两个主要的库:编译时(compiler)和运行时(runtime)。编译时负责将模板转换为渲染函数,而运行时则负责实际的渲染、组件管理等。

@vue/runtime-core 是 Vue 3 中运行时的核心部分,它包含了实际执行渲染、响应式系统、虚拟 DOM 和其他运行时相关的功能。Vue 3 使用了模块化的方式来组织这些功能,因此你会在代码中看到像 @vue/runtime-core 这样的模块引用。

在你的代码示例中,通过声明模块 @vue/runtime-core,你可以扩展 Vue 运行时的全局类型和功能,以便让类型检查器和编辑器能够正确地理解和处理这些扩展。具体到你的代码,它在全局注册了一个名为 XtxSwiper 的组件,使得在整个应用中都可以直接使用这个组件,而不需要在每个单独的组件中都进行导入和注册。

首页 – 轮播图指示点 

知识点:
  • UniHelper 提供事件类型,文档说明
  • (可选链) 允许前面表达式为空值
  • (非空断言) 主观上排除掉空值情况
    <view class="indicator">
      <text
        v-for="(item, index) in 3"
        :key="item"
        class="dot"
        :class="{ active: index === activeIndex }"
      ></text>
    </view>
const activeIndex = ref(0);
const onChange: UniHelper.SwiperOnChange = (ev) => {
  // ! 非空断言,主观上排除掉空值情况
  activeIndex.value = ev.detail!.current;
};

首页 – 获取轮播图数据

1. 封装获取轮播图数据API
export const getHomeBannerAPI = (distributionSite = 1) => {
  return http<BannerItem[]>({
    method: 'GET',
    url: '/home/banner',
    data: {
      distributionSite,
    },
  })
}

2. 页面初始化调用API
import { onLoad } from '@dcloudio/uni-app'
import { getHomeBannerAPI } from '@/services/home'
import type { BannerItem } from '@/types/home'
import { ref } from 'vue'
const bannerList = ref<BannerItem[]>([])
const getHomeBannerData = async () => {
  const res = await getHomeBannerAPI()
  console.log(res)
  bannerList.value = res.result
  console.log(bannerList.value)
}
onLoad(() => {
  getHomeBannerData()
})

首页 – 轮播图数据类型并渲染

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

2. 指定类型并传值给子组件
<XtxSwiper :list="bannerList" />

3. 渲染轮播图数据

defineProps<{
  list: BannerItem[]
}>()
    <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>

首页 – 轮播图总结

首页分类

首页 – 前台分类组件

1677150782440

准备工作

  1. 准备组件,只有首页使用

前台类目布局为独立的组件 CategoryPanel属于首页的业务组件,存放到首页的 components 目录中。

<script setup lang="ts">
//
</script>

<template>
  <view class="category">
    <navigator
      class="category-item"
      hover-class="none"
      url="/pages/index/index"
      v-for="item in 10"
      :key="item"
    >
      <image
        class="icon"
        src="https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/images/nav_icon_1.png"
      ></image>
      <text class="text">居家</text>
    </navigator>
  </view>
</template>

<style lang="scss">
/* 前台类目 */
.category {
  margin: 20rpx 0 0;
  padding: 10rpx 0;
  display: flex;
  flex-wrap: wrap;
  min-height: 328rpx;

  .category-item {
    width: 150rpx;
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    box-sizing: border-box;

    .icon {
      width: 100rpx;
      height: 100rpx;
    }
    .text {
      font-size: 26rpx;
      color: #666;
    }
  }
}
</style>
  1. 导入并使用组件
import CategoryPanel from "./componets/CategoryPanel.vue";

<CategoryPanel />
  1. 设置首页底色为 #F7F7F7
<style lang="scss">
page {
  background-color: #f7f7f7;
}
</style>

首页 – 获取前台分类数据

1. 封装获取前台分类数据API

/**
 * 首页-前台分类-小程序
 */
export const getHomeCategoryAPI = () => {
  return http<CategoryItem[]>({
    method: 'GET',
    url: '/home/category/mutli',
  })
}


2. 页面初始化调用API

import type {  CategoryItem } from "@/types/home";
import { getHomeCategoryAPI } from "@/services/home";
import { onLoad } from "@dcloudio/uni-app";
import { ref } from "vue";
const categoryList = ref<CategoryItem[]>([]);
const getHomeCategoryData = async () => {
  const res = await getHomeCategoryAPI();
  categoryList.value = res.result;
  console.log(res);
};
onLoad(() => {
  getHomeCategoryData();
});

首页 – 前台分类数据类型并渲染

1. 定义前台分类数据类型

export type CategoryItem = {
  /** 图标路径 */
  icon: string
  /** id */
  id: string
  /** 分类名称 */
  name: string
}


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

  <CategoryPanel :list="categoryList" />

import type { CategoryItem } from "@/types/home";
defineProps<{
  list: CategoryItem[];
}>();


3. 渲染前台分类数据

  <view class="category">
    <navigator class="category-item" v-for="item in list" :key="item.id">
      <image class="icon" :src="item.icon" mode="aspectFit"></image>
      <text class="text">{{ item.name }}</text>
    </navigator>
  </view>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/78308.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第九章 动态规划part11(代码随想录)

123.买卖股票的最佳时机III 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须在再次购买前出售掉之前的股票&…

RabbitMq-1基础概念

RabbitMq-----分布式中的一种通信手段 1. MQ的基本概念&#xff08;message queue,消息队列&#xff09; mq:消息队列&#xff0c;存储消息的中间件 分布式系统通信的两种方式&#xff1a;直接远程调用&#xff0c;借助第三方完成间接通信 消息的发送方是生产者&#xff0c…

部署piwigo网页 通过cpolar分享本地电脑上的图片

通过cpolar分享本地电脑上有趣的照片&#xff1a;发布piwigo网页 文章目录 通过cpolar分享本地电脑上有趣的照片&#xff1a;发布piwigo网页前言1. 设定一条内网穿透数据隧道2. 与piwigo网站绑定3. 在创建隧道界面填写关键信息4. 隧道创建完成 总结 前言 首先在本地电脑上部署…

linux下的lld命令

Linux下的lld命令的主要作用&#xff1a;用来查看程式运行所需的共享库&#xff08;动态链接库&#xff09;,常用来解决程式因缺少某个库文件而不能运行的一些问题。 1、首先ldd不是一个可执行程序&#xff0c;而只是一个shell脚本 2、ldd 的使用 lld 可执行程序或者动态库…

MyBatis动态SQL:打造灵活可变的数据库操作

目录 if标签trim标签where标签set标签foreach标签 动态SQL就是根据不同的条件或需求动态地生成查询语句&#xff0c;比如动态搜索条件、动态表或列名、动态排序等。 if标签 在我们填写一些信息时&#xff0c;有些信息是必填字段&#xff0c;有的则是非必填的&#xff0c;这些…

SpringBoot-lombok

为什么要使用lombok? Lombok是一个通过注解以达到减少代码的Java库,如通过注解的方式减少getter,setter方法,构造方法等。通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法&#xff0c;并可以自动化生成日志变量&#xff0c;简化java开发、提高…

c++--SLT六大组件之间的关系

1.SLT六大组件&#xff1a; 容器&#xff0c;迭代器&#xff0c;算法&#xff0c;仿函数&#xff0c;适配器&#xff0c;空间配置器 2.六大组件之间的关系 容器&#xff1a;容器是STL最基础的组件&#xff0c;没有容器&#xff0c;就没有数据&#xff0c;容器的作用就是用来存…

UI设计师个人工作总结范文精选

UI设计师个人工作总结范文(一) 在忙忙碌碌中&#xff0c;2019年又将过去了&#xff0c;在这一年当中&#xff0c;设计部无论是在运作模式、设计产值、还是人员结构&#xff0c;各方面的变化都比较大。 设计部的运作模式是从7月底开始进行调整的&#xff0c;以独立承包制的运营方…

Python学习笔记_基础篇(十一)_socket编程

python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和软件组成的。硬件中的CPU是计算机的核心&#xff0c;它承担计算机的所有任务。 操作系统是运行在硬件之上的软件&#xff0c;是计算机的管理者&#xff0c;它负责资源的管理和分配、任务的调度。 程序是运行…

应用在汽车前照灯系统中的环境光传感芯片

为了保证行车照明的安全性和方便性&#xff0c;减轻驾驶员的劳动强度。近年来&#xff0c;出现了许多新的照明控制系统&#xff0c;例如用于日间驾驶的自动照明系统、光束调节系统、延迟控制等。尤其是汽车自适应前照灯系统&#xff0c;它是一种能够自动改变两种以上的光型以适…

分类预测 | MATLAB实现WOA-CNN-BiLSTM-Attention数据分类预测

分类预测 | MATLAB实现WOA-CNN-BiLSTM-Attention数据分类预测 目录 分类预测 | MATLAB实现WOA-CNN-BiLSTM-Attention数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现WOA-CNN-BiLSTM-Attention数据分类预测&#xff0c;运行环境Matlab2023b及以上…

【数据库系统】--【4】DBMS存储管理

DBMS存储管理 01存储介质概述02外存管理03数据缓冲区管理04共享缓冲区的并发控制05本地缓冲区管理 01存储介质概述 02外存管理 03数据缓冲区管理 04共享缓冲区的并发控制 05本地缓冲区管理 小结 ●存储介质概述 ●外存管理 ●共享数据缓冲区 缓冲区的组织结构缓冲区的替换策略…

易服客工作室:WordPress是什么?初学者的解释

目录 什么是WordPress&#xff1f; WordPress可以制作什么类型的网站&#xff1f; 谁制作了WordPress&#xff1f;它已经存在多久了&#xff1f; 谁使用 WordPress&#xff1f; 白宫网站 微软 滚石乐队 为什么要使用 WordPress&#xff1f; WordPress 是免费且…

JAVA基础知识(六)——异常处理

异常 一、异常概述与异常体系结构二、常见异常三、异常处理机制一&#xff1a;try-catch-finally四、异常处理机制二&#xff1a;throws五、手动抛出异常&#xff1a;throw六、用户自定义异常类七、开发中如何选择使用try-catch-finally还是使用throws八、如何看待代码中的编译…

ATF(TF-A) 威胁模型汇总

安全之安全(security)博客目录导读 目录计划如下&#xff0c;相关内容补充中&#xff0c;待完成后进行超链接&#xff0c;敬请期待&#xff0c;欢迎您的关注 1、通用威胁模型 2、SPMC威胁模型 3、EL3 SPMC威胁模型 4、fvp_r 平台威胁模型 5、RSS-AP接口威胁模型 威胁建模是安全…

Redis消息传递:发布订阅模式详解

目录 1.Redis发布订阅简介 2.发布/订阅使用 2.1 基于频道(Channel)的发布/订阅 2.2 基于模式(pattern)的发布/订阅 3.深入理解Redis的订阅发布机制 3.1 基于频道(Channel)的发布/订阅如何实现的&#xff1f; 3.2 基于模式(Pattern)的发布/订阅如何实现的&#xff1f; 3.3 Sp…

UDP TCP 报文内容

1.UDP 2.TCP 源/目的端口号:表示数据是从哪个进程来,到哪个进程去; 32位序号/32位确认号:后面详细讲;4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是15*460 6位标志位: o URG:紧急指针是否有效 ——urgent 紧急的 o ACK:确认号是否有…

Python pycparser(c文件解析)模块使用教程

文章目录 安装 pycparser 模块模块开发者网址获取抽象语法树1. 需要导入的模块2. 获取 不关注预处理相关 c语言文件的抽象语法树ast3. 获取 预处理后的c语言文件的抽象语法树ast 语法树组成1. 数据类型定义 Typedef2. 类型声明 TypeDecl3. 标识符类型 IdentifierType4. 变量声明…

Java8实战-总结16

Java8实战-总结16 引入流流与集合只能遍历一次外部迭代与内部迭代 引入流 流与集合 只能遍历一次 和迭代器类似&#xff0c;流只能遍历一次。遍历完之后&#xff0c;这个流就已经被消费掉了。可以从原始数据源那里再获得一个新的流来重新遍历一遍&#xff0c;就像迭代器一样…

前后端分离------后端创建笔记(11)用户删除

B站视频&#xff1a;30-用户删除&结束语_哔哩哔哩_bilibili 1、现在我们要做一个删除的功能 1.1 首先做一个删除的功能接口&#xff0c;第一步先来到后端&#xff0c;做一个删除的接口 2、删除我们用Delete请求 3、方法名我给他改一下 3.1这里给他调一下删除方法&#xf…