uni-app--》基于小程序开发的电商平台项目实战(二)

news2025/1/21 16:29:49

🏍️作者简介:大家好,我是亦世凡华、渴望知识储备自己的一名在校大学生

🛵个人主页:亦世凡华、

🛺系列专栏:uni-app

🚲座右铭:人生亦可燃烧,亦可腐败,我愿燃烧,耗尽所有光芒。

👀引言

        ⚓经过web前端的学习,相信大家对于前端开发有了一定深入的了解,今天我开设了uni-app专栏,主要想从移动端开发方向进一步发展,而对于我来说写移动端博文的第二站就是uni-app开发,希望看到我文章的朋友能对你有所帮助。

今天开始使用 vue3 + uni-app 搭建一个电商购物的小程序,因为文章会将项目的每一个地方代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的GitHub上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多关注本专栏,学习更多前端uni-app知识。然后开篇先简单介绍一下本项目用到的技术栈都有哪几个方面(阅读此次项目实践文章能够学习到的技术):

uni-app:跨平台的应用开发框架,基于vue.js可以一套代码同时构建运行在多个平台。

pnpm:高性能、轻量级npm替代品,帮助开发人员更加高效地处理应用程序的依赖关系。

vue3:vue.js最新版本的用于构建用户界面的渐进式JavaScript框架。

typescript:JavaScript的超集,提供了静态类型检查,使得代码更加健壮。

pinia:vue3构建的Vuex替代品,具有响应式能力,提供非常简单的 API,进行状态管理。

uni-ui:基于vue.js和uni-app的前端UI组件库,开发人员可以快速地构建跨平台应用程序。

如果是第一次接触uni-app并且想学习uni-app的朋友,我是不建议直接从此次实战项目开始看起,可以先阅读一下我以前的基础文章:什么是uniapp?如何开发uniapp?按部就班的学习可以让学习变得更轻松更容易上手哦,闲话少说我们直接开始今天的uni-app实战篇。

目录

🍇设置tabbar

🍈自定义导航栏

🍉封装轮播图组件

🍊分类模块搭建

🍋热门推荐模块搭建

🍌猜你喜欢模块搭建

🏆文末送书(好书推荐)


🍇设置tabbar

uni-app设置的底部tabbar的方式与原生微信小程序类似,如果不了解什么是底部tabbar的朋友,那么我推荐你先看一下 tabBar底部栏 ,在uni-app中无非也是相同的操作,我们借助我们上文讲解的插件在pages文件夹下右键新建 uni-app 页面,

输入创建文件夹的名称,空格之后书写导航栏标题:

在pages.json会自动生成我们创建的文件的名称:

接下来在pages.json文件夹下设置tabBar属性的内容,这里要事先在一些图标库类似阿里云图标库找到相关的图标图片,这里不再赘述,代码如下:

// 设置TabBar
"tabBar": {
	"color": "#333",
	"selectedColor": "#008c8c",
	"backgroundColor": "#eee",
	"borderStyle": "white",
	"list": [
		{
			"text": "首页",
			"pagePath": "pages/home/home",
			"iconPath": "static/tabs/home_default.png",
			"selectedIconPath": "static/tabs/home_selected.png"
		},
		{
			"text": "分类",
			"pagePath": "pages/category/category",
			"iconPath": "static/tabs/category_default.png",
			"selectedIconPath": "static/tabs/category_selected.png"
		},
		{
			"text": "购物车",
			"pagePath": "pages/cart/cart",
			"iconPath": "static/tabs/cart_default.png",
			"selectedIconPath": "static/tabs/cart_selected.png"
		},
		{
			"text": "我的",
			"pagePath": "pages/my/my",
			"iconPath": "static/tabs/user_default.png",
			"selectedIconPath": "static/tabs/user_selected.png"
		}
	]
}

最终呈现的效果如下:

🍈自定义导航栏

比如说我们想设置首页独有的一个导航栏,我们可以在首页home文件夹下新建一个业务文件夹,里面存放这该页面的业务组件,比如我们想在首页自定义一下导航栏, 我们可以设置如下代码:

<template>
  <view class="navbar">
    <!-- logo文字 -->
    <view class="logo">
      <h2 class="logo-title">电商平台</h2>
      <text class="logo-text">新鲜 · 亲民 · 快捷</text>
    </view>
    <!-- 搜索条 -->
    <view class="search">
      <text class="icon-search">搜索商品</text>
      <text class="icon-scan"></text>
    </view>
  </view>
</template>

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

<style lang="scss" scoped>
/* 自定义导航条 */
.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-title {
      width: 126rpx;
      height: 39rpx;
      color: #fff;
    }
    .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>

设置完组件之后,然后在home组件中引入该组件:

引入该组件之后,我们需要在pages.json文件中进行设置home首页的导航栏自定义:

设置完自定义之后,我们设置的导航栏组件会自动出现在小程序最顶部:

有个问题就是我们设置的自定义导航栏并不能适配任何手机,因为手机屏幕的宽高不同会导致自定义的导航栏会出现一些图文覆盖的画面,为了防止这种情况,我们需要先了解一个概念,如下:

安全区域:手机的安全区域(Safe Area)是指屏幕上可供应用程序内容使用的实际可视区域,不包括潜在的刘海、圆角等设备特定区域。

我们可以调用uni-app给我们提供的一个api来获取手机系统的一些信息

我们可以打印一下来看看该函数获取到的手机系统的数据:

这里将获取到数据进行样式进行一个动态的呈现,如下:

设置完获取手机机型来展示动态样式数据之后,即使你用了iPhone14 Pro Max效果也很好看:

🍉封装轮播图组件

因为这里我们设置的轮播图在整个项目的多处页面会用到,所以这里我们可以将轮播图设置为全局组件然后再在每个想使用的组件中进行引入便可以了。 如果对轮播图不清楚的朋友可以看看 官网

这里的组件我们设置为子组件,父组件通过传递一些props参数,然后通过数据的传递呈现出不同内容的轮播图组件:

<template>
  <view class="carousel">
    <!-- 轮播图区域 -->
    <swiper indicator-dots autoplay :interval="3000" :duration="1000" circular :list="list">
      <!-- 循环渲染轮播图的item项 -->
      <swiper-item v-for="item in list" :key="item.id">
        <view class="swiper-item">
          <!-- 动态绑定图片的 src 属性 -->
          <image :src="item.imgUrl" mode="aspectFill"></image>
        </view>
      </swiper-item>
    </swiper>
  </view>
</template>

<script setup lang="ts">
import type { BannerItem } from '@/types/home'
// 添加泛型参数来指定属性类型
defineProps<{
  list: BannerItem[]
}>()
</script>

<style lang="scss">
/* 轮播图 */
.carousel {
  height: 100%;
  position: relative;
  overflow: hidden;
  transform: translateY(0);
  background-color: #efefef;
  .swiper-item,
  image {
    width: 100%;
    height: 100%;
  }
}
</style>

这里开始撰写相应的轮播图接口函数如下:

// 封装首页所有要使用的api函数
import type { BannerItem } from '@/types/home'
import { http } from '@/utils/http'

/**
 * 获取首页广告区域的接口函数
 *  @param distributionSite 广告区域展示位置
 */
export const getHomeBanner = (distributionSite = 1) => {
  return http<BannerItem[]>({
    method: 'GET',
    url: '/home/banner',
    data: {
      distributionSite,
    },
  })
}

接下来我们在首页开始调用相应的接口函数获取相应的轮播图数据,然后将获取到的数据通过props传递给全局轮播图组件:

<template>
  <HomeNavbar></HomeNavbar>
  <Swiper :list="bannerList" />
</template>

<script lang="ts" setup>
import { getHomeBanner } from '@/api/home'
import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue'
import HomeNavbar from './components/HomeNavbar.vue'
import type { BannerItem } from '@/types/home'

let bannerList = ref<BannerItem[]>([])

// 获取首页banner数据
const getHomeBannerData = async () => {
  const res = await getHomeBanner()
  bannerList.value = res.result
}
// 组件刚加载的时候调用
onLoad(() => {
  getHomeBannerData()
})
</script>

这里简单说一下,我们要根据接口函数获取到的数据编写相应的ts类型,如下:

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

最终达到的效果如下:

🍊分类模块搭建

分类模块的搭建很简单,通过获取接口函数传递过来的数据,然后在首页通过调用该接口函数获取到的数据然后通过props父传子组件数据进行页面渲染即可,这里我们也是将分类模块单独抽离出来作为home的业务组件,这里我们先编写相应的接口函数,如下:

import { http } from '@/utils/http'
/* *
 * 获取首页前台分类的接口函数
 */
export const getHomeCategory = () => {
  return http({
    method: 'GET',
    url: '/home/category/mutli',
  })
}

编写完接口函数之后,接下来我们在首页home组件中调用该接口函数并打印一下查看数据:

// 获取首页分类数据
const getHomeCategoryData = async () => {
  const res = await getHomeCategory()
  console.log(res)
}
// 组件刚加载的时候调用
onLoad(() => {
  getHomeCategoryData()
})

可以看到我们已经获取到对应的接口函数的数据了,接下来我们需要通过返回给我们的数据编写相应的ts类型:

/** 首页-前台类目数据类型 */
export type CategoryItem = {
  /** 图标路径 */
  icon: string
  /** id */
  id: string
  /** 分类名称 */
  name: string
}

我们通过获取到的分类数据通过props传参传递给子组件CategoryPanel,如下:

<template>
  <view class="category">
    <view class="category-item" hover-class="none" v-for="item in list" :key="item.id">
      <image class="icon" :src="item.icon" @tap="goCategory"></image>
      <text class="text">{{ item.name }}</text>
    </view>
  </view>
</template>

<script setup lang="ts">
// 引入ts类型
import type { CategoryItem } from '@/types/home'

// 设置点击事件
const goCategory = () => {
  uni.switchTab({
    url: '/pages/category/category',
  })
}
// 定义 props 接收数据
defineProps<{
  list: CategoryItem[]
}>()
</script>

<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>

最终达到的效果如下:

🍋热门推荐模块搭建

热门推荐的模块搭建和分类模块搭建类似,通过接口函数调用相应的数据然后再在业务组件中进行一个渲染加载数据即可,这里我们需要先编写相应的接口函数:

/* *
 * 获取首页热门推荐的接口函数
 */
export const getHomeHot = () => {
  return http<HotItem[]>({
    method: 'GET',
    url: '/home/hot/mutli',
  })
}

这里的HotItem是根据接口返回给我们的数据编写相应的ts类型的,这里简单提一下:

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

接下来在首页调用相应的接口函数来获取到数据:

// 获取热门推荐数据
let hotList = ref<HotItem[]>([])
const getHomeHotData = async () => {
  const res = await getHomeHot()
  hotList.value = res.result
}
// 组件刚加载的时候调用
onLoad(() => {
  getHomeHotData()
})

这里通过props传参,将接口获取到的数据传递给业务组件当中去,然后通过插值语法展示:

<template>
  <!-- 推荐专区 -->
  <view class="panel hot">
    <view class="item" v-for="item in list" :key="item.id">
      <view class="title">
        <text class="title-text">{{ item.title }}</text>
        <text class="title-desc">{{ item.alt }}</text>
      </view>
      <navigator hover-class="none" url="/pages/hot/hot" class="cards">
        <image
          v-for="src in item.pictures"
          :key="src"
          class="image"
          mode="aspectFit"
          :src="src"
        ></image>
      </navigator>
    </view>
  </view>
</template>

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

// 定义props接收数据
defineProps<{
  list: HotItem[]
}>()
</script>

最终的效果如下:

🍌猜你喜欢模块搭建

猜你喜欢的模块搭建和前面的类似,区别在于猜你喜欢这个组件是和轮播图一样,不仅仅只是首页模块才使用,所以这里外面需要将其设置为全局组件,命名规则是在轮播图我们已经进行设置了,开头必须是Sw,这里我们先开始便捷相应的接口函数:

/* *
 * 获取首页猜你喜欢的接口函数
 */
export const getHomeGoodsGuessLike = () => {
  return http<PageResult<GuessItem>>({
    method: 'GET',
    url: '/home/goods/guessLike',
  })
}

这里的ts类型采用了泛型嵌套, GuessItem作为泛型T参数,成为items的数组内容数据

接下来我们调用相应的接口函数,然后进行数据的一个呈现:

<template>
  <!-- 猜你喜欢 -->
  <view class="caption">
    <text class="text">猜你喜欢</text>
  </view>
  <view class="guess">
    <navigator
      class="guess-item"
      v-for="item in guessList"
      :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>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
// 获取猜你喜欢的接口函数数据
import { getHomeGoodsGuessLike } from '@/api/home'
import type { GuessItem } from '@/types/home'

// 获取猜你喜欢数据
let guessList = ref<GuessItem[]>([])
const getHomeGoodsGuessLikeData = async () => {
  const res = await getHomeGoodsGuessLike()
  guessList.value = res.result.items
}
// 组件挂载完毕
onMounted(() => {
  getHomeGoodsGuessLikeData()
})
</script>

为了让我们自定义设置的导航栏处于顶部固定显示的效果,这里我们需要使用scroll-view实现设置滚动可视区域的范围,如下:

这里我们通过flex上下布局,然后让滚动区域占据可视区域,最大的宽度这里就设置80%,因为要刨去顶部导航栏的范围:

最终实现的效果如下,至此首页的基础静态搭建完成:

🏆文末送书(好书推荐)

博主最近发现了一个令人惊喜的消息!对于喜欢读书的朋友来说,我非常推荐这个前端书籍网站!在这里,你可以找到最新、最全的前端书籍,满足你对知识的渴望。

无论你是初学者还是资深开发者,这个网站都有适合你的书籍选择。最近也有很多优惠活动:

清华社【秋日阅读企划】领券立享优惠

IT好书 5折叠加10元 无门槛优惠券:https://u.jd.com/Yqsd9wj

活动时间:9月4日-9月17日,先到先得,快快来抢

更重要的是,博主特别为大家准备了一个惊喜活动

只要在评论区留言 “ 人生苦短我爱前端 ” ,博主将会抽取3位幸运儿,免费送出一本该网站出品的精选Vue.js书籍并包邮到你手中!

就算没有抽到的朋友也不要灰心,近期还有该网站也会有更多精彩活动,博主会一直关注。一旦有好的优惠活动会第一时间分享给大家,没有抽到这本书但也想购买的朋友,可以通过下方连接购买

📚 京东购买链接:《Vue.js从入门到精通(软件开发视频大讲堂)》

如果这篇文章的浏览量破3000的话,博主会继续给粉丝送书,大家可以选择自己想要的书籍,博主会尽量满足大家的需求,我会在底部设置一个投票,大家可以选择自己想要的书籍,当然大家也可以把想要的书打在评论区,下次送书说不定就是你想要的书籍哦!

提醒:大家别忘记了在评论区评论:人生苦短,我爱前端!参与抽奖哦。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Acwing 800. 数组元素的目标和

Acwing 800. 数组元素的目标和 题目描述代码展示 题目描述 代码展示 #include<iostream>using namespace std;const int N 1e5 10;int a[N], b[N];int main() {int n , m , x, i 0, j m - 1;cin >> n >> m >> x;for (int i 0; i < n; i ) sc…

java JUC并发编程 第七章 原子操作类增强

系列文章目录 第一章 java JUC并发编程 Future: link 第二章 java JUC并发编程 多线程锁: link 第三章 java JUC并发编程 中断机制: link 第四章 java JUC并发编程 java内存模型JMM: link 第五章 java JUC并发编程 volatile与JMM: link 第六章 java JUC并发编程 CAS: link 第七…

ABB IW93 HESG440356R1处理器模块

处理能力&#xff1a; IW93处理器模块具有强大的处理能力&#xff0c;能够高效执行控制逻辑和算法&#xff0c;确保工业过程的顺利运行。 通信接口&#xff1a; 该模块通常具有多种通信接口&#xff0c;用于与其他设备和系统进行数据交换和集成。这些接口可能包括以太网、串行…

9.13号作业

1> 将之前定义的栈类和队列类都实现成模板类 栈的模块类 #include <iostream> using namespace std;template <typename T> class Stack { private:T data[40]{0};T top-1; public:Stack (){cout<<"这是构造函数"<<endl;}int stack_e…

相亲App定制开发,助力您打造独特交友平台

作为专业的App开发团队&#xff0c;我们致力于为您打造一款独特而出色的相亲交友App。我们深刻理解相亲领域的需求&#xff0c;通过技术创新和用户体验优化&#xff0c;为您提供个性化的定制开发服务。 在相亲App的定制开发过程中&#xff0c;我们将全面考虑您的目标市场和用户…

Java项目---图片服务器

图片服务器--->服务器&#xff08;图床&#xff09; 核心功能&#xff1a;上传图片、展示图片等 比如&#xff1a;编写博客时我们会插入图片&#xff0c;本质上是往文章中放了一个链接&#xff08;URL&#xff09;&#xff0c;这个URL资源在另外一个服务器上。 核心知识点…

在ubuntu18.04上编译C++版本jsoncpp/opencv/onnxruntime且如何配置CMakelist把他们用起来~

这篇文章背景是笔者在ubuntu上编译C代码&#xff0c;依赖一些包&#xff0c;然后需要编译并配置到CMakelist做的笔记。主要也是一直不太懂CMakellist&#xff0c;做个笔记以防忘记&#xff0c;也给读者提供一站式的参考&#xff0c;可能您需要的不是这几个包&#xff0c;但大同…

STM32f103入门(12)USART串口信息发送+接收

USART 介绍串口发送使用工具初始化发送数据接收数据 介绍 电平标准是数据1和数据0的表达方式&#xff0c;是传输线缆中人为规定的电压与数据的对应关系&#xff0c;串口常用的电平标准有如下三种&#xff1a; TTL电平&#xff1a;3.3V或5V表示1&#xff0c;0V表示0 RS232电平&…

成都都市圈公共图书馆《乡村振兴战略下传统村落文化旅游设计》许少辉八一新著

成都都市圈公共图书馆《乡村振兴战略下传统村落文化旅游设计》许少辉八一新著

Discrod账号为什么被封?怎么解封?

Discord作为海外社交产品的新晋王者&#xff0c;近两年来非常受欢迎&#xff0c;据统计&#xff0c;每个月使用Discord的用户数超过3000万。而在跨境电商领域&#xff0c;”内容社群”的打法已经见怪不怪&#xff0c;营销推广少不了Discord&#xff0c;拥有一个或者多个成熟的D…

深度学习-激活函数

文章目录 基础知识Sigmoid函数 &#xff08;Logistic函数&#xff09;双曲正切函数&#xff08;Tanh函数&#xff09;线性整流函数&#xff08;ReLU函数&#xff09;Leaky ReLU函数Softmax函数 基础知识 激活函数是神经网络中的一种非线性函数&#xff0c;它作为神经元的输出函…

Linux 安装Harbor镜像仓库私服

参考链接 Docker 的基础知识、安装、使用Harbor镜像仓库私服搭建 Harbor是什么&#xff1f; Harbor是由VMware公司开源的企业级的Docker Registry管理项目&#xff0c;它包括权限管理(RBAC)、LDAP、日志审核、管理界面、自我注册、镜像复制和中文支持等功能。 Harbor 的所有组…

WebGL正射投影

目录 可视范围&#xff08;正射类型&#xff09; 可视空间 正射投影的盒状可视空间的工作原理 盒状可视空间 定义盒状可视空间 Matrix4.setOrtho&#xff08;&#xff09; 按键控制near、far ​编辑 示例效果 示例代码 代码详解 修改near和far值 通过右方向键增大n…

从物理叠加到化学反应,看方太如何把洗碗机玩出「新价值」

文 | 智能相对论 作者 | 佘凯文 随着酷暑烈日的逐渐远去&#xff0c;秋意也开始浓厚了起来。所谓“秋风起&#xff0c;秋膘贴”&#xff0c;在“金九银十”的当下&#xff0c;美食自是不可辜负的恩赐。肥美多膏的大闸蟹、软糯香甜的南瓜羹、爽脆可口的莲藕汤..... 秋季的美食…

idea中启动maven项目报错-java: 程序包lombok.extern.slf4j不存在问题如何解决

1、 现象&#xff1a; 在springboot的maven项目启动时&#xff0c;报错&#xff1a; Error:(3, 27) java: 程序包lombok.extern.slf4j不存在 编译不报错&#xff0c;maven依赖也合适&#xff0c;项目就是无法启动 原因&#xff1a; 其实不是项目本身或者maven本身的问题&am…

Java垃圾收集机制

目录 前言 判断对象是否存活 引用计数算法 可达性分析算法 GC Root的产生 Java中的四种引用类型 1.强引用 强引用弱化方式 方式1&#xff1a;使对象指向null 方式2&#xff1a;使对象超出作用域范围 2.软引用 3.弱引用 4.虚引用 垃圾收集算法 分代收集理论 垃圾…

Linux内核及可加载内核模块编程

图1 Linux系统整体结构 图2 Linux的源代码结构 下面显示一段内核模块代码案例&#xff1a; #include <linux/moduLe.h> #include <linux/kernel.h #include <linux/intt.h> /*模块的初始化函数lkp_ init()_init是用于初始化的修饰符 */ static int __init lk…

第十五届全国大学生数学竞赛报名快要截止了,你报上名了吗?

关于组织参加 第十五届全国大学生数学竞赛的通知 01 为了培养人才、服务教学、提高大学生学习数学的兴趣&#xff0c;培养学生分析问题、解决问题的能力&#xff0c;发现和选拔数学创新人才&#xff0c;为学生提供一个展示基础知识和思维能力的舞台&#xff0c;我校决定组织参…

SSM整合demo及个人思考

SSM整合 项目整体架构说明1. 创建Maven项目2. 配置web.xml4. 配置springmvc.xml5. 配置spring.xml6. 配置mybatis-config.xml以及创建mapper接口和mapper配置文件7. 配置log4j.xml8. 后端CURD测试8.1 在数据库中插入数据8.2 pojo中的实体类Employee8.3 mapper层的EmployMapper接…

oppo手机便签隐藏了一条怎样打开?手机如何找到隐藏便签?

有不少用户在使用OPPO手机的过程中&#xff0c;遇到了一些问题&#xff0c;例如自己在使用手机系统便签应用时&#xff0c;把一条重要的便签设置了隐藏&#xff0c;但是现在找不到隐藏的便签了。 那么oppo手机便签隐藏了一条怎样打开&#xff1f;OPPO手机如何找到隐藏便签&…