黑马程序员uni-app 小兔鲜儿 项目及bug记录(上)(1)

简介: 黑马程序员uni-app 小兔鲜儿 项目及bug记录(上)(1)

黑马程序员 uni-app 小兔鲜儿 项目及bug记录(上)

文档食用指南

  • 心很挣扎,是要复制官方文档然后再上面基础上进行修改来写这篇博客还是什么(这样从头到尾只要打开我这一个网页即可)想了想,还是算了,就对官方文档做个补充吧。 📜
  • 这篇博客能解决您写小兔线遇到的疑惑和bug,day1,我还记录了些代码,到了day2后,就是专注解决疑惑和bug与介绍项目这样些的好处:比如哑组件模式、Promise性能调优等。
  • 一些没有放到官方文档的阶段性繁琐代码(比如写过很多遍的封装请求) 也加入了本文
  • 📖本文档与官方文档配合使用 小兔鲜儿小程序 | uniapp+vue3+ts (gitee.io)
  • 这个老师课和备案比vue3小兔鲜好太多 🥇,不过还有一些没有总和 比如说 day四最后没有将最终代码放出来 对于已经知道实现的小伙伴不太友好,网上的其他文章也没有放,但我这里有放
  • 使用本文档 帮助您快速开发uniapp 😄
  • 感觉不错就点赞关注吧 :😍
  • 注意 有时候不是你的代码写的有问题 而是项目的后端有问题 看time 在day4里面我就遇到一个接口请求 一直10s 偶尔才返回数据 第二天零点几s就成功拿到数据了
  • 估计是项目请求的后端访问量太大了

  • 有时候 你会遇到一些莫名奇妙的报错 比如导入模板文件的时候报错了 这时候请重新打开编译器

Day 1


  • 本项目建议使用vs开发 建议直接点击目录 通过命令行创建项目

语法

  • 在pages.json中如此做,就可以实现

设置

模拟打开的时候,如果是灰的需要修改

使用命令行创建项目

https://blog.csdn.net/qq_42880714/article/details/126509087

使用vscode开发

插件安装

unit-create-view
uni-helper 
uniapp小程序扩展
1、创建unit文件可自动注册路由
2、代码提示
3、鼠标悬停提示

TS配置

npm i -D @types/wechat-miniprogram @uni-helper/uni-app-types
安装类型声明文件
  • 如果你没有ts配置文件 那是因为你创建了一个js项目 你需要打开cmd创建一个ts项目
npx degit dcloudio/uni-preset-vue#vite-ts  uni-app-Vue3-TS 

{
  "extends": "@vue/tsconfig/tsconfig.json",
  "compilerOptions": {
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "./src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom"
    ],
    "types": [
      "@dcloudio/types",
      "@types/wechat-miniprogram",
      "@uni-helper/uni-app-types"
    ],
    "ignoreDeprecations": "5.0" //TS废弃了之前的版本 所以使用这个
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue"
  ]
}

  • uni-app自带的东西

解决js注释问题

  • jsonc文件允许注释
  • uni-app只允许图中两个写注释

基础架构

拉取小兔线项目

git clone http://git.itcast.cn/heimaqianduan/erabbit-uni-app-vue3-ts.git
heima-shop

  • 要使用pnpm来运行编译项目
npm install -g pnpm
pnpm set registry https://registry.npmmirror.com

使用管理员身份进入cmd 运行以上命令即可

  • 项目编译后会多出mp-weixin文件夹 这个才是才是微信小程序的本体 再微信小程序中打开这个而不是整个项目

安装uni-ui 配置easycom

npm i @dcloudio/uni-ui 
• 1
// pages.json
  // 组件自动映入规则
  "easycom": {
    // 开始自动扫描
    "autoscan": true,
    // 正则方式匹配
    "custom": {
      // uni-ui 规则如下配置
      "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
    }
  },

安装提示

pnpm i -D @uni-helper/uni-ui-types
{
  "extends": "@vue/tsconfig/tsconfig.json",
  "compilerOptions": {
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "./src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom"
    ],
    "types": [
      "@dcloudio/types",
      "@types/wechat-miniprogram",
      "@uni-helper/uni-app-types",
      "@uni-helper/uni-ui-types" // [!code 添加了ui ++]
    ],
    "ignoreDeprecations": "5.0" //TS废弃了之前的版本 所以使用这个
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue"
  ]
}

小程序端pinia持久化

  • stores中进行如下配置
import { defineStore } from 'pinia'
import { ref } from 'vue'
// 定义 Store
export const useMemberStore = defineStore(
  'member',
  () => {
    // 会员信息
    const profile = ref<any>()
    // 保存会员信息,登录时使用
    const setProfile = (val: any) => {
      profile.value = val
    }
    // 清理会员信息,退出时使用
    const clearProfile = () => {
      profile.value = undefined
    }
    // 记得 return
    return {
      profile,
      setProfile,
      clearProfile,
    }
  },
  // TODO: 持久化
  {
    // 配置持久化 网页端只要 persist:true
    persist: {
      // 调整为兼容多端的API
      storage: {
        getItem(key) {
          return uni.getStorageSync(key)
        },
        setItem(key, value) {
          uni.setStorageSync(key, value)
        },
      },
    },
  },
)

  • 如果没有出来可以尝试点击编译 就能刷出来了

如何解决项目中的问题

  • 遇到问题直接访问官方文档 然后查看代码作者编写的项目文档即可

文件拦截器

请求和上传文件

// src/utils/http.ts
import { useMemberStore } from '@/stores'
// 请求基地址
const baseURL = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'
// 拦截器配置
const httpInterceptor = {
  // 拦截前触发
  invoke(options: UniApp.RequestOptions) {
    // 1. 非 http 开头需拼接地址
    if (!options.url.startsWith('http')) {
      options.url = baseURL + options.url
    }
    // 2. 请求超时
    options.timeout = 10000
    // 3. 添加小程序端请求头标识
    options.header = {
      'source-client': 'miniapp',
      ...options.header,
    }
    // 4. 添加 token 请求头标识
    const memberStore = useMemberStore()
    const token = memberStore.profile?.token
    if (token) {
      options.header.Authorization = token
    }
  },
}
// 拦截 request 请求
uni.addInterceptor('request', httpInterceptor)
// 拦截 uploadFile 文件上传
uni.addInterceptor('uploadFile', httpInterceptor)
<script setup lang="ts">
import { useMemberStore } from '@/stores'
import '@/utils/http'
const memberStore = useMemberStore()
// 测试请求
const getDate = () => {
  uni.request({
    method: 'GET',
    url: '/home/banner',
  })
}
</script>
<template>
  <view class="my">
    <view>会员信息:{{ memberStore.profile }}</view>
    <button
      @tap="
        memberStore.setProfile({
          nickname: '黑马先锋',
        })
      "
      size="mini"
      plain
      type="primary"
    >
      保存用户信息
    </button>
    <button @tap="memberStore.clearProfile()" size="mini" plain type="warn">清理用户信息</button>
    <!-- @tap是uni-app框架的监听 其他是演示什么的 -->
    <button @tap="getDate" size="mini" plain type="primary">测试请求</button>
  </view>
</template>
<style lang="scss">
//
</style>
文件拦截器这一节出现的问题

Cannot find module '@/stores'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?
报错信息

解决方案

{
  "extends": "@vue/tsconfig/tsconfig.json",
  "compilerOptions": {
    "allowJs": true,
    "sourceMap": true,
    "moduleResolution": "node",
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    },
    "lib": ["esnext", "dom"],
    "types": ["@dcloudio/types",
              "miniprogram-api-typings",
              "@uni-helper/uni-app-types",
              "@uni-helper/uni-ui-types" // uni-ui 组件类型
            ]
  },
  "vueCompilerOptions": {
    // experimentalRuntimeMode 已废弃,现调整为 nativeTags,请升级 Volar 插件至最新版本
    "nativeTags": ["block", "component", "template", "slot"]
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}

相关知识解析

import { useMemberStore } from ‘@/stores’ 是在导入什么

Promise请求函数封装

/**
 * 请求函数
 * @param  UniApp.RequestOptions
 * @returns Promise
 *  1. 返回 Promise 对象,用于处理返回值类型
 *  2. 获取数据成功
 *    2.1 提取核心数据 res.data
 *    2.2 添加类型,支持泛型
 *  3. 获取数据失败
 *    3.1 401错误  -> 清理用户信息,跳转到登录页
 *    3.2 其他错误 -> 根据后端错误信息轻提示
 *    3.3 网络错误 -> 提示用户换网络
 */
type Data<T> = {
  code: string
  msg: string
  result: T
}
// 2.2 添加类型,支持泛型
export const http = <T>(options: UniApp.RequestOptions) => {
  // 1. 返回 Promise 对象 一个异步处理函数 可以处于进行中、已成功、已失败三种状态 用于解决回调地域和异步代码复杂性问题
  // 其中 resolve是成功调用的函数 另一个是失败调用的函数
  return new Promise<Data<T>>((resolve, reject) => {
    uni.request({
      // 使用展开符 具体情况可以看我笔记的下面
      ...options,
      // 响应成功
      success(res) {
        // 状态码 2xx,参考 axios 的设计
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 2.1 提取核心数据 res.data as是强制转换
          resolve(res.data as Data<T>)
        } else if (res.statusCode === 401) {
          // 401错误  -> 清理用户信息,跳转到登录页
          const memberStore = useMemberStore()
          memberStore.clearProfile()
          uni.navigateTo({ url: '/pages/login/login' })
          reject(res)
        } else {
          // 其他错误 -> 根据后端错误信息轻提示
          uni.showToast({
            // 指定不显示图标
            icon: 'none',
            // 如果请求数据中有msg则显示 否则标题为请求错误
            title: (res.data as Data<T>).msg || '请求错误',
          })
          reject(res)
        }
      },
      // 响应失败
      fail(err) {
        uni.showToast({
          icon: 'none',
          title: '网络错误,换个网络试试',
        })
        reject(err)
      },
    })
  })
}
//my.vue 的测试请i去更新
// 测试请求
const getDate = async () => {
  const res = await http({
    method: 'GET',
    url: '/home/banner',
    header: {},
  })
  console.log('请求成功', res)
}
我无法看懂这个函数!

…options

小结

自定义导航栏

<!-- src/pages/index/componets/CustomNavbar.vue -->
<script setup lang="ts">
const { safeAreaInsets } = uni.getSystemInfoSync()
</script>
<template>
  <view class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
    <!-- 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;
    padding-top: 20rpx;
    .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>
// src/pages.json
{
  "path": "pages/index/index",
  "style": {
    "navigationStyle": "custom", // 隐藏默认导航
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "首页"
  }
}

报错 Module ‘“d:/Code/erabbitShop-uni-app-Vue3-TS/src/pages/index/components/CustomNavbar.vue”’ has no default export.

  • 因为你装的插件问题 Vetur

  • 把这个插件删掉/禁用 使用 vola(不在维护)

没有显示导航栏目

  • 查看项目有没有跑起来

Day2

轮播图

  • 导入组件没有什么值得讲的,后面的是配置自动导入,项目约定都以Xtx开头

  • 使用CTRL + i 实现自动导入

轮播图一图理清

Ts

  • 打错字了 应该是对返回数据做了一个预测

为什么要把子组件使用的数据在父组件发请求获取 而不是在子组件中获取?明明父组件不需要这些数据

这是一个常见的设计模式,称为"智能组件和哑组件"模式。

在这种模式中,父组件负责获取数据和处理业务逻辑,而子组件负责接收数据并展示。这种方式有几个优点:

  1. 数据流的可控性: 父组件可以更好地控制数据的获取和传递,从而使整个应用程序的数据流更加清晰可见。
  2. 复用性: 子组件可以更加通用,因为它们不需要关心数据的获取方式和业务逻辑,只需要关注数据的展示。
  3. 单一职责原则: 父组件负责数据获取和处理,符合单一职责原则,使得组件更加容易理解和维护。

另外,这种设计模式也有助于提高代码的可测试性和可维护性,因为业务逻辑更加集中,更容易进行单元测试和重构。

我甚至看不懂vue代码!要怎么办

首页 前台分类组件

// 修改小程序的颜色 类似html5中为body指定颜色
page {
  background-color: #f7f7f7;
}

获取前台数据

TS类型声明使用及编写

存储理念

  • 一个组件是通用的存放在components中,不是则存放在page里的components中

热门推荐

猜你喜欢

滚动实现

获取数据

为什么要在子组件中获取数据而不是父组件中获取数据?

在子组件中获取数据而不在父组件中获取数据通常被称为"自包含组件"或"自管理组件"模式。在这种模式下,子组件负责管理自己的状态和数据获取逻辑,而不依赖于外部组件传递数据。

这种模式的优点包括:

  1. 组件独立性:子组件独立于父组件,可以更轻松地复用和维护。
  2. 封装性:子组件封装了自己的数据获取逻辑,使得代码更加清晰和易于理解。
  3. 可测试性:子组件的行为和状态更容易进行单元测试,因为其逻辑更加集中和独立。

然而,这种模式也存在一些局限性:

  1. 数据传递复杂性:如果子组件需要从多个父组件获取数据,可能需要在多个地方重复编写数据获取逻辑,增加了复杂性。
  2. 性能影响:如果同一个数据在多个子组件中重复获取,可能会导致冗余的数据请求,影响性能。

猜你喜欢分页准备

首页下拉刷新

调优

这样就能实现全部一起开始请求



黑马程序员uni-app 小兔鲜儿 项目及bug记录(上)(2):https://developer.aliyun.com/article/1548510

目录
相关文章
|
1月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
147 0
安卓项目:app注册/登录界面设计
|
1月前
|
移动开发 小程序 数据可视化
基于npm CLI脚手架的uniapp项目创建、运行与打包全攻略(微信小程序、H5、APP全覆盖)
基于npm CLI脚手架的uniapp项目创建、运行与打包全攻略(微信小程序、H5、APP全覆盖)
220 3
|
1月前
|
缓存 开发框架 移动开发
uni-app:下载使用uni&创建项目&和小程序链接&数据缓存&小程序打包 (一)
uni-app 是一个跨平台的开发框架,它允许开发者使用 Vue.js 来构建应用程序,并能够同时发布到多个平台,如微信小程序、支付宝小程序、H5、App(通过DCloud的打包服务)等。uni-app 的目标是通过统一的代码库,简化多平台开发过程,提高开发效率。 在这一部分中,我们将逐步介绍如何下载和使用uni-app、创建一个新的项目、如何将项目链接到小程序,以及实现数据缓存的基本方法。
|
3月前
|
小程序 前端开发 Java
SpringBoot+uniapp+uview打造H5+小程序+APP入门学习的聊天小项目
JavaDog Chat v1.0.0 是一款基于 SpringBoot、MybatisPlus 和 uniapp 的简易聊天软件,兼容 H5、小程序和 APP,提供丰富的注释和简洁代码,适合初学者。主要功能包括登录注册、消息发送、好友管理及群组交流。
106 0
SpringBoot+uniapp+uview打造H5+小程序+APP入门学习的聊天小项目
|
3月前
|
开发框架 .NET Docker
【Azure 应用服务】App Service .NET Core项目在Program.cs中自定义添加的logger.LogInformation,部署到App Service上后日志不显示Log Stream中的问题
【Azure 应用服务】App Service .NET Core项目在Program.cs中自定义添加的logger.LogInformation,部署到App Service上后日志不显示Log Stream中的问题
|
3月前
|
JavaScript Windows
【Azure 应用服务】用App Service部署运行 Vue.js 编写的项目,应该怎么部署运行呢?
【Azure 应用服务】用App Service部署运行 Vue.js 编写的项目,应该怎么部署运行呢?
|
3月前
|
Java 开发工具 git
【Azure 应用服务】本地Git部署Java项目到App Server,访问无效的原因
【Azure 应用服务】本地Git部署Java项目到App Server,访问无效的原因
|
3月前
|
Linux Python
【Azure 应用服务】Azure App Service For Linux 上实现 Python Flask Web Socket 项目 Http/Https
【Azure 应用服务】Azure App Service For Linux 上实现 Python Flask Web Socket 项目 Http/Https
|
3月前
|
存储 关系型数据库 Linux
【Azure 应用服务】App Service For Linux 部署PHP Laravel 项目,如何修改首页路径为 wwwroot\public\index.php
【Azure 应用服务】App Service For Linux 部署PHP Laravel 项目,如何修改首页路径为 wwwroot\public\index.php
|
3月前
|
Linux C# C++
【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务

热门文章

最新文章