坑: await 把 Promise 解析为普通对象,async 函数 return 的返回值是 promise 对象,await 后转化为普通 Object
需求: 需要在请求后端数据后,渲染时,边动态设置uni-icon的type类型
根据需求可知,需要使用同步请求,只能等设置完type才能进行渲染,如果异步请求,后台响应太慢了,此时Dom渲染完毕,就无法调用函数动态获取type了
或者等后台请求完,在给每个数据添加iconType,在刷新下数据,v-for进行呈现即可,这里使用的是第二种
<template>
<view>
<!-- 书籍浏览 -->
<view class="box" v-for="(item, index) in books" :key="index">
<view class="books">
<image
class="img"
:src="item.picUrl"
mode="widthFix"
style="width: 150rpx"
></image>
<view class="content" @click="bookDetailClick({ item })">
<view class="tit">{{ item.bookName }}</view>
<!-- <text class="num">{{ index + 1 }}</text> -->
<view class="info">
<!-- <view class="desc">{{ item.bookDesc }}</view> -->
<u-parse class="desc" :content="item.bookDesc" />
<view class="author">{{ item.authorName }}</view>
<view class="category">{{ item.catName }}</view>
</view>
</view>
<uni-icons
class="icons"
:type="item.iconType"
size="20"
@click="detail(item)"
></uni-icons>
</view>
<!-- 分割线 -->
<view class="fengequyu"></view>
</view>
</view>
</template>
<script>
import { getBookList, getBookBySearch } from "@/common/api/book.js";
import {
getQueryIsInShelf,
addToBookShelf,
removeFromBookShelf,
} from "@/common/api/bookshelf.js";
import { getBookDetailById } from "@/common/api/book.js";
export default {
components: {},
data() {
return {
iconType: "",
keyword: "", //关键词
workDirection: "", // 男频还是女频
bookNameList: [],
books: [],
pageNum: 1,
pageSize: 10,
total: 0,
flag: false, //用于显示数据见底输出提示信息
};
},
created() {
this.bookInit();
},
onLoad: function (options) {
if (options.data) {
var data = JSON.parse(decodeURIComponent(options.data));
// 使用传递的数据
console.log("传递search数据:", data);
this.workDirection = data.workDirection;
this.keyword = data.searchValue;
}
this.getBookBySearch();
},
onPullDownRefresh() {
console.log("触发下拉刷新");
},
onReachBottom() {
console.log("数据触底了");
this.pageNum++;
console.log(this.pageNum, "当前页码");
if (this.pageNum > this.total / this.pageSize) {
//数据已经拉取完,没有了
flag = true;
console.log("数据已经拉取完,没有了,显示提示信息");
}
},
methods: {
async bookInit() {
this.books = [];
//重新封装books,添加iconType
// 在这里获取书籍列表,可能是从 API 获取
const bookDatas = await this.getBookBySearch();
// 为每本书设置图标类型
for (const book of bookDatas.data.list) {
book.iconType = await this.getType(book);
}
console.log("打印是否存在iconType", bookDatas.data.list);
this.books = bookDatas.data.list; // 更新书籍列表数据
console.log(this.books, "更新后books");
},
async detail(item) {
console.log(item, "点击传输item");
if (item.iconType == "plus") {
let res = await getBookDetailById(item.id);
const firstBookIndexId = res.data.firstBookIndexId;
//加入书架
await addToBookShelf(item.id, firstBookIndexId)
.then((resAddToShelf) => {
if (resAddToShelf.ok) {
uni.showToast({
title: "加入书架成功",
icon: "none",
mask: true,
duration: 1000,
});
this.getType(item);
} else {
this.message("error", resAddToShelf.msg);
}
})
.catch((error) => {
this.message("error", "加入书架失败" + error);
});
} else {
//移除书架
removeFromBookShelf(item.id)
.then((resRemoveToShelf) => {
if (resRemoveToShelf.ok) {
uni.showToast({
title: "移出书架成功",
icon: "none",
mask: true,
duration: 1000,
});
this.getType(item);
} else {
this.message("error", resRemoveToShelf.msg);
}
})
.catch((error) => {
this.message("error", "移出书架失败" + error);
});
}
},
async getType(item) {
const resIsInShelf = await getQueryIsInShelf(item.id); //注意注意!!!这返回的是promise对象
if (!resIsInShelf.data) {
return "plus";
} else {
console.log("true");
return "minus";
}
},
message(type, message) {
uni.showToast({
title: message,
icon: type,
mask: true,
});
},
//根据搜索结果获取书籍列表
async getBookBySearch() {
let res = await getBookBySearch(
this.pageNum,
this.pageSize,
this.keyword,
this.workDirection
);
console.log(res, "根据搜索结果获取书籍列表");
this.books = [...this.books, ...res.data.list];
this.total = res.data.total;
return res;
},
//点击查看小说详情 公共函数,所有循环的对象都必须定义成item
bookDetailClick(book) {
console.log(book, "当前点击的数据");
console.log(book.item.id, "当前点击的数据的id");
uni.navigateTo({
url: "/pages/bookdetail/bookdetail?bookId=" + book.item.id,
});
},
},
};
</script>
<style lang="scss">
.uni-searchbar {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
position: relative;
padding: 16rpx;
/* 将默认的 #FFFFFF 改为 #C00000 */
background-color: #c00000;
}
.icons {
float: left;
position: absolute;
top: 50%;
right: 10px;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.fengequyu {
width: 100%;
height: 1rpx;
background-color: #e8e8e8;
// margin-top: 100rpx;
}
::v-deep ._root {
/* 超出部分隐藏 */
display: -webkit-box;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
/* autoprefixer: off */
-webkit-box-orient: vertical;
/* autoprefixer: on */
}
.search-box {
position: sticky;
top: 0;
z-index: 999;
}
.books {
width: 100%;
height: 240rpx;
//定位垂直居中 子绝父相
position: relative;
}
.img {
float: left;
margin-top: 10px;
}
.content {
width: 480rpx;
float: left;
//间距
margin-left: 22rpx;
margin-top: 5rpx;
text-align: left;
}
.tit {
display: inline-block;
font-size: 30rpx;
}
.num {
float: right;
color: red;
}
.info {
margin-top: 10rpx;
}
.desc {
font-size: 26rpx;
color: #777777;
/* 超出部分隐藏 */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
}
.author {
color: #777777;
font-size: 30rpx;
//间距
margin-top: 50rpx;
display: inline-block;
}
.category {
border: 1px solid gray;
float: right;
color: gray;
font-size: 25rpx;
padding: 2rpx 15rpx;
margin-top: 50rpx;
}
</style>