青年帮新闻完整版(咸虾米)笔记

        1、新建uniapp项目

78b7f64913aa4ce9aae58b231f666b6d.png2、新建界面(新闻界面、个人中心界面)

bd82f66ef08c4ae9bd76304bc1dd78d8.png

 3、配置tabBar9659b275d9e54ccd91b97cddc47409f7.png

 显示界面如下:

48c52c1ec4ab43879ce128bb1ad2ec66.png

 在图标素材网站找首页和个人的矢量图

iconfont-阿里巴巴矢量图标库

步骤:

 (1)选择喜欢的图标后,点击下载,然后同样的图标下载两个,一个是选中前的图片,一个是选中后的图片

b699d9d12f094bbeae23873d0aeb94c2.png

 (2)将下载的几张图片放在一个文件夹中,再将文件夹放至项目的static里面

57f1de4139ea496bab423600b60779f3.png

 (3)运用下载的图标28f00157d1ff4719b4b0f7b52fbaa29c.png设置后页面显示如下:

 

ac935f0d9c354ee28df2279db5b1aa44.png

 (4)设置导航栏背景颜色,导航栏标题颜色,设置导航栏标题文本

b883ed2f8d88421bbe66b30cd758b3d1.png

 4、scroll-view实现横向滚动条样式

<template>
	<view class="home">
		<view class="scrollNav">
			<scroll-view scroll-x class="navscroll">
				<view class="item">国内</view>
				<view class="item">国内</view>
				<view class="item">国内</view>
				<view class="item">国内</view>
				<view class="item">国内</view>
				<view class="item">国内</view>
				<view class="item">国内</view>
				<view class="item">国内</view>
				<view class="item">国内</view>
				<view class="item">国内</view>
				<view class="item">国内</view>
				<view class="item">国内</view>
				<view class="item">国内</view>
			</scroll-view>
		</view>
		<view class="content">
			<view class="row">
				每一行新闻显示的内容
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: 'Hello'
			}
		},
		onLoad() {

		},
		methods: {

		}
	}
</script>

<style scoped lang="scss">
	.navscroll {
		display: flex;
		height: 100rpx;
		background-color: #F1F3F5;
		// nowarp:使用了该属性后,文本将会在不换行的情况下一直显示,直到文本结束或者遇到换行符为止。
		white-space: nowrap;

		// 去掉国内字下拉条
		/deep/ ::-webkit-scrollbar {
			width: 4px !important;
			height: 1px !important;
			overflow: auto !important;
			background: transparent !important;
			-webkit-appearance: auto !important;
			display: block;
		}

		.item {
			display: inline-block;
			line-height: 100rpx;
			padding: 0 28rpx;
			font-size: 38rpx;
		}
	}
</style>

 5、定义components组件(里面设置每一条新闻显示的样式)

<template>
	<view class="newbox">
		<view class="pic">
			<image src="../../static/qingnianbang/壁纸2.jpg" mode="aspectFit"></image>
		</view>

		<view class="text">
			<view class="title">
				默认新闻标题默认新闻标题默认新闻标题默认新闻标题默认新闻标题默认新闻标题默认新闻标题
			</view>
			<view class="info">
				<text>作者名称</text>
				<text>998浏览</text>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		name: "newsbox",
		data() {
			return {

			};
		}
	}
</script>

<style lang="scss">
	.newbox {
		display: flex;

		image {
			width: 240rpx;
			height: 200rpx;
		}

		.text {
			flex: 1;
			padding: 5rpx 20rpx;
			display: flex;
			flex-direction: column;
			justify-content: space-between;

			.title {
				font-size: 38rpx;
				color: #333;
				// 设置溢出部分隐藏;
				overflow: hidden;
				// 设置文本溢出时以省略号显示;
				text-overflow: ellipsis;
				// 设置显示为块级元素;
				display: -webkit-box;
				// 设置最多显示2行文本 
				-webkit-line-clamp: 2;
				// 设置文本溢出时以省略号显示最后一行
				text-overflow: -o-ellipsis-lastline;
				// 设置文本排列方式为垂直
				-webkit-box-orient: vertical;
			}

			.info {
				font-size: 26rpx;
				color: #999;

				text {
					padding-right: 30rpx;

				}
			}
		}
	}
</style>

6、布局个人中心页面定义组件默认值

   个人中心页面样式

<template>
	<view class="user">
		<view class="top">
			<image src="../../static/qingnianbang/历史记录.png" mode=""></image>
			<text>浏览历史</text>
		</view>
		<view class="content">
			<view class="row" v-for="item in 10">
				<newsbox></newsbox>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		methods: {
			
		}
	}
</script>

<style scoped lang="scss">
.top{
	display: flex;
	flex-direction: column;
	background-color: #F7F7F7;
	image{
		margin: 50rpx auto 30rpx auto;
		height: 150rpx;
		width: 150rpx;
	}
	text{
		// padding: 50rpx;
		text-align: center;
		font-size: 38rpx;
		padding-bottom: 50rpx;
	}
}
.content{
	margin-top: 40rpx;
}
</style>

组件默认值 

<template>
	<view class="newbox">
		<view class="pic">
			<image :src="item.picurl" mode="aspectFit"></image>
		</view>
		<view class="text">
			<view class="title">
				{{ item.title }}
			</view>
			<view class="info">
				<text>{{ item.author }}</text>
				<text class="a">{{ item.hits }}浏览</text>
			</view>
		</view>
	</view>
</template>
<script>
	export default {
		name: "newsbox",
		props: {
			item: {
				type: Object,
				default () {
					return {
						title: "组件内的默认标题",
						author: "张三",
						hits: "668",
						picurl: '../../static/qingnianbang/壁纸2.jpg'
					}
				}
			}
		},
		data() {
			return {

			};
		}
	}
</script>

<style lang="scss">
	.newbox {
		display: flex;

		image {
			width: 240rpx;
			height: 200rpx;
		}

		.text {
			flex: 1;
			padding: 5rpx 20rpx;
			display: flex;
			flex-direction: column;
			justify-content: space-between;

			.title {
				font-size: 38rpx;
				color: #333;
				// 设置溢出部分隐藏;
				overflow: hidden;
				// 设置文本溢出时以省略号显示;
				text-overflow: ellipsis;
				// 设置显示为块级元素;
				display: -webkit-box;
				// 设置最多显示2行文本 
				-webkit-line-clamp: 2;
				// 设置文本溢出时以省略号显示最后一行
				text-overflow: -o-ellipsis-lastline;
				// 设置文本排列方式为垂直
				-webkit-box-orient: vertical;
			}

			.info {
				font-size: 26rpx;
				color: #999;

				text {
					padding-right: 30rpx;

				}

				.a {
					padding: 30rpx;
				}
			}
		}
	}
</style>

实现组件化的差异

    在newsbox组件中,新增一个名为info的类盒子。实现逻辑是判断传递给组件的值中是否包含item.lootime的值。如果不包含,就显示首页盒子的内容;如果包含,就只显示浏览时间的盒子。通过这种方式,可以根据传递的值来实现组件的显示样式差异化。

 f5665706267a40bbbd97a85049d4a8c8.png

 7、uniapp内置css变量window-top的吸顶效果

 //使用CSS变量(–window-top)来指定元素的顶部位置
top: var(--window-top);
// 将导航栏国内那一行固定在上方
//(将元素的定位方式设置为固定定位。元素的位置相对于视窗固定,不会随页面滚动而改变)
position: fixed;
left: 0;
z-index: 10;

8、导航栏点击高亮

    通过设置一个变量navindex为0,可以在导航栏的选项设置点击事件,并将点击的下标传递给navindex变量。然后,可以创建一个名为active的CSS类,用于设置选中项的颜色。通过使用三元运算符判断,如果下标等于navindex变量的值,则应用active颜色类,就可以实现点击高亮的效果。

<template>
	<view class="home">
		<view class="scrollNav">
			<scroll-view scroll-x class="navscroll">
				<view class="item" v-for="(item,index) in 10" @click="clickNav(index)"
					:class="index=== navindex?'ative':''" :key="item.id">国内</view>
			</scroll-view>
		</view>
		<view class="content">
			<view class="row" v-for="item in 10">
				<newsbox></newsbox>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: 'Hello',
				navindex: 0
			}
		},
		onLoad() {

		},
		methods: {
			clickNav(index) {
				this.navindex = index
			}
		}
	}
</script>

<style scoped lang="scss">
	.navscroll {
		display: flex;
		height: 100rpx;
		background-color: #F1F3F5;
		// nowarp:使用了该属性后,文本将会在不换行的情况下一直显示,直到文本结束或者遇到换行符为止。
		white-space: nowrap;
		top: var(--window-top);
		// 将导航栏国内那一行固定在上方
		position: fixed;
		left: 0;
		z-index: 10;

		//自定义滚动条,使滑动的时候滚动条不会显示在页面
		/deep/ ::-webkit-scrollbar {
			width: 4px !important;
			height: 1px !important;
			overflow: auto !important;
			background: transparent !important;
			-webkit-appearance: auto !important;
			display: block;
		}

		.item {
			display: inline-block;
			line-height: 100rpx;
			padding: 0 28rpx;
			font-size: 38rpx;

		}
	}

	.content {
		margin-top: 120rpx;

		.row {
			border-bottom: 1px dashed #efefef;
		}
	}

	.ative {
		color: #3DD680;
	}
</style>

 9、页面跳转与详情页布局

         设置单击事件b8ff0db0cf0a4179a02112e636dd12c5.png跳转到详情页(设置详情页地址)在index和user里面都要设置

2af10aaba14f43baa48651ea6aa501a9.png

 创建详情页面,页面样式

 

<template>
	<view class="detail">
		<view class="title">
			文章标题
		</view>
		<view class="info">
			<view class="author">
				编辑:张三
			</view>
			<view class="time">
				发布时间:2022-12-12 15:30:00
			</view>
		</view>
		<view class="content">
			内容部分
		</view>
		<view class="description">
			声明:本站的内容均采集与腾讯新闻,如果侵权请联系管理(51389257@qq.com)进行删除,本站进行了内容采集不代表本站及作者观点,若有侵权请及时联系管理员,谢谢您的支持
			<view>
			</view>
</template>

<script>
	export default {
		data() {
			return {

			};
		},

	}
</script>

<style lang="scss" scoped>
	.detail {
		.title {
			margin: 40rpx 20rpx;
			font-size: 50rpx;
		}

		.info {
			background-color: #F6F6F6;
			display: flex;
			justify-content: space-between;
			margin: 20rpx 25rpx 40rpx 25rpx;
			padding: 25rpx;
			color: #8E898A;
		}

		.content {
			margin: 0 20rpx;
			padding-bottom: 50rpx;
		}

		.description {
			background: #FEF0F0;
			font-size: 26rpx;
			padding: 20rpx;
			color: #F89898;
			line-height: 1.8em;
		}
	}
</style>

 

 10、uni.request获取网络请求渲染到页面中

 三个接口地址:

获取新闻详情
url: "https://ku.qingnian8.com/dataApi/news/detail.php",
获取新闻列表
url: "https://ku.qingnian8.com/dataApi/news/newslist.php",
获取新闻栏目
url: "https://ku.qingnian8.com/dataApi/news/navlist.php",

 拿到新闻栏目数据

31f2caaba4314f6c9e46b6d0f408d02f.png

可以看到区分新闻栏目是根据id进行划分的,并且数据类型是数组

f2e062b442e04cc6acb24357bc40af94.png   创建一个名为navArr的数组,并将获取到的数据赋值给navArr。然后,需要将页面中的栏目遍历的数量10改为使用navArr中的数据进行渲染,实现页面内容的动态更新。

 

a4eacedca0294dd2b749da6b7029f071.png

54d26fa3089d48a7841ba97f361504ec.png 28c95a9cfe8b47759f5a25a19ad9e055.png

 获取新闻列表(渲染步骤与前面一致)

c3093c05a22f4cee941db3b542bdf1c7.png

e9153450c7fe4c0d81891b80cbf4250c.png

70a129d6b8784040a34044b108de9746.png

 

1dd0a55ba7e44e099cd1a37ca2ba750d.png

 将遍历后的数据传给组件

  这里的 :item 是子组件定义的 prop(属性),用于接收从父组件传递过来的数据。而 "item" 是父组件中要传递的具体数据。

328c202b59d8444989b853cf09dc3a51.png

 到这里实现了综合页面的渲染,这个接口需要根据cid=id(id是导航栏目里面的id)传值进行判断,才可以实现新闻栏目分类的效果,cid 是一个关键的参数,用于从后端 API 获取特定分类的新闻数据。当点击导航栏中的某个新闻分类时,cid 会被传递给后端接口,以获取该分类下的新闻列表。也就是cid=50则显示国内的新闻,cid=51则显示国际新闻...

参数名

介绍是否必填
cid栏目id必填
num获取的条数非必填
page页码非必填

 

返回值

参数名介绍
idid唯一标识
title标题

ca659ac56c7b4bee805547edec30d68f.png 11、点击导航跳转不同的新闻页面

      因为接口需要id所以我们需要先拿到id,以便于赋值给cid

1eb28368eab844699810dedc68385353.png

787db1886c5b442ca96567fe8f76c1c4.png

cebffc76333f4b769e9bd5585110fa9b.png

   在新闻栏目点击事件里面的方法再次调用网络请求的方法,将拿到的新闻栏目的id将id通过网络请求发送给获取网络请求数据的方法,在被调用的方法中接收被点的id,然后在默认的情况下方法中的id=50是指id的默认值为50,50对应的就是国内的新闻id,也就是默认显示国内新闻。如果点击之后进行调用之后就是将id赋值给cid,就显示传入id对应的新闻界面,以达到切换新闻栏目的分类效果。

 

7f462e72768842fbae02fd541d3903a1.png

f2ec674481bb41359d415230a6f2056f.png d33134c93b69415e8637fad9450b56da.png

如果当前栏目没有数据,就应该显示没有数据的image

2c9d4d86b9cf4609bcb40ab1bd303f1c.png3cf15b00e6ce4f62a362ce04185b8dd3.png

12、onReachBottom触底加载更多翻页效果(onReachBottom页面滚动到底部的事件(不是scroll-view滚到底),常用于下一页数据。)

        在我们拿到新闻列表的接口中,page是根据页码来显示展示的数据c6fc9cf314204e4794504f99c0a970cc.png

在网络请求中增加一个名为"page"的参数,展示当前的页面数。设置一个全局变量"currentPage",将初始值设为自己想要的页面,比如1。当触发底事件时,通过改变的值来更新"page"的值,即"currentPae++”。再onReachBottom()方法里在调用一次网络请求,获取新一组的数据。这样就可以实现翻功能,获取到新的数据展示。但是这样的话就不能翻回翻页前的数据,所以我们需要加载更多,将原有的数据拼接到新的数据。

f2453f83dd19445e8eeb934def674112.png30a6991abcc94da698c5d0b10e2f02eb.png

 但是以上操作可能导致点击新的新闻栏目分组时候page还是显示的加载后的page页面的内容,所以我们需要再点击新闻栏目分组时,重新将page的值赋值为1。赋值为1后会将新点击的栏目数据从新追加到数据里面,所以我们还需要将原有数组里面的内容清空。

bab092f788cb46048de57fe755730867.png

 13、优化细节增加loading加载样式

设置全局变量loading默认值赋值为0(不显示内容),1=加载中,2=没有更多内容了

dd7e4a6ea39c4ae69ee4f44fcb70b720.png 判断什么时候需要显示什么 

在触底的时候我们获取网络请求的时候需要添加数据加载中,所以在触底事件中,页面++后,将loading的状态设置为1,也就是数据加载中,同时,再切换导航的时候我们需要将loading重新赋值为默认值0。再获取网络请求的方法中做判断,如果我们获取的数据的长度为0,就将loading的值改为2,也就是没有更多内容了。

 7a11700db58a4d4c87486d5426d823b3.png

 如果loading状态已经变成2了,就不用再去翻页和请求了,所以在这里做一个判断。然后页面没有数据也会显示没有更多内容了 我们直接在loading这个盒子做一个判断,如果newarr数组有数据才显示就可以了。

86f0552c188b4c2ab74505b2c160577d.png

 14、获取参数跳转到不同的详情页

    获取新闻详情需要的参数

参数名介绍是否必填
cid栏目id必填
id当前新闻id必填

返回值

参数名介绍

id

id唯一标识符
title标题
picurl缩略图地址
posttime发布时间
classid栏目id
author作者
hits浏览量

页面跳转的时候将item传过去,item这个对象里面就包含了需要的参数

1c3883b1d55740da9b5b19e2a33edf5d.png

 在方法中接收

80aa8404048a4949b993ce1c44a96eb7.png

 

 console.log打印item就可以在浏览器控制台看到打开详情页后,可以看到item的数据已经传递过去

5933530f44854730987d3676f492224f.png这个接口需要接收两个参数:cid和id。可以通过uni.navigateTo方法中的url将这两个参数传递给目标页面。在接收参数的页面,使用onLoad生命周期函数来接收参数,并将其渲染到页面上

         cid=栏目id 所以在控制台的数据中可以看到我们需要传递的数据名为classid,id=当前新闻的id。

cf2ab234bc4f435784574228a68be427.png

 63c1081d4600482d94c5b3f9572372a9.png

创建一个全局变量,将onload函数里接收到的数据赋值给创建的全局变量。

5357e50621a1418f828c83e629a1e19f.png

 在获取新闻详情网络请求中,将onload获取到的参数放在data里面,就可以拿到新闻详情的数据,在全局变量中创建一个对象,将新闻详情的数据赋值给这个定义的对象,就通过调用对象里面的数据在页面进行渲染。e510227587b7449698493aa0a4cb3ed1.png

使用rich-text解析富文本 (rich-text标签是小程序(微信小程序和支付宝小程序)中的一个组件,它的作用是用于渲染富文本内容。富文本内容指的是带有多种样式(如字体、颜色、大小等)和标签(如链接、图片等)的文本内容。)

837fab5cbc554195af7323f9414fcdf3.png

<rich-text :nodes="detail.content"></rich-text>这段代码的作用是在小程序中使用rich-text组件来渲染富文本内容。具体来说,detail.content是一个存储富文本内容的数据字段,它可以是一个字符串,也可以是一个包含富文本标签和样式的数组。这个数据字段可以通过绑定语法(:nodes="detail.content")传递给rich-text组件的nodes属性。nodes属性接受一个数组作为参数,数组中的每个元素表示一个富文本节点。富文本节点可以是一个文本节点(纯文本内容),也可以是一个节点对象,其中包含了富文本标签和样式。组件会根据传入的nodes数组解析并渲染出对应的富文本内容。

 15、解决小程序图片宽度超出页面显示范围

 1876eefb385d40bd85421fc673a1b0eb.png

   将字符串中的所有"<img"替换为’<img style=“max-width:100%”‘。这个替换操作是通过使用正则表达式来匹配字符串中的"<img",并用新的字符串’<img style=“max-width:100%”'来替换它们。这样做的目的是给所有的图片元素添加一个样式,使其最大宽度限制为100%。就可以解决图片宽度超出页面显示范围。

16、转换时间戳

 新建目录utils,创建js文件。abeaca905b2445b9b11b96f751770f1a.png

将以下内容赋值在工具类中 

//时间间隔函数
export function timeInterval(timesData) {
  //如果时间格式是正确的,那下面这一步转化时间格式就可以不用了
  var dateBegin = timesData;//将-转化为/,使用new Date    
  var dateEnd = new Date();//获取当前时间   
  var dateDiff = Math.abs( dateEnd.getTime() - dateBegin );  //时间差的毫秒数
  var yearDiff = Math.floor(dateDiff / (24 * 3600 * 1000*365));
  var dayDiff = Math.floor(dateDiff / (24 * 3600 * 1000));  //计算出相差天数
  var leave1 = dateDiff % (24 * 3600 * 1000)    //计算天数后剩余的毫秒数
  var hours = Math.floor(leave1 / (3600 * 1000))//计算出小时数
  //计算相差分钟数
  var leave2 = leave1 % (3600 * 1000)    //计算小时数后剩余的毫秒数
  var minutes = Math.floor(leave2 / (60 * 1000))//计算相差分钟数
  //计算相差秒数
  var leave3 = leave2 % (60 * 1000)      //计算分钟数后剩余的毫秒数
  var seconds = Math.round(leave3 / 1000);
  var timesString = '';
  if (yearDiff!=0){
    timesString = yearDiff + '年前';
  } else if (yearDiff == 0   && dayDiff != 0) {
    timesString = dayDiff + '天前';
  } else if (dayDiff == 0 && hours != 0) {
    timesString = hours + '小时前';
  } else if (hours == 0 && minutes != 0) {      
    timesString = minutes + '分钟前';      
  } else if (minutes == 0 && seconds<60){ 
    timesString = '刚刚'; 
  } 
  return timesString 
}
 
 
// 日期格式化
export function parseTime(time, pattern) {
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
      time = parseInt(time)
    } else if (typeof time === 'string') {
      time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
    }
    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

 引入

809d3ab8840f4a7e8fafef5ce8cde5a0.png

 在网络请求中使用,将posttime值通过转换函数转换后重新赋值给posttime,就可以完成时间戳的转换。

50ca26b64ed34a989decde9d1fabadc6.png

 设置当前页面的动态标题(uni.setNavigationBarTitle(object)函数)

edeea11b1798422e90674a565d9eb860.png17、StorageSync读写缓存渲染浏览记录页面

网络请求里获取获取到数据之后,调用savaHistory函数,在savaHistory函数定义缓存数据方法。(通过uni.getStorageSync函数从本地存储中同步获取名为"historyArr"的值,将其赋给变量historyArr。如果本地存储中没有"historyArr"的值,那么将historyArr赋值为空数组。)在savaHistory函数里定义变量let,将我们需要的参数放在里面,再通过uni.setStorageSync方法将该对象保存到名为historyArr的本地存储中。

 

 

1c339470ed8a4f2fbdb96019b19c1d04.png

查看本地储存839ab171dea049cf9a86dbb1bfa17c6a.png

在详情页里接收传递过来的参数

7725f04bbf5540f289b0d6e1bd1f798d.png

重复点击会将重复添加历史记录

e6a1e067d8494878a2742463e27b8598.png

历史记录去重

4935db1f7c184709be53ca1121a2e4d0.png

无历史记录优化细节

83a1a970694a48b39dd716ee52c8b773.png

 

  • 30
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值