一、项目创建
本项目一共需要3个页面,即首页、新闻页和个人中心页,其中首页和个人中心页需要以tabBar的形式展示,可以点击tab图标互相切换。
1. 首页功能需求
首页功能需求如下:(1)首页需要包含幻灯片播放效果和新闻列表;(2)幻灯片至少要有3幅图片自动播放;(3)点击新闻列表可以打开新闻全文。
2. 新闻页功能需求
新闻页功能需求如下:(1)阅读新闻全文的页面需要显示新闻标题、图片、正文和日期;(2)允许 点击按钮将当前阅读的新闻添加到本地收藏夹中;(3)已经收藏过的新闻也可以点击按钮取消收藏。
3. 个人中心页功能需求
个人中心页功能需求如下:(1)未登录状态下显示登录按钮,用户点击以后可以显示微信头像和昵称。(2)登录后读取当前用户的收藏夹,展示收藏的新闻列表。(3)收藏夹中的新闻可以直接点击查看内容。(4)未登录状态下收藏夹显示为空。
在Page下新建两个文件夹,index为首页,my为个人中心,detail为新闻页
二、视图设计
新闻数据和图片下载地址:https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/demo4_file.zip
1. 导航栏设计
app.json
"pages":[
"pages/index/index",
"pages/my/my",
"pages/detail/detail"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#328eeb",
"navigationBarTitleText": "我的新闻网",
"navigationBarTextStyle":"white"
},
2. tabBar设计
app.json
"tabBar": {
"color": "#000",
"selectedColor": "#328eeb",
"list": [{
"pagePath": "pages/index/index",
"iconPath":"/images/index.png",
"selectedIconPath": "/images/index_blue.png",
"text": "首页"
},
{
"pagePath": "pages/my/my",
"iconPath":"/images/my.png",
"selectedIconPath": "/images/my_blue.png",
"text": "我的"
}]
}
3. 页面设计
I. 首页设计
首页由两部分组成:幻灯片和新闻列表
- 幻灯片:<swiper>组件
- 新闻列表:<view>容器,内部使用数组循环
index.wxml
<!--幻灯片滚动-->
<swiper indicator-dots="true" autoplay="true" interval="5000" duration="500">
<block wx:for="{{swiperImg}}" wx:key="swiper{{index}}">
<swiper-item>
<image src="{{item.src}}" class="slide-image"></image>
</swiper-item>
</block>
</swiper>
<!--新闻列表-->
<view id="news-list">
<view class="list-item" wx:for="{{newsList}}" wx:key="{{item.id}}">
<image src="{{item.poster}}"></image>
<text>{{item.title}} ———— {{item.add_date}}</text>
</view>
</view>
<swiper>组件属性众多,indicator-dots:是否显示面板指示点 , autoplay: 是否自动切换
interval:自动切换时间间隔 , duration :滑动动画时长
index.wxss
/*<swiper>区域样式*/
/*1-1 swiper组件*/
swiper{
height: 400rpx;
}
/*1-2 swiper中的图片*/
swiper image{
width: 100%;
height: 100%;
}
/*新闻列表区域样式*/
/*2-1 新闻列表容器*/
.news-list{
min-height: 600rpx;
padding: 15rpx;
}
/*2-2 列表项目*/
.list-item{
display: flex;
flex-direction: row;
border-bottom: 1rpx solid gray;
}
/*2-3 新闻图片*/
.list-item image{
width: 230rpx;
height: 150rpx;
margin: 10rpx;
}
/*2-4 新闻标题*/
.list-item text{
width: 100%;
line-height: 60rpx;
font-size: 10pt;
}
在index.js中加入一些临时数据:
/**
* 页面的初始数据
*/
data: {
//幻灯片素材
swiperImg: [
{src: 'https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/newsimage1.jpg'},
{src: 'https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/newsimage2.jpg'},
{src: 'https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/newsimage3.jpg'}
],
newsList:[
{id: '264698',
title: '标题',
poster: 'https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/newsimage1.jpg',
content: ' 内容',
add_date: '2022-08-19'}
},
II. 个人中心页面设计
个人中心页面包括:登录面板、我的收藏
登录面板:显示用户的微信头像和昵称
我的收藏:显示收藏在本地的新闻列表
自定义id:
- myLogin: 登录面板
- myIcon:微信头像图片
- nickName: 微信昵称
- myFavorites: 我的收藏
my.wxml
<!--登录面板-->
<view class="myLogin">
<block wx:if="{{isLogin}}">
<image class="myIcon" src="{{src}}"></image>
<text class="nickName">{{nickName}}</text>
</block>
<button wx:else open-type="getUserInfo" bindtap="getMyInfo">未登录,点此登录</button>
</view>
<!--我的收藏-->
<view class="myFavorites">
<text>我的收藏({{number}})</text>
<!--收藏的新闻列表-->
<view class="news-list">
<view class="list-item" wx:for="{{newsList}}" wx:key="{{item.id}}">
<image src="{{item.poster}}"></image>
<text bindtap="goToDetail" data-id="{{item.id}}">{{item.title}} ———— {{item.add_date}}</text>
</view>
</view>
</view>
my.wxss
/*登录面板*/
.myLogin{
background-color: #328eeb;
height: 400rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
}
/*1-1 头像图片*/
.myIcon{
width: 200rpx;
height: 200rpx;
border-radius: 50%;
}
/*1-2 微信昵称*/
.nickName{
color: white;
}
/*我的收藏*/
.myFavorites{
padding: 20rpx;
}
/*新闻列表区域样式*/
/*2-1 新闻列表容器*/
.news-list{
min-height: 600rpx;
padding: 15rpx;
}
/*2-2 列表项目*/
.list-item{
display: flex;
flex-direction: row;
border-bottom: 1rpx solid gray;
}
/*2-3 新闻图片*/
.list-item image{
width: 230rpx;
height: 150rpx;
margin: 10rpx;
}
/*2-4 新闻标题*/
.list-item text{
width: 100%;
line-height: 60rpx;
font-size: 10pt;
}
注: 由于新闻列表的样式与首页完全相同,没有必要重复样式代码,否则会造成冗余,可以将index. wxss中新闻列表样式的相关代码挪到app. wxss 中公共使用。
III.新闻页设计
新闻页是用于给用户浏览新闻全文的,需要用户点击首页的新闻列表,然后在新窗口中打开该页面。新闻页包括新闻标题、新闻图片﹑新闻正文和新闻日期。
结构:
自定义class:
- container:整体容器
- poster:新闻图片
- title:新闻标题
- content:新闻内容
- add_date:新闻时间
detail.wxml
<view class="container">
<view class="title">{{artical.title}}</view>
<view class="poster">
<image src="{{artical.poster}}" mode="widthFix"></image>
</view>
<view class="content">
<text>{{artical.content}}</text>
</view>
<view class="add_date">{{artical.add_date}}</view>
</view>
detail.wxss
.container{
padding: 15rpx;
}
.title{
font-size: 35rpx;
line-height: 35rpx;
text-align: center;
}
.poster image{
width: 100%;
}
.content text{
text-align: left;
font-size: 30rpx;
line-height: 35rpx;
}
.add_date{
font-size: 30rpx;
text-align: right;
line-height: 30rpx;
margin-right: 25rpx;
margin-top: 20rpx;
}
detail.js中录入部分新闻数据
data: {
artical:{
id: '264698',
title: '标题',
poster: 'https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/newsimage1.jpg',
content: ' 内容',
add_date: '2022-08-19'
},
}
预览:
三、逻辑实现
1. 公共逻辑
将数据存入公共JS文件(utils/common.js)
自定义函数getNewsList 和 getNewsDetail分别用于获取新闻列表信息和指定ID的新闻正文内容
module.exports语句用于暴露函数出口
//模拟新闻数据
const news = [
{id: '264698',
title: '标题'
poster: 'https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/newsimage1.jpg',
content: ' 内容',
add_date: '2022-08-19'},
{id: '304083',
title: '',
poster: 'https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/newsimage2.jpg',
content: '',
add_date: '2022-08-09'},
{id: '305670',
title: '',
poster: 'https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/newsimage3.jpg',
content: '',
add_date: '2022-08-11'}
];
//获取新闻列表
function getNewsList() {
let list = [];
for (var i = 0; i < news.length; i++) {
let obj = {};
obj.id = news[i].id;
obj.poster = news[i].poster;
obj.add_date = news[i].add_date;
obj.title = news[i].title;
list.push(obj);
}
return list; //返回新闻列表
}
//获取新闻内容
function getNewsDetail(newsID) {
let msg = {
code: '404', //没有对应的新闻
news: {}
};
for (var i = 0; i < news.length; i++) {
if (newsID == news[i].id) { //匹配新闻id编号
msg.code = '200'; //成功
msg.news = news[i]; //更新当前新闻内容
break;
}
}
return msg; //返回查找结果
}
// 对外暴露接口
module.exports = {
getNewsList: getNewsList,
getNewsDetail: getNewsDetail
}
2. 首页逻辑
首页主要有两个功能需要实现,一是展示新闻列表,二是点击新闻标题可以跳转对应的内容页面进行浏览。
I.展示新闻列表
在index.js中需要获取到新闻列表,此时就需要使用公共JS文件中的getNewsList函数,
引入common.js文件
var common = require("../../utils/common.js")
index.js
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let list=common.getNewsList()
this.setData({
newsList:list
})
},
效果:
II. 点击新闻跳转
为新闻项目添加点击事件
index.wxml
为整个<view>添加点击事件自定义函数goToDetail(),保证不论点到新闻哪部分都可以跳转,并使用data-id属性携带新闻id
<!--新闻列表-->
<view id="news-list">
<view class="list-item" wx:for="{{newsList}}" wx:key="{{item.id}}" bindtap="goToDetail" data-id="{{item.id}}">
<image src="{{item.poster}}"></image>
<text>{{item.title}} ———— {{item.add_date}}</text>
</view>
</view>
index.js
goToDetail:function(e) {
//获取data-id的数据
let id = e.currentTarget.dataset.id
//携带新闻id进行页面跳转
wx.navigateTo({
url: '../detail/detail?id=' + id,
})
},
3. 新闻页逻辑
两个功能:
- 显示对应新闻
- 可以添加、取消新闻收藏
I. 显示对应新闻
在首页逻辑中,点击新闻跳转时携带了新闻ID,新闻页需接收ID编号,并查询对应的新闻内容
在获取id后,需检查当前新闻是否在收藏夹中来确认isAdd是true还是false,来使收藏按钮显示不同的文本
detail.js
onLoad(options) {
let id = options.id
//检查当前新闻是否在收藏夹中
var newartical = wx.getStorageSync(id)
//存在
if(newartical != '')
{
this.setData({
isAdd:true,
artical:newartical
})
}
//不存在
else{
let result = common.getNewsDetail(id)
//获取新闻内容
if(result.code == '200'){
this.setData({
artical:result.news,
isAdd:false
})
}
}
},
II.添加、取消新闻收藏
在detail.js中追加addFavorites() 和 cancelFavorites()函数用于点击添加/取消收藏
detail.js
/*添加收藏*/
addFavorites:function () {
let artical = this.data.artical
wx.setStorageSync(artical.id, artical) //将文章放入缓存区
this.setData({
isAdd:true
})
},
/*取消收藏 */
cancelFavorites:function() {
let artical = this.data.artical
wx.removeStorageSync(artical.id)
this.setData({
isAdd:false
})
},
预览:
添加本地缓存:
删除本地缓存:
4. 个人中心页逻辑
个人中心页需要实现三个方面的内容:
1.获取微信用户信息
2.获取收藏列表
3.浏览收藏的新闻
I. 获取用户信息
添加<button>组件作为登录按钮,并且使用wx:if和wx:else属性让未登录时只显示按钮,登录后显示微信头像和昵称
my.wxml
<!--登录面板-->
<view class="myLogin">
<block wx:if="{{isLogin}}">
<image class="myIcon" src="{{src}}"></image>
<text class="nickName">{{nickName}}</text>
</block>
<button wx:else open-type="getUserInfo" bindtap="getMyInfo">未登录,点此登录</button>
</view>
预览:
获取用户信息的操作同实验1
my.js
getMyInfo: function(e){
wx.getUserProfile({
desc: '获取信息',
success:(res)=>{
this.setData({
src:res.userInfo.avatarUrl,
nickName:res.userInfo.nickName,
isLogin:true
})
}
})
},
onLoad(options) {
if(wx.getUserProfile){
this.setDate({
canIUseGetUserProfile: true
})
}
},
II.获取收藏列表
在收藏列表上方动态显示出收藏数目
my.js
data: {
number:0,
nickName: "未登录",
src:"/images/index.png",
},
获取收藏数目:
//更新number
getMyFavorites:function() {
let info = wx.getStorageInfoSync() //读取本地缓存信息
let keys = info.keys //获取全部key信息
let num = keys.length //获取收藏全部新闻数量
let myList = [];
for(var i=0;i<num;i++)
{
let obj = wx.getStorageSync(keys[i])
myList.push(obj)
}
//更新收藏列表
this.setData({
newsList:myList,
number:num
})
},
修改getMyInfo()函数,使其在被调用时调用getMyFavorites()函数,即用户登录后显示用户收藏信息
getMyInfo: function(e){
wx.getUserProfile({
desc: '获取信息',
success:(res)=>{
this.setData({
src:res.userInfo.avatarUrl,
nickName:res.userInfo.nickName,
isLogin:true
})
//获取新闻列表
this.getMyFavorites()
}
})
},
用户登录成功后还可以手动更改新闻的收藏状态,修改my.js中的onShow()函数,判断如果是登录状态就刷新一下收藏列表
/**
* 生命周期函数--监听页面显示
*/
onShow() {
if(this.data.isLogin){
this.getMyFavorites()
}
},
III.浏览收藏的新闻
与首页点击新闻跳转相似
预览:
取消收藏: