这一章节是要将从首页的点击进入子组件,然后展示对应的数据。这里涉及到页面传递参数、将获取的数据渲染到页面上
给组件通过defineProps声明变量传值渲染
因为使用的是子组件,那就需要再父组件中点击后,给子组件传递参数,根据参数得到对应的数据并渲染到页面上。效果图:
在初始进入页面时,就要获取这里的数据,数据包含了图片缩略图、时间、图片类型。
// 获取专题精选的图片地址
const classifyList=ref([])
const getClassify = async () => {
let res=await apiGetClassify({pageSize:8});
classifyList.value=res.data
}
getClassify();
先要获取数据,这是获取数据的方法,上一章已经学习了将网络请求进行封装,这里直接调用接口就可以了,获取到数据后,那要怎么给子组件传递参数?这就需要使用defineProps声明变量后,在从父组件传递数据过去。
子组件声明变量:
defineProps({
isMore: {
type: Boolean,
default: false
},
item: { //数据源
type: Object, //类型,因为是传对象,这里使用Object
default () { //这里定义对象的参数
return {
name: "默认名称",
picurl: "../../common/images/classify1.jpg",
updateTime: Date.now() - 1000 * 60 * 60 * 5
}
}
}
})
子组件定义了对象接收的参数,那父组件要怎么传递呢?
直接使用子组件定义的对象名后,这里就使用:item=“item”,将需要的数据传递过去。
子组件接收到数据后,直接使用定义的对象名将数据渲染到页面上
这里圈出的是什么?查看数据源,发现服务器给的是一时间戳,那如何将时间戳更改成效果图的形式?例如:大于1分钟小于1小时的时候,页面显示的是多少分钟前发布的。这种情况要如何编写?这里就要说下ChatGPT强大了,可以直接使用AI编写,将编写的js放在公共模块下,这里就可以直接使用了,下面把AI写的js贴出来
export function timeDifference(timestamp) {
const now = new Date().getTime();
const difference = now - timestamp;
const minute = 60 * 1000;
const hour = 60 * minute;
const day = 24 * hour;
const month = 30 * day;
if (difference < minute) {
return '1分钟';
} else if (difference < hour) {
return Math.floor(difference / minute) + '分钟';
} else if (difference < day) {
return Math.floor(difference / hour) + '小时';
} else if (difference < month) {
return Math.floor(difference / day) + '天';
} else if (difference < 3 * month) {
return Math.floor(difference / month) + '月';
} else {
return null;
}
}
export function gotoHome(){
uni.showModal({
title:"提示",
content:"页面有误将返回首页",
showCancel:false,
success: (res) => {
if(res.confirm){
uni.reLaunch({
url:"/pages/index/index"
})
}
}
})
}
当AI给出的是当前页面的方法,我们把这个放在公共区域,那就需要把该方法暴露出去,其他地方才能使用,在方法前面添加 export就好
组件深层跳转传参和多参数网络请求
上面组件已经显示数据了,那如果要看同类型下的其他数据呢,只用点击进入后,就可以继续访问网络数据了,那组件跳转如何传递参数呢?
在前面学习跳转的时候,已经学习了组件跳转传参的方式,第一个参数是使用’?‘的形式,第二个以后得参数,要使用’&'将所有参数拼接起来,
那如何接收呢?
我们使用onLoad()接收,这里记着,使用onLoad接收的时候,要在当前页面引用@dcloudio/uni-app,不然是不能使用的。
在onLoad接收的时候,可以直接得到传递的参数,
onLoad((e)=>{
let{id=null,name=null}=e
queryParams.classid=id;
uni.setNavigationBarTitle({
title:name
});
getClassList(); //获取数据
})
这就是接受参数后再访问网络,这里需要注意,因为uni-app的生命周期,这里不能把网络访问放在下面调用,必须放在onLoad之后访问。
多参数访问网络数据
这里访问服务器获取数据的时候,就需要传递进入页面的类型、id、数量等,这就是多个参数,为了方便我们,直接在外部定义一个空对象,将需要传递的参数全部写到对象中,给对象一个默认值。然后在onLoad中给对象赋值,使用的时候,可以直接使用对象名就能把所有的参数传递过去,我们已经在网络请求中进行了封装了。
这里特别提醒下,也是我犯下的错,
我已经定义了对象,在请求的时候,将对象传递过去,我是把对象放在{}中,死活获取不到,最后各种尝试,才发现,居然把对象又放在对象中,这样服务器解析的时候,就没办法拿到定义的参数名了,这里说下,大家谨记
下面是这个页面的详细逻辑代码
<template>
<view class="classlist">
<view class="content">
<navigator url="/pages/preview/preview" class="item" v-for="item in classList" :key="item._id">
<image :src="item.smallPicurl" mode="aspectFill"></image>
</navigator>
</view>
</view>
</template>
<script setup>
import {ref} from 'vue';
import {apiClassList} from "@/api/apis.js"
import {onLoad,onReachBottom} from "@dcloudio/uni-app"
const classList = ref([]);
const queryParams={ //对象设置默认值
classid:0,
pageNum:1,
pageSize:9
}
onLoad((e)=>{
let{id=null,name=null}=e
queryParams.classid=id;
uni.setNavigationBarTitle({
title:name
});
getClassList();
})
const getClassList = async () => {
let res = await apiClassList(queryParams);
classList.value = res.data;
}
</script>
<style lang="scss" scoped>
.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>
这章就到这里了,加油加油!!!