6步开发
1.使用mock数据构建list基本结构
2.美化样式
3.tab切换,获取真实数据
4.渲染真实数据
5,让list具备左右切换的能力
6完成list与tabs联动的能力
使用mock数据,构建list基本结构
hot-list-item/ hot -ranking
<template>
<view class="item-container" @click="$emit('click')">
<view class="item-box">
<!-- 左侧 -->
<view class="item-box-left">
<!-- 排名 -->
<hot-ranking :ranking="ranking" />
</view>
<view class="item-box-right">
<!-- 标题 -->
<view class="item-title line-clamp-2">{{ data.title }}</view>
<!-- 简介 -->
<view class="item-desc line-clamp-2">{{ data.desc }}</view>
<view class="item-bottom-box">
<!-- 作者 -->
<text class="item-author">{{ data.nickname }}</text>
<!-- 热度 -->
<view class="hot-box">
<image class="hot-icon" src="@/static/images/hot-icon.png" />
<text class="hot-text">{{ data.views | hotNumber }} 热度</text>
</view>
</view>
</view>
</view>
</view>
</template>
hot-ranking<br />现在用的mock假数据<br />
渲染items,for循环
美化样式
.item-container {
padding-bottom: $uni-spacing-col-lg;
.item-box {
display: flex;
margin: 0 $uni-spacing-col-base;
padding: $uni-spacing-row-lg $uni-spacing-col-base;
background-color: $uni-bg-color;
border-radius: $uni-border-radius-lg;
box-shadow: 2px 2px 5px 1px rgba(143, 143, 143, 0.1);
.item-box-left {
margin-right: $uni-spacing-row-sm;
}
.item-box-right {
width: 100%;
.item-title {
font-size: $uni-font-size-lg;
font-weight: bold;
color: $uni-text-color-title;
}
.item-desc {
padding-top: $uni-spacing-row-sm;
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.item-bottom-box {
margin-top: $uni-spacing-col-sm;
display: flex;
justify-content: space-between;
align-items: center;
.item-author {
font-size: $uni-font-size-sm;
color: $uni-text-color-grey;
}
.hot-box {
.hot-icon {
width: $uni-img-size-sm;
height: $uni-img-size-sm;
vertical-align: top;
}
.hot-text {
margin-left: $uni-spacing-row-sm;
font-size: $uni-font-size-sm;
color: $uni-text-color-hot;
}
}
}
}
}
}
根据tab切换,获取真实数据
tabClick监听,完成list与tab联动的能力
对于点击事件,可以接受当前的激活项·
hot-vue
有了激活项后,可以修改
在data添加激活项
在template里。currentIndex绑定上defaultIndex
当用户点击的时候,让currentIndex = 传递过来的index
这样完成了绑定
数据请求
hot。js
获取tab下面对应的列表,请求文档中的热搜文章列表、
接受一个type参数,就是tab的id
export function getHotListFromTabType (type) {
return request({
url:'/hot/list',
data: {
type
}
})
}
在hot.vue调用接口
import { getHotTabs,getHotListFromTabType } from 'api/hot'
创建对应方法methods ,获取list列表数据
先写上临时id,后来完成调用方法TODO
async loadHotListFromTab(){
await getHotListFromTabType(0)
}
调用时机是在获取热搜文章类型后 调用list 列表数据
因为,获取list数据时候,需要tab中对应的id
async loadtHotTabs() {
// uniapp 支持 async await
const { data: res } = await getHotTabs();
this.tabData = res.list;
// 获取列表数据
this.loadHotListFromTab();
},
现在问题是数据怎么获取?
2个情况
- 如果没有获取到数据
1.1 展示对应loading
1.2 调用接口获取数据
1.3 把数据保存到本地
1.4 隐藏loading
- 已经获取到数据
2.1 直接渲染数据有了缓存之后
需要有一个对应数据源,把数据保存到位置
listData
还需要loading展示内容
data() {
return {
// tabs 数据源
tabData: [],
// list 列表数据加载过程
isLoading: true,
// 以 index 为 key,对应的 list 为 val
listData: {},
去完成1-2步骤
async getHotListFromTab() {
if (!this.listData[this.currentIndex]) {
//1.没有获取到数据
//1.1 展示 loading
this.isLoading = true;
//1.2 调用接口获取数据
// 获取列表数据
const id = this.tabDate[this.currentIndex].id
const { data: res } = await getHotListFromTabType(id);
// 1.3 把数据保存到本地
this.listData[this.currentIndex] = res.list;
// 1.4隐藏 loading
this.isLoading = false;
}
// 因为 this.$nextTick 存在一定的兼容性问题,所以更加推荐使用 setTimeout
setTimeout(async () => {
// 获取当前 swiper 的高度
this.currentSwiperHeight = await this.getCurrentSwiperHeight();
// 放入缓存
this.swiperHeightData[this.currentIndex] = this.currentSwiperHeight;
}, 0);
},
创建loading
uni展示加载动画的组件 state表示当前动画的类型
<uni-load-more status="loading" v-if="isLoading"></uni-load-more>
hot-list-item希望在loading False时候展示
用block包裹
//加载动画
<uni-load-more status="loading" v-if="isLoading" />
//列表
<block v-else>
<!-- 列表循环数据更改为 listData[tabIndex] -->
<hot-list-item
:class="'hot-list-item-' + tabIndex"
v-for="(item, index) in listData[tabIndex]"
:key="index"
:data="item"
:ranking="index + 1"
@click="onItemClick(item)"
></hot-list-item>
</block>
目前数据没有获取,是因为没有调用方法
方法需要在两个地方调用
1,刚获取到文章类型后,调用一次
2.用户点击tab时候再调用一次·1
渲染真实数据
//hot.vue
循环编理item换成真实数据源,里面是key value
<hot-list-item
v-for="(item, index) in listData[currentIndex]" :key="index"
在//hot-list-item里面接受2个参数
data和ranking
props: {
//item的数据
data: {
type: Object,
required: true
},
//排名
ranking: {
type: Number,
required: true
}
把data和item传递给hot.vue 模板里的循环
<hot-list-item
v-for="(item, index) in listData[tabIndex]"
:key="index"
:data="item"
:ranking="index + 1"
></hot-list-item>
数据传递过来后,去显示对应的数据
//hot-list-item
结合文档去写
<view class="item-box-right">
<!-- 标题 -->
<view class="item-title line-clamp-2">{{ data.title }}</view>
<!-- 简介 -->
<view class="item-desc line-clamp-2">{{ data.desc }}</view>
<view class="item-bottom-box">
<!-- 作者 -->
<text class="item-author">{{ data.nickname }}</text>
<!-- 热度 -->
<view class="hot-box">
<image class="hot-icon" src="@/static/images/hot-icon.png" />
<text class="hot-text">{{ data.views | hotNumber }} 热度</text>
</view>
</view>
</view>
功能:简介最多展示2行
样式抽离到styles/global.scss
定义公共样式
固定的zhan’shi
.line-clamp-2 {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
在mai’n.js里引入
import ‘./styles/global.scss’
处理前面排名,把排名传递给hot-ranking里面去
props:{}