🏙️作者简介:大家好,我是亦世凡华、渴望知识储备自己的一名前端工程师
🌄个人主页:亦世凡华、
🌆系列专栏:uni-app
🌇座右铭:人生亦可燃烧,亦可腐败,我愿燃烧,耗尽所有光芒。
👀引言
⚓经过web前端的学习,相信大家对于前端开发有了一定深入的了解,今天我开设了uni-app专栏,对于想从移动端开发方向进一步发展的朋友,希望看到我文章的朋友能对你有所帮助。
今天开始使用vue3+uni-app搭建一个电商购物的小程序,因为文章会将项目的每一个地方代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的github上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多关注本专栏,学习更多前端uni-app知识。
如果是第一次接触uni-app并且想学习uni-app的朋友,我是不建议直接从此次实战项目开始看起,可以先阅读一下我以前的基础文章:什么是uniapp?如何开发uniapp?按部就班的学习可以让学习变得更轻松更容易上手哦,闲话少说我们直接开始今天的uni-app实战篇。
目录
🏔️分类列表页面
🌋预览壁纸页面
🗻定义头部导航
🏕️公告页面布局
🏔️分类列表页面
当我们点击首页的壁纸图片的时候,肯定是要跳转到对应的详情页面的,这里我们创建一个分类列表页面,用于存放具体的壁纸信息,由于不仅仅只是首页需要跳转,别的页面也是需要该分类页面,所以这里我们就创建与首页平齐的文件夹,如下所示:
创建好分类页面之后,接下来我们开始创建对应的文件内容样式,这里暂时用静态图片代替:
<template>
<view class="classlist">
<view class="content">
<navigator url="" class="item" v-for="item in 10" :key="item">
<image src="../../common/image/2.jpg" mode="aspectFill"></image>
</navigator>
</view>
</view>
</template>
<script setup></script>
<style scoped lang="scss">
.classlist {
.content {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 5rpx;
padding: 5rpx;
.item {
height: 440rpx;
image {
width: 100%;
height: 100%;
display: block;
}
}
}
}
</style>
然后我们在我们上篇文章讲解到的内容选择区域设置的公共组件处设置跳转链接,这里我们直接传入对应的路径即可,如下所示:
因为首页和分类页面采用相同的组件,所以实现的方式是一致的,呈现的效果如下所示:
🌋预览壁纸页面
接下来开始对预览页面的内容进行开发,这里仍然需要在pages目录下新建一个页面,老生常谈的事这里就不再赘述了,因为壁纸要全屏展示,所以这里我们给创建的页面设置一下自定义导航栏,默认导航栏就会被去除掉:
基础的页面布局如下所示,这里我们设置了一下壁纸的一些遮罩内容,当点击图片的时候,遮罩内容消失,然后用户就可以手动滑动图片了,当再次点击壁纸,遮罩又出现了,具体的实现代码如下所示:
<template>
<view class="preview">
<swiper circular>
<swiper-item v-for="item in 5" :key="item">
<image @tap="maskChange" src="../../common/image/2.jpg" mode="aspectFill"></image>
</swiper-item>
</swiper>
<view class="mask" v-show="maskState">
<view class="goBack"></view>
<view class="count">3 / 9</view>
<view class="time">
<uni-dateformat :date="new Date()" format="hh:mm"></uni-dateformat>
</view>
<view class="date">
<uni-dateformat :date="new Date()" format="MM月dd日"></uni-dateformat>
</view>
<view class="footer">
<view class="box" v-for="item in information" :key="item">
<uni-icons :type="item.icon" size="28" :color="item.color"></uni-icons>
<view class="text">{{ item.name }}</view>
</view>
</view>
</view>ri
</view>
</template>
<script setup>
import { ref} from 'vue'
// 默认显示遮罩内容
const maskState = ref(true)
// 文本信息
let information = ref([
{ name: '信息', icon: 'info', color: 'orange' },
{ name: '5分', icon: 'star', color: 'yellow' },
{ name: '下载', icon: 'download', color: 'green' },
])
// 点击图片取消遮罩内容
const maskChange = () => {
maskState.value = !maskState.value
}
</script>
最终呈现的效果如下所示:
信息弹窗:然后接下来我们要给这个壁纸设置一个弹出层,用来告知用户当前壁纸的一些相关信息,这里我们用到了uni官网提供的弹出层组件,如下我们需要进行安装:
然后这里我们用到了一个评分的功能,这里我们也可以使用uni官网提供的插件,如下:
设置的代码效果如下所示:
<!-- 弹出层 -->
<uni-popup ref="infoPopup" type="bottom" :safe-area="false">
<view class="infoPopup">
<view class="popHeader">
<view></view>
<view class="title">壁纸信息</view>
<view class="close" @tap="handleClose">
<uni-icons type="closeempty" size="18" color="#999"></uni-icons>
</view>
</view>
<scroll-view scroll-y>
<view class="content">
<view class="row" v-for="item in popData" :key="item">
<view class="label">{{ item.label }}</view>
<view class="value roteBox" v-if="item.label == '评分:'">
<uni-rate readonly touchable value="3.5" size="16" />
<text class="score">{{ item.value }}</text>
</view>
<view class="value tabs" v-else-if="item.label == '标签:'">
<view class="tab" v-for="tab in item.tabs" :key="tab">{{ tab }}</view>
</view>
<text v-else selectable class="value">{{ item.value }}</text>
</view>
<view class="copyright">声明:仅用于学习,切勿商业用途</view>
</view>
</scroll-view>
</view>
</uni-popup>
最终呈现的效果如下所示:
评分弹窗:评分弹窗的话也是需要借助上面的uni提供的组件进行设置,具体的代码如下所示:
<!-- 评分弹出层 -->
<uni-popup ref="scorePopup" :is-mask-click="false">
<view class="scorePopup">
<view class="popHeader">
<view></view>
<view class="title">壁纸评分</view>
<view class="close" @tap="handleScoreClose">
<uni-icons type="closeempty" size="18" color="#999"></uni-icons>
</view>
</view>
<view class="content">
<uni-rate v-model="userScore" allowHalf />
<text class="text">{{ userScore }}分</text>
</view>
<view class="footer">
<button @tap="submitScore" :disabled="!userScore" type="default" size="mini" plain="">确认评分</button>
</view>
</view>
</uni-popup>
最终呈现的效果如下所示:
返回按钮:这里我们在左上角做一个返回的按钮进行返回上一层的回调事件,这里用到了一个计算高度的函数,在下面的标题中将着重讲解一下:
<view class="goBack" :style="{ top: getStatusBarHeight() + 'px' }" @tap="goBack">
<uni-icons type="back" size="24" color="#fff"></uni-icons>
</view>
// 点击返回按钮
const goBack = () => {
uni.navigateBack()
}
最终呈现的效果如下所示:
🗻定义头部导航
在首页顶部的地方,我们需要做一个头部的导航搜索栏,便于用户进行搜索操作,这里我们也做一个公共的组件,便于使用,如下所示:
因为我们要自定义导航栏的内容,所以在首页页面,我们也需要对其的pages文件设置自定义导航栏,如下所示:
然后我们开始设置自定义导航栏的内容,这里我们需要通过借助uni提供的API来计算手机顶部的高度:
<template>
<view class="custom-nav-bar">
<view class="navbar">
<view class="statusBar" :style="{ height: statusBarHeight+'px' }"></view>
<view class="titleBar" :style="{ height: titleBarHeight+'px' }">
<view class="title">标题</view>
<view class="search">
<uni-icons class="icon" type="search" size="18" color="#888"></uni-icons>
<text class="text">搜索</text>
</view>
</view>
</view>
<view class="fill" :style="{ height: statusBarHeight + titleBarHeight + 'px' }"></view>
</view>
</template>
<script setup>
import { ref } from 'vue'
// 获取手机系统相关信息
let system = uni.getSystemInfoSync()
// 获取内容距离手机顶部的高度
let statusBarHeight = ref(system.statusBarHeight)
// 获取胶囊按钮的顶部距离及其自身高度
let { top, height } = uni.getMenuButtonBoundingClientRect()
let titleBarHeight = ref(height + (top - statusBarHeight.value)*2)
</script>
最终呈现的效果如下所示:
因为获取系统相关信息可能是通用的功能,这里我们可以通过将其抽离出一个单独的钩子函数来进行操作,如下所示:
// 获取手机系统相关信息
const system = uni.getSystemInfoSync()
// 获取内容距离手机顶部的高度
export const getStatusBarHeight = () => system.statusBarHeight || 0
// 获取胶囊按钮的高度操作
export const getTitleBarHeight = () => {
if (uni.getMenuButtonBoundingClientRect) {
let { top, height } = uni.getMenuButtonBoundingClientRect()
return height + (top - getStatusBarHeight())*2
} else {
return 40
}
}
// 整体的nav高度操作
export const getNavBarHeight = () => getStatusBarHeight() + getTitleBarHeight()
然后我们在相应的组件中进行引入然后使用即可,也能达到相同的效果:
然后我们可以给我们设置的公共nav组件设置一个props来传递不同的title展示不同的标题:
🏕️公告页面布局
接下来完成首页中对公告部分内容,点击跳转到具体的公告页面的内容进行相应的布局,这里我们仍然要创建一个页面出来,这里我们使用到了uni官网提供的一个标签,如下所示:
然后页面我们简单的布局一下:
<template>
<view class="notice">
<view class="title">
<view class="tag">
<uni-tag inverted text="置顶" type="error" />
</view>
<view class="font">这个区域填写标题</view>
</view>
<view class="info">
<view class="item">author</view>
<view class="item">
<uni-dateformat :date="Date.now()" format="yyyy-MM-dd hh:mm:ss" />
</view>
</view>
<view class="content">
内容区域
</view>
<view class="count">
阅读 5888
</view>
</view>
</template>
<script setup></script>
<style scoped lang="scss">
.notice {
padding: 30rpx;
.title {
font-size: 40rpx;
color: #111;
line-height: 20rpx;
padding-bottom: 30rpx;
display: flex;
.tag {
transform: scale(0.8);
transform-origin: left center;
flex-shrink: 0;
}
.font {
padding-left: 6rpx;
}
}
}
</style>
然后我们在首页给公告栏的文字内容套上navigator属性进行页面跳转,如下所示:
最终呈现的效果如下所示: