Vue项目:List组件的引入
如果项目没有使用自动按需导入插件 unplugin-vue-components 则需要我们手动添加组件导入
// 1. 引入你需要的组件:
// 因为我们上面List组件中用到了Cell组件,所以在用到List组件的时候也需要引入进来。
// List as vanList的意思就是给List组件取别名:取别名后DOM中才能以<van-list>来用,
// 否则就只能写成<list> 为了与官方书写方式保持一致所以需要取个别名,Cell as vanCell也是一样的意思
import { List as vanList,Cell as vanCell } from 'vant';
// 2. 引入组件样式
import 'vant/lib/index.css';
下面是使用案列:
<template>
<div style="height: 70%;">
<!-- @load滚动条与底部距离小于 offset 时触发 -->
<list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad"
:immediate-check="false" :offset="15">
<cell v-for="item in filmsList" :key="item.filmId">
<img :src="item.poster" style="width: 100px;height: 120px; float:left;">
<div>{{ item.name }}</div>
</cell>
</list>
</div>
</template>
<script setup>
import axios from 'axios';
import { ref, onBeforeMount, onMounted, onBeforeUnmount, onUnmounted,inject } from "vue";
import { useRoute, useRouter } from 'vue-router'
// 1. 引入你需要的组件: 因为我们上面List组件中用到了Cell组件,所以在用到List组件的时候也需要引入进来。
import { List ,Cell } from 'vant';//无需手动导入,我们引入了自动导入的插件
// 2. 引入组件样式
import 'vant/lib/index.css';
const filmsList = ref([]);//这是存储电影的数组。获取到第一页的10条数据存储在这里,滑动页面底部获取第二页的数据再追加进来,直到获取到的所有数据全部添加进来。
// 非加载中,loading 为 false,此时会根据列表滚动位置判断是否触发 load 事件(列表内容不足一屏幕时,会直接触发):
// 加载中,loading 为 true,表示正在发送异步请求,此时不会触发 load 事件。
// 加载状态:初始值一定要给false :false表示允许触发@load加载数据,为true表示不允许触发@load事件加载数据。
// 场景举列:我们的列表第一次展示10条数据,我们往下滑动,滑动到最底部的时候,应该将第二页的数据加载出来,然后再滑动到最底部的时候,应该将第三页的数据加载出来,以此类推,直到数据库中的数据全部被加载完毕,就不允许再触发@load事件加载数据了
// loading初始值为false,表示可以触发@load事件加载数据,当触发@load将第一页的数据加载完毕后,会自动将 loading的值设置为true,设置为true后,就不能再触发@load事件加载数据了,但是我们还有还有第二页的数据需要加载,怎么办?
// 所以,我们需要判断与后台接口沟通,我这个请求接口中总数据条数是多少?假设是50条,那么我们就可以判断:每一页取10条数据,假设现在是滑动到了第三页了,也就是说我们从后台总共取到了30条数据,所以肯定还有20条数据没有取到,那就必须允许
// 我们继续滑动取数据,所以我们可以手动将 loading 值设为 false,直到50条数据获取完毕,就将loading的值设为true。(或者也可以通过是否能从接口中获取到数据判断是否为判断依据,将loading 设为 false还是true)
const loading = ref(false);
const finished = ref(false);//是否已加载完成,加载完成后不再触发 load 事件 :初始值一定要给false:表示所有数据都加载完毕。不允许再次触发@load事件。它与loading是有区别的(我上面的场景举列说loading为true的时候不允许触发@load事件,仅仅是做一个比较好理解的举列而已)
const route = useRoute(); //它是用来拿路由请求参数的
const router = useRouter();
const pageNum = ref(1);
onMounted(async () => {
//第一次加载电影列表数据
const result = await axios({
url: `https://m.maizuo.com/gateway?cityId=110100&pageNum=${pageNum.value}&pageSize=10&type=1&k=7069698`,
headers: {
'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.1","e":"16992764191480200349024257"}',
'X-Host': 'mall.film-ticket.film.list'
}
})
console.log(result.data.data.films);
filmsList.value = result.data.data.films //将请求到的电影列表赋值给filmsList
})
const onLoad = async () => {
console.log("滑动到底部了")
pageNum.value++; //当前页:
const result = await axios({
url: `https://m.maizuo.com/gateway?cityId=110100&pageNum=${pageNum.value}&pageSize=10&type=1&k=7069698`,
headers: {
'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.1","e":"16992764191480200349024257"}',
'X-Host': 'mall.film-ticket.film.list'
}
})
//说明没有获取到数据,也就是说所有的数据全部取完了,真正的到底了
if (result.data.data.films.length === 0) {
loading.value = true;
finished.value = true;
}
else {
loading.value = false; //表示允许再次触发@load事件
//filmsList中的数据应该是在原来的基础是追加:var a=[1,2,3] var b=[4,5] var c=[...a,...b] 此时c的值就是[1,2,3,4,5]
filmsList.value = [...filmsList.value, ...result.data.data.films] //将请求到的电影列表赋值给filmsList
}
}
//用于编程式导航点击跳转
const handelClick = (filmId, name) => {
// 第一种写法:字符串路径
router.push(`/FilmsDetail/${filmId}/${name}`); //router.push("/FilmsDetail/"+filmId+"/"+name) :将一个新的请求路径添加到我们的 history 栈中进行跳转
// 第二种写法:带有路径的对象
// router.push({ path: `/FilmsDetail/${filmId}/${name}` })
// 第三种写法:命名的路由,并加上参数,让路由建立url
// router.push({ name: "FilmsDetail", params: { myid: filmId, myname: name } })
// 第四种写法:带查询参数 例如:
// router.push({ path: '/FilmsDetail', query: { myid: filmId, myname: name } });
//VOA (Options API):中编程式导航的写法(以上四种写法都是一样的,只是this.$router与router.push不同)
//this.$router.push("/FilmsDetail") //将一个新的请求路径添加到我们的 history 栈中进行跳转
}
</script>
<style scoped>
li {
padding: 10px;
}
:deep(.van-cell__value){
text-align: left;
}
:deep(.van-list__finished-text){
height: 100px; /*设置高度,避免被tabbar栏遮盖。数据加载完毕后在底部提示“没有更多数据了”*/
}
</style>