练习案例
商品首页
展示商品
ts
# 设置行内样式 超过两行 显示 ...
设置高度 80rpx
设置文本的行数 line-clamp:2
文本溢出... ellipsis
设置伸缩布局 flex
# 回到顶部的样式
使用固定定位
使用wx:if或wx:show控制隐藏
监听页面滚动回调钩子
默认参数event是滚动的位置
定义响应式数据,使用if判断
点击图标滚动位置
使用全局对象的方法 pageScrollTo({})
首页样式
/pages/index/index.wxss
css
.home{
width: 100%;
height: 100%;
}
.home .swiper{
width: 750rpx;
height: 350rpx;
}
.home .swiper .image{
width: 750rpx;
height: 350rpx;
}
.home .category{
display: flex;
flex-wrap: wrap;
}
.home .category .category-item{
width: 146rpx;
width: 146rpx;
display: flex;
flex-direction:column;
justify-content: center;
align-items: center;
background-color: #b7d9eb;
border: 2rpx solid #ccc;
}
.home .category .category-item .category-image{
width: 80rpx;
height: 80rpx;
}
.home .category .category-item .category-title{
font-size: 30rpx;
}
.home .good{
display: flex;
flex-wrap: wrap;
justify-content: space-around; /* 两端的间距是中间的一半 */
}
.home .good .good-item{
width: 320rpx;
margin-top: 20rpx;
border: solid 2rpx #ccc;
}
.home .good .good-item .good-item-img{
width: 320rpx;
height: 320rpx;
}
.home .good .good-item .good-item-title{
font-size: 30rpx;
display: -webkit-box; /* 创建弹性盒子 */
-webkit-box-orient: vertical; /* 设置方向为垂直 */
overflow: hidden; /* 隐藏超出的内容 */
text-overflow: ellipsis; /* 超出部分用省略号 */
-webkit-line-clamp: 2; /* 限制显示的行数 */
word-wrap: break-word; /* 单词折行 */
}
/* 固定定位到右下角 */
.home .totop{
position: fixed; /* 固定定位 */
right: 30rpx;
bottom: 100rpx;
}
.home .totop .totop-img{
width: 80rpx;
height: 80rpx;
}
首页静态
/pages/index/index.wxml
xml
<view class="home">
<!-- 轮播图 -->
<swiper class="swiper" indicator-dots indicator-color="#dbdbdb" indicator-active-color="#d81e06" autoplay circular>
<swiper-item>
<image class="image" src="https://2216847528.oss-cn-beijing.aliyuncs.com/asset/20241118150656.png" mode="aspectFill"/>
</swiper-item>
<swiper-item>
<image class="image" src="https://2216847528.oss-cn-beijing.aliyuncs.com/asset/20241118150656.png" mode="aspectFill"/>
</swiper-item>
<swiper-item>
<image class="image" src="https://2216847528.oss-cn-beijing.aliyuncs.com/asset/20241118150656.png" mode="aspectFill"/>
</swiper-item>
</swiper>
<!-- 分类 -->
<view class="category">
<view class="category-item">
<image class="category-image" src="/static/category/a-duankouduomeiti.png" mode="aspectFill"/>
<text class="category-title">多媒体</text>
</view>
<view class="category-item">
<image class="category-image" src="/static/category/a-huandengpianpptyanshiduomeiti.png" mode="aspectFill"/>
<text class="category-title">PPT</text>
</view>
<view class="category-item">
<image class="category-image" src="/static/category/a-jiangtaijiaocheng.png" mode="aspectFill"/>
<text class="category-title">讲台</text>
</view>
<view class="category-item">
<image class="category-image" src="/static/category/a-tupianzhaopian.png" mode="aspectFill"/>
<text class="category-title">照片</text>
</view>
<view class="category-item">
<image class="category-image" src="/static/category/a-zhaoxiangjizhaopianpaisheduomeiti.png" mode="aspectFill"/>
<text class="category-title">视频</text>
</view>
<view class="category-item">
<image class="category-image" src="/static/category/a-duankouduomeiti.png" mode="aspectFill"/>
<text class="category-title">多媒体</text>
</view>
<view class="category-item">
<image class="category-image" src="/static/category/a-huandengpianpptyanshiduomeiti.png" mode="aspectFill"/>
<text class="category-title">PPT</text>
</view>
<view class="category-item">
<image class="category-image" src="/static/category/a-jiangtaijiaocheng.png" mode="aspectFill"/>
<text class="category-title">讲台</text>
</view>
<view class="category-item">
<image class="category-image" src="/static/category/a-tupianzhaopian.png" mode="aspectFill"/>
<text class="category-title">照片</text>
</view>
<view class="category-item">
<image class="category-image" src="/static/category/a-zhaoxiangjizhaopianpaisheduomeiti.png" mode="aspectFill"/>
<text class="category-title">视频</text>
</view>
</view>
<!-- 商品列表 -->
<view class="good">
<view class="good-item">
<image class="good-item-img" src="https://2216847528.oss-cn-beijing.aliyuncs.com/asset/20241118104045.png" mode="aspectFill"/>
<text class="good-item-title" >樱井雪乃,用日语写作是さくらい ゆきの,罗马音表示为Yukino Sakurai。这位角色以其独特的魅力在动漫界吸引了不少粉丝,她的配音员是柚木凉香,为我们带来生动的</text>
</view>
<view class="good-item">
<image class="good-item-img" src="https://2216847528.oss-cn-beijing.aliyuncs.com/asset/20241118155049.png" mode="aspectFill"/>
<text class="good-item-title" >樱井雪乃,用日语写作是さくらい ゆきの,罗马音表示为Yukino Sakurai。这位角色以其独特的魅力在动漫界吸引了不少粉丝,她的配音员是柚木凉香,为我们带来生动的</text>
</view>
<view class="good-item">
<image class="good-item-img" src="https://2216847528.oss-cn-beijing.aliyuncs.com/asset/20241118104045.png" mode="aspectFill"/>
<text class="good-item-title" >樱井雪乃,用日语写作是さくらい ゆきの,罗马音表示为Yukino Sakurai。这位角色以其独特的魅力在动漫界吸引了不少粉丝,她的配音员是柚木凉香,为我们带来生动的</text>
</view>
<view class="good-item">
<image class="good-item-img" src="https://2216847528.oss-cn-beijing.aliyuncs.com/asset/20241118155049.png" mode="aspectFill"/>
<text class="good-item-title" >樱井雪乃,用日语写作是さくらい ゆきの,罗马音表示为Yukino Sakurai。这位角色以其独特的魅力在动漫界吸引了不少粉丝,她的配音员是柚木凉香,为我们带来生动的</text>
</view>
<view class="good-item">
<image class="good-item-img" src="https://2216847528.oss-cn-beijing.aliyuncs.com/asset/20241118104045.png" mode="aspectFill"/>
<text class="good-item-title" >樱井雪乃,用日语写作是さくらい ゆきの,罗马音表示为Yukino Sakurai。这位角色以其独特的魅力在动漫界吸引了不少粉丝,她的配音员是柚木凉香,为我们带来生动的</text>
</view>
<view class="good-item">
<image class="good-item-img" src="https://2216847528.oss-cn-beijing.aliyuncs.com/asset/20241118155049.png" mode="aspectFill"/>
<text class="good-item-title" >樱井雪乃,用日语写作是さくらい ゆきの,罗马音表示为Yukino Sakurai。这位角色以其独特的魅力在动漫界吸引了不少粉丝,她的配音员是柚木凉香,为我们带来生动的</text>
</view>
<view class="good-item">
<image class="good-item-img" src="https://2216847528.oss-cn-beijing.aliyuncs.com/asset/20241118104045.png" mode="aspectFill"/>
<text class="good-item-title" >樱井雪乃,用日语写作是さくらい ゆきの,罗马音表示为Yukino Sakurai。这位角色以其独特的魅力在动漫界吸引了不少粉丝,她的配音员是柚木凉香,为我们带来生动的</text>
</view>
<view class="good-item">
<image class="good-item-img" src="https://2216847528.oss-cn-beijing.aliyuncs.com/asset/20241118155049.png" mode="aspectFill"/>
<text class="good-item-title" >樱井雪乃,用日语写作是さくらい ゆきの,罗马音表示为Yukino Sakurai。这位角色以其独特的魅力在动漫界吸引了不少粉丝,她的配音员是柚木凉香,为我们带来生动的</text>
</view>
</view>
<!-- 回到顶部 -->
<view class="totop">
<image wx:if="{{showtopBtn}}" bind:tap="toTop" class="totop-img" src="/static/category/toTop.png" mode="aspectFill"/>
</view>
</view>
首页数据
/pages/index/index.js
js
//通过Page方法创建页面 App->Page
Page({
//页面数据
data: {
name: '结城sakuna',
deg:0,
showtopBtn:false
},
//编程式导航按钮回调
goDetail(){
//编程式导航页面跳转
//navigateTo:A->B,但是A页面不会销毁(不能跳转到tabbar页面)
//redirectTo 关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。
wx.redirectTo({
url: '/pages/detail/detail?a=1&b=2',
})
},
// 监听页面滚动
onPageScroll(event){
// 判断
if(event.scrollTop >= 300){
this.setData({
showtopBtn:true
})
}else{
this.setData({
showtopBtn:false
})
}
},
// 回到顶部
toTop(){
wx.pageScrollTo({
scrollTop:0,
duration:400
})
}
})
Tabbar
/app.json
json
{
"pages": [
"pages/index/index",
"pages/user/user",
"pages/shopcart/shopcart"
],
"window": {
"navigationBarBackgroundColor": "#2980B9",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "结城sakana"
},
"tabBar": {
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "/static/tabbar/shouye1.png",
"selectedIconPath": "/static/tabbar/shouye.png"
},
{
"pagePath": "pages/shopcart/shopcart",
"text": "购物车",
"iconPath": "/static/tabbar/shopcart1.png",
"selectedIconPath": "/static/tabbar/shopcart.png"
},
{
"pagePath": "pages/user/user",
"text": "个人中心",
"iconPath": "/static/tabbar/user1.png",
"selectedIconPath": "/static/tabbar/user.png"
}
],
"color": "#2980B9",
"selectedColor": "d81e06",
"backgroundColor": "#ccc"
}
}
文字超出隐藏
css
.good .good-item .good-item-title{
font-size: 30rpx;
display: -webkit-box; /* 创建弹性盒子 */
-webkit-box-orient: vertical; /* 设置方向为垂直 */
overflow: hidden; /* 隐藏超出的内容 */
text-overflow: ellipsis; /* 超出部分用省略号 */
-webkit-line-clamp: 2; /* 限制显示的行数 */
word-wrap: break-word; /* 单词折行 */
}
回到顶部按钮
css
# 定位布局
# 监听页面滚动
js
// 回到顶部
toTop(){
wx.pageScrollTo({
scrollTop:0,
duration:400
})
}
uni案例-萌宠
底部安全区环境变量
ts
padding-bottom:env(safe-area-inset-bottom)
萌宠案例
pets.vue
vue
<template>
<view class="container">
<!-- 菜单 -->
<view class="menu">
<uni-segmented-control
:current="current"
:values="values"
@clickItem="onClickItem"
styleType="button"
activeColor="#2B9939"></uni-segmented-control>
</view>
<!-- 内容 -->
<view class="layout">
<view class="box" v-for="(item, index) in pets" :key="item._id">
<view class="pic">
<image
lazy-load
:src="item.url"
mode="widthFix"
@click="onPreview(index)"></image>
</view>
<view class="text">{{ item.content }}</view>
<view class="author">—— {{ item.author }}</view>
</view>
</view>
<!-- 刷新和回到顶部 -->
<view class="float">
<view class="item" @click="onRefresh">
<uni-icons
type="refreshempty"
size="26"
color="#888"></uni-icons>
</view>
<view class="item" @click="onTop">
<uni-icons type="arrow-up" size="26" color="#888"></uni-icons>
</view>
</view>
<!-- 加载更多 -->
<view class="loadMore">
<uni-load-more :status="status" iconType="auto"></uni-load-more>
</view>
</view>
</template>
<script setup>
import { computed, ref } from "vue";
import { onReachBottom, onPullDownRefresh, onReady } from "@dcloudio/uni-app";
// 定义数据数组
const pets = ref([]);
// 当前分类
const current = ref(0);
// 当前状态
const status = ref("loading");
// 分类数据格式
const classify = [
{ key: "all", value: "全部" },
{ key: "dog", value: "狗狗" },
{ key: "cat", value: "猫猫" },
];
// 通过计算属性 算出分段器的数据格式
const values = computed(() => classify.map((item) => item.value));
//点击菜单回调
const onClickItem = (e) => {
// 设置当前页面的索引
current.value = e.currentIndex;
// 清空数据
pets.value = [];
// 重新发送请求
network();
};
//点击预览
const onPreview = function (index) {
// 获取图片url数组
let urls = pets.value.map((item) => item.url);
// 触发预览图片
uni.previewImage({
current: index,
urls,
});
};
//点击刷新
const onRefresh = function () {
// 开始下拉刷新
console.log("点击刷新执行了");
uni.startPullDownRefresh();
};
//返回顶部
const onTop = () => {
// 滚动API
uni.pageScrollTo({
scrollTop: 0,
duration: 100,
});
};
//发送网络请求
function network() {
// 导航栏加载样式
// uni.showNavigationBarLoading();
status.value = "loading";
// 发送网络请求
uni.request({
url: "https://tea.qingnian8.com/tools/petShow",
data: {
size: 5,
type: classify[current.value].key,
},
header: {
"access-key": "sakuna7758521",
},
})
.then((res) => {
if (res.data.errCode === 0) {
pets.value = [...pets.value, ...res.data.data];
console.log(pets.value);
} else if (res.data.errCode === 400) {
uni.showToast({
title: res.data.errMsg,
icon: "fail",
});
}
})
.catch((err) => {
uni.showToast({
title: "请求有误,请重新刷新",
icon: "none",
});
})
.finally(() => {
// 隐藏导航栏加载样式
// uni.hideNavigationBarLoading();
// 停止刷新
uni.stopPullDownRefresh();
status.value = "more";
});
}
// 触底加载生命周期
onReachBottom(() => {
// 发送网络请求
network();
});
// 下拉刷新生命周期
onPullDownRefresh(() => {
// 清空数据
pets.value = [];
// 设置当前分类为0
current.value = 0;
// 发送网络请求
network();
});
network();
// 发送网络请求 在setup阶段就发送网络请求
</script>
<style lang="scss" scoped>
.container {
.menu {
padding: 50rpx 50rpx 0;
}
.layout {
padding: 50rpx;
.box {
margin-bottom: 60rpx;
box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.08);
border-radius: 15rpx;
overflow: hidden;
.pic {
image {
width: 100%;
}
}
.text {
padding: 30rpx;
color: #333;
font-size: 36rpx;
}
.author {
padding: 0 30rpx 30rpx;
text-align: right;
color: #888;
font-size: 28rpx;
}
}
}
.loadMore {
padding-bottom: calc(env(safe-area-inset-bottom) + 50rpx);
}
.float {
position: fixed;
right: 30rpx;
bottom: 80rpx;
padding-bottom: env(safe-area-inset-bottom);
.item {
width: 90rpx;
height: 90rpx;
background: rgba(255, 255, 255, 0.9);
border-radius: 50%;
margin-bottom: 20rpx;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #eee;
}
}
}
</style>
pages.json
json
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path" : "pages/pets/pets",
"style" :
{
"navigationBarTitleText" : "pets",
"enablePullDownRefresh": true
}
},
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
},
{
"path" : "pages/device/device",
"style" :
{
"navigationBarTitleText" : ""
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {}
}