Vue 实现腾讯新闻案例

父组件:

<template>
	<div>
		
		<div class="news-top">
			
			<div style="background-color: white;">
				<input type="text"
						@keydown.enter="search" 
						v-model="kw"
						@focus="handleFocus"
						@blur="handleBlur"
						@keydown.down="down"
						@keydown.up="up">
						
				<button @click="search">搜索</button>
			</div>
			
			<div class="search-list" v-show="isSearch">
				<div v-for="(item,index) in searchRecord"
					:class="{'active':activeIndex==index}">
					{{item}}
				</div>
			</div>
			
		</div>
		
		
		<div style="margin-top: 30px;">
			
			<div v-for="(item,index) in newsList">
				
				<NewsCard1 
					v-if="item.imageUrls != null && item.imageUrls.length >= 3"
					:title="item.title"
					:imageUrls="item.imageUrls"
					:publishDate="item.publishDate"
					:posterScreenName="item.posterScreenName">
				</NewsCard1>
				
				<NewsCard2 
					v-if="item.imageUrls != null && item.imageUrls.length > 0 && item.imageUrls.length < 3"
					:title="item.title"
					:imageUrls="item.imageUrls"
					:publishDate="item.publishDate"
					:posterScreenName="item.posterScreenName">
				</NewsCard2>
				
			</div>
			
			<p style="text-align: center;">
				<button v-show="isShow" @click="getMore">加载更多</button>
				<span v-show="isHide">{{load}}</span>
			</p>
			
		</div>
		
		
	</div>
</template>

<script>
	import NewsCard1 from '../components/NewsCard1.vue'
	import NewsCard2 from '../components/NewsCard2.vue'
	export default{
		components:{
			NewsCard1,
			NewsCard2
		},
		data(){
			return{
				kw:'', //搜索关键词
				newsList:[],
				page:1, //页数
				isShow:false, //显示或隐藏'加载更多'
				isHide:false, //显示或隐藏'正在加载...'
				load:'正在加载...',
				searchRecord:[], //搜索记录
				isSearch:false, //显示或隐藏'搜索记录'
				activeIndex:-1 //被选中的记录的下标
			}
		},
		created() { //初始化保存
			let list = localStorage.searchRecord
			if(list){
				this.searchRecord = JSON.parse(list)
			}
		},
		watch:{
			kw(val){
				if(val.length == 0){
					this.activeIndex = -1
				}
			}
		},
		methods:{
			down(){
				if(this.activeIndex == this.searchRecord.length-1){
					return
				}
				this.activeIndex++
			},
			up(){
				if(this.activeIndex<=0){
					return
				}
				this.activeIndex--
			},
			handleFocus(){ //获取焦点时
				if(this.searchRecord != ''){
					this.isSearch = true
				}else{
					this.isSearch = false
				}
			},
			handleBlur(){ //失去焦点时
				this.isSearch = false
				this.activeIndex = -1
			},
			search(){ //搜索
				if(this.activeIndex>-1){
					this.kw = this.searchRecord[this.activeIndex]
				}
				this.isSearch = false
			
				this.isHide = true
				this.instance()
				
				if(!this.searchRecord.includes(this.kw.trim())){ //判断重复搜索记录
					this.searchRecord.push(this.kw)
					this.save()
				}
				
			},
			instance(){ //封装axios
				this.$axios.get('http://api.kudesoft.cn/news/list',{
					params:{
						kw:this.kw,
						page:this.page
					}
				}).then(res=>{
					console.log(res.data.result.data)
					let list = res.data.result.data
					
					if(list == undefined){
						this.load = '没有更多数据了!'
						return
					}else{
						this.load = '正在加载...'
					}
					
					if(this.page<=1){
						this.newsList = list
						this.isShow = true
						this.isHide = false
					}else{
						this.newsList = [...this.newsList,...list]
						this.isShow = true
						this.isHide = false
					}
					
				})
			},
			getMore(){ //加载更多
				this.page++
				this.isShow = false
				this.isHide = true
				this.instance()
			},
			save(){ //本地保存
				localStorage.searchRecord = JSON.stringify(this.searchRecord)
			}
		}
	}
</script>

<style scoped>
	.search-list{
		width: 163px;
		border-bottom: 1px solid;
		border-left: 1px solid;
		border-right: 1px solid;
		background-color: white;
		margin-top: -1px;
	}
	.active{
		background-color: lightgray;
	}
	.news-top{
		position: fixed;
		top: 0;
		left: 0;
	}
</style>

子组件:

<template>
	<div class="news-dbox">
		
		<div>
			{{title}}
		</div>
		
		<div class="news-img">
			<img v-for="(item,index) in imageUrls" :src="item" v-show="index<3" width="115px" height="100px">
		</div>
		
		<div class="news-bot">
			<span>{{posterScreenName}}</span>
			<span>评论</span>
			<span>{{publishDate | TimeFilter}}</span>
		</div>
		
	</div>
</template>

<script>
	export default{
		props:{
			title:String, //标题
			imageUrls:Array, //图片
			publishDate:Number, //发布日期时间戳
			posterScreenName:String //发布者名称
		},
		filters: {
			TimeFilter(time) {
				let oldDate = new Date(time*1000)
				let newDate = new Date()
				var dayNum = "";
				var getTime = (newDate.getTime() - oldDate.getTime())/ 1000;
				
				if (getTime < 60 * 5) {
					dayNum = "刚刚";
				} else if (getTime >= 60 * 5 && getTime < 60 * 60) {
					dayNum = parseInt(getTime / 60) + "分钟前";
				} else if (getTime >= 3600 && getTime < 3600 * 24) {
					dayNum = parseInt(getTime / 3600) + "小时前";
				} else if (getTime >= 3600 * 24 && getTime < 3600 * 24 * 30) {
					dayNum = parseInt(getTime / 3600 / 24) + "天前";
				} else if (getTime >= 3600 * 24 * 30 && getTime < 3600 * 24 * 30 * 12) {
					dayNum = parseInt(getTime / 3600 / 24 / 30) + "个月前";
				} else if (time >= 3600 * 24 * 30 * 12) {
					dayNum = parseInt(getTime / 3600 / 24 / 30 / 12) + "年前";
				}
				
				return dayNum;
			}
		}
	}
</script>

<style scoped="scoped">
	.news-dbox{
		width: 100%;
		height: 175px;
		display: flex;
		flex-direction: column;
		justify-content: space-around;
		margin: 10px 0;
		border-bottom: 1px solid lightgray;
	}
	.news-img{
		display: flex;
		justify-content: space-around;
	}
	.news-img img{
		border-radius: 3px;
	}
	.news-bot span{
		margin: 0 5px;
	}
</style>

子组件:

<template>
	<div class="news-dbox">
		
		<div style="display: flex; flex-direction: column; justify-content: space-between;">
			<div>{{title}}</div>
			
			<div class="news-bot">
				<span>{{posterScreenName}}</span>
				<span>评论</span>
				<span>{{publishDate | TimeFilter}}</span>
			</div>
		</div>
		
		<div class="news-img">
			<img :src="imageUrls[0]" width="130px" height="110px">
		</div>
		
		
	</div>
</template>

<script>
	export default{
		props:{
			title:String, //标题
			imageUrls:Array, //图片
			publishDate:Number, //发布日期时间戳
			posterScreenName:String //发布者名称
		},
		filters: {
			TimeFilter(time) {
				let oldDate = new Date(time*1000)
				let newDate = new Date()
				var dayNum = "";
				var getTime = (newDate.getTime() - oldDate.getTime())/ 1000;
				
				if (getTime < 60 * 5) {
					dayNum = "刚刚";
				} else if (getTime >= 60 * 5 && getTime < 60 * 60) {
					dayNum = parseInt(getTime / 60) + "分钟前";
				} else if (getTime >= 3600 && getTime < 3600 * 24) {
					dayNum = parseInt(getTime / 3600) + "小时前";
				} else if (getTime >= 3600 * 24 && getTime < 3600 * 24 * 30) {
					dayNum = parseInt(getTime / 3600 / 24) + "天前";
				} else if (getTime >= 3600 * 24 * 30 && getTime < 3600 * 24 * 30 * 12) {
					dayNum = parseInt(getTime / 3600 / 24 / 30) + "个月前";
				} else if (time >= 3600 * 24 * 30 * 12) {
					dayNum = parseInt(getTime / 3600 / 24 / 30 / 12) + "年前";
				}
				
				return dayNum;
			}
		}
	}
</script>

<style scoped="scoped">
	.news-dbox{
		width: 100%;
		height: 120px;
		display: flex;
		justify-content: space-around;
		margin: 10px 0;
		border-bottom: 1px solid lightgray;
	}
	
	.news-img img{
		border-radius: 3px;
	}
	.news-bot span{
		margin: 0 5px;
	}
</style>

你可能感兴趣的:(vue.js)