赞
踩
Vue基础篇一:编写第一个Vue程序
Vue基础篇二:Vue组件的核心概念
Vue基础篇三:Vue的计算属性与侦听器
Vue基础篇四:Vue的生命周期(秒杀案例实战)
Vue基础篇五:Vue的指令
Vue基础篇六:Vue使用JSX进行动态渲染
Vue提高篇一:使用Vuex进行状态管理
Vue提高篇二:使用vue-router实现静态路由
Vue提高篇三:使用vue-router实现动态路由
Vue提高篇四:使用Element UI组件库
Vue提高篇五:使用Jest进行单元测试
Vue提高篇六: 使用Vetur+ESLint+Prettier插件提升开发效率
Vue实战篇一: 使用Vue搭建注册登录界面
Vue实战篇二: 实现邮件验证码发送
Vue实战篇三:实现用户注册
Vue实战篇四:创建多步骤表单
Vue实战篇五:实现文件上传
Vue实战篇六:表格渲染动态数据
Vue实战篇七:表单校验
Vue实战篇八:实现弹出对话框进行交互
Vue实战篇九:使用省市区级联选择插件
Vue实战篇十:响应式布局
Vue实战篇十一:父组件获取子组件数据的常规方法
Vue实战篇十二:多项选择器的实际运用
Vue实战篇十三:实战分页组件
Vue实战篇十四:前端excel组件实现数据导入
Vue实战篇十五:表格数据多选在实际项目中的技巧
Vue实战篇十六:导航菜单
Vue实战篇十七:用树型组件实现一个知识目录
Vue实战篇十八:搭建一个知识库框架
Vue实战篇十九:使用printjs打印表单
Vue实战篇二十:自定义表格合计
Vue实战篇二十一:实战Prop的双向绑定
Vue实战篇二十二:生成二维码
Vue实战篇二十三:卡片风格与列表风格的切换
Vue实战篇二十四:分页显示
Vue实战篇二十五:使用ECharts绘制疫情折线图
Vue实战篇二十六:创建动态仪表盘
Vue实战篇二十七:实现走马灯效果的商品轮播图
Vue实战篇二十八:实现一个手机版的购物车
Vue实战篇二十九:模拟一个简易留言板
Vue项目实战篇一:实现一个完整的留言板(带前后端源码下载)
Vue实战篇三十:实现一个简易版的头条新闻
Vue实战篇三十一:实现一个改进版的头条新闻
<template> <ul class="infinite-list" v-infinite-scroll="load" style="overflow:auto"> <li v-for="i in count" class="infinite-list-item">{{ i }}</li> </ul> </template> <script> export default { data () { return { count: 0 } }, methods: { load () { this.count += 2 } } } </script>
methods: { // 自动加载方法,获取下一页新闻 load() { // 从状态管理器中获取当前新闻列表是第几页 let start = this.$store.state.news.start start++ // 接口限制最大不超过400页 if (start < 400) { this.getNews(this.$store.state.news.channel, start, this.$store.state.news.num).then(res => { console.log('loading more news', res) if (res && res.data.result) { const newsData = this.$store.state.news.newsData newsData.push.apply(newsData, res.data.result.list) this.$store.commit('SET_NEWS', newsData) this.$store.commit('SET_START', start) } }) } }, ... }
// 用于存储各种变量 const news = { state: { // 频道 channel: '', // 起始位置 start: 0, // 一次向接口接取新闻的条数 num: 10, // 存放拉取下来的新闻 newsData: [], // 当前正在查看的新闻 newsIndex: -1, // 是否加载状态 loading: false }, mutations: { SET_CHANNEL: (state, channel) => { state.channel = channel }, SET_START: (state, start) => { state.start = start }, SET_NUM: (state, num) => { state.num = num }, SET_NEWS: (state, news) => { state.newsData = news }, SET_NEWS_INDEX: (state, newsIndex) => { state.newsIndex = newsIndex }, SET_LOADING: (state, loading) => { state.loading = loading } }, actions: { setChannel({ commit }, channel) { return new Promise(resolve => { commit('SET_CHANNEL', channel) }) }, setStart({ commit }, start) { return new Promise(resolve => { commit('SET_START', start) }) }, setNum({ commit }, num) { return new Promise(resolve => { commit('SET_NUM', num) }) }, setNews({ commit }, news) { return new Promise(resolve => { commit('SET_NEWS', news) }) }, setNewsIndex({ commit }, newsIndex) { return new Promise(resolve => { commit('SET_NEWS_INDEX', newsIndex) }) }, setLoading({ commit }, loading) { return new Promise(resolve => { commit('SET_LOADING', loading) }) } } } export default news
1、在新闻列表中引入无限滚动加载功能,并关联自动加载方法
2、在底部放入加载条,显示正在努力加载
3、向接口获取数据成功后,重新渲染新闻列表
<template> <div> <!-- 标题栏 --> <div class="header"> <span /> <span>新闻</span> <span /> </div> <channel /> <div ref="container" class="nav-content"> <!-- 在新闻列表中引入无限滚动加载功能 --> <div v-if="loading == false" v-infinite-scroll="load" class="news-list"> <div v-for="(item, index) in newData" :key="index" class="section" @click="toNews(index)" > <div class="news"> <div class="news-left"> <img :src="item.pic" alt=""> </div> <div class="news-right"> <div class="newsTitle">{{ item.title }}</div> <div class="newsMessage"> <span>{{ item.time }}</span> <span>{{ item.src }}</span> </div> </div> </div> </div> <!-- 在底部放入加载条 --> <div class="loading-more">正在努力加载</div> </div> <el-main v-else v-loading="loading" class="load" element-loading-background="rgba(0,0,0,0)" element-loading-text="正在加载中" /> </div> </div> </template> <script> import Channel from './channel' import { getNewList } from '@/api/news' export default { name: 'Home', components: { Channel }, data() { return { } }, computed: { newData() { return this.$store.state.news.newsData }, loading() { return this.$store.state.news.loading } }, methods: { load() { // 获取下一页新闻 console.log('已到达底部,自动触发加载方法') let start = this.$store.state.news.start start++ if (start < 400) { this.getNews(this.$store.state.news.channel, start, this.$store.state.news.num).then(res => { console.log('加载下一页新闻列表', res) if (res && res.data.result) { const newsData = this.$store.state.news.newsData newsData.push.apply(newsData, res.data.result.list) this.$store.commit('SET_NEWS', newsData) this.$store.commit('SET_START', start) } }) } }, // 异步获取新闻 async getNews(channel, start, num) { const data = await getNewList(channel, start, num) return data }, // 打开新闻阅读 toNews(index) { this.$store.commit('SET_NEWS_INDEX', index) this.$router.push('/news') } } } </script> <style lang="scss" scoped> .header { width: 100%; height: 1.2rem; background-color: #d43d3d; display: flex; justify-content: space-between; align-items: center; color: #fff; font-size: 20px; font-weight: 700; letter-spacing: 3px; z-index: 99; position: fixed; top: 0; img { width: 0.67rem; height: 0.67rem; cursor: pointer; } } .nav-content { margin-top: 2.4rem; } .news-list { position: relative; height:calc(100vh - 2.4rem - 49px); overflow-y:auto; width: 100%; } .section { width: 100%; height: 2.5rem; border-bottom: 1px solid #ccc; } .news { height: 2.25rem; box-sizing: border-box; margin: 10px 10px; display: flex; } .news-left { height: 100%; width: 2.8rem; display: inline-block; } .news-left img { width: 100%; height: 100%; } .news-right { flex: 1; padding-left: 10px; } .newsTitle { width: 100%; height: 62%; color: #404040; font-size: 17px; overflow: hidden; } .newsMessage { width: 100%; height: 38%; display: flex; align-items: flex-end; color: #888; justify-content: space-between; } .load { width: 100%; height: 100%; overflow: hidden; } .loading-more { margin-top: 5px; width: 100%; height: 20px; text-align: center; } </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。