一、实验目标
基础目标:
1、综合所学知识创建完整的前端新闻小程序项目;
2、能够在开发过程中熟练掌握真机预览、调试等操作。
额外实现:
使用云端数据库存储新闻内容。
二、实验步骤
1.素材准备
通过以下地址下载小程序所需要的图片:https://gaopursuit.oss-cnbeijing.aliyuncs.com/2022/demo4_file.zip
之后创建一个images文件夹,将压缩包中的文件导入。
2.视图设计
2.1 导航栏设计
在app.json添加以下代码,为导航栏设计效果;
"window": { "navigationBarBackgroundColor": "#328EEB", "navigationBarTitleText": "我的新闻网", "navigationBarTextStyle": "white" },
将导航栏改为蓝色背景,字体白色的样式,效果如下:
2.2 tabBar设计
在app.json文件中继续追加以下代码,实现底部导航栏的效果:
"tabBar": { "color": "#000", "selectedColor": "#328EEB", "list": [{ "pagePath": "pages/index/index", "text": "首页", "iconPath": "images/index.png", "selectedIconPath": "images/index_blue.png" }, { "pagePath": "pages/my/my", "iconPath": "images/my.png", "selectedIconPath": "images/my_blue.png", "text": "我的" } ] },
完成以上两部操作后,整个页面的效果如下:
3.页面设计
3.1 首页设计
首页一共用到两个组件:swiper组件和view组件
其中swiper用来放滚动的幻灯片,view用来展示新闻列表
在.wxml文件里添加以下代码:
<swiper indicator-dots autoplay interval="5000" duration="500"> <block wx:for="{{swiperImg}}" wx:key='swiper{{index}}'> <swiper-item> <image src="{{item.src}}" class="slide-image"/> </swiper-item> </block> </swiper> <view id="news-list"> <view class='list-item' wx:for="{{newsList}}" wx:for-item="news" wx:key="{{news.id}}"> <image src='{{news.poster}}'></image> <text>{{news.title}}--{{news.add_date}}</text> </view> </view>
在.wxss文件中为其添加样式:
swiper{ height:400rpx; } swiper image{ width: 100%; height:100%; } #news-list{ min-height: 600rpx; padding: 15rpx; } .list-item{ display: flex; flex-direction: row; border-bottom: 1rpx solid gray; } .list-item image{ width: 230rpx; height: 150rpx; margin: 10rpx; } .list-item text{ width: 100%; line-height: 60rpx; font-size: 10pt; }
为了进行测试,在js文件中插入几个临时数据用于预览效果:
data: { swiperImg: [ {src: 'https://news.ouc.edu.cn/_upload/article/images/dd/19/ede76a4a4ebdb1d3ab278a12fdd8/9bb154f8-e33b-421a-b453-82c758a32405.jpg'}, {src: 'https://news.ouc.edu.cn/_upload/article/images/3a/4d/73b22a9b404f93e907238f2a2325/55606b28-53b8-412f-9420-74c7a30657b6.jpg'}, {src: 'https://news.ouc.edu.cn/_upload/article/images/94/9e/509119874e5287e8c56ef708865b/11604054-e936-468b-a50e-a4233e475a53.jpg'} ], newsList:[{ id:"264698", title:'海大志愿者', poster:'https://news.ouc.edu.cn/_upload/article/images/dd/19/ede76a4a4ebdb1d3ab278a12fdd8/9bb154f8-e33b-421a-b453-82c758a32405.jpg', add_date:'2024-09-02' }] },
3.2 个人中心页面设计
个人中心页面主要包含登录面板和我的收藏两个部分,使用view组件进行布局,.wxml文件代码如下:
<view id="myLogin"> <block> <image src="{{src}}" id='myIcon'/> <text id='nickName'>{{nickName}}</text> </block> </view> <view id="myFavorites"> <text>我的收藏(1)</text> <view id="news-list"> <view class="list-item" wx:for="{{newsList}}" wx:for-item="news" wx:key="{{news.id}}"> <image src="{{news.poster}}" /> <text>{{news.title}}--{{news.add_date}}</text> </view> </view> </view>
在.wxss文件中设置样式:
#myLogin{ background-color: #328EEB; height: 400rpx; display: flex; flex-direction: column; align-items: center; justify-content: space-around; } #myIcon{ width: 200rpx; height: 200rpx; border-radius: 50%; } #nickName{ color: white; } #myFavorites{ padding: 20rpx; }
此处列表的样式和首页的样式是相同的,因此直接在app.wxss文件中为其设置样式即可,这样可以实现代码的复用,减少冗余代码。在app.wxss文件中写入以下代码:
#news-list{ min-height: 600rpx; padding: 15rpx; } .list-item{ display: flex; flex-direction: row; border-bottom: 1rpx solid gray; } .list-item image{ width: 230rpx; height: 150rpx; margin: 10rpx; } .list-item text{ width: 100%; display: block; line-height: 60rpx; font-size: 10pt; }
同样地,为了测试程序的效果,我们在js文件中插入数据来预览程序的效果:
data: { nickName:'未登录', src:'/images/index.png', newsList:[{ id:"264698", title:'海大志愿者', poster:'https://news.ouc.edu.cn/_upload/article/images/dd/19/ede76a4a4ebdb1d3ab278a12fdd8/9bb154f8-e33b-421a-b453-82c758a32405.jpg', add_date:'2024-09-02' }], num:0, },
此时效果如下:
3.3新闻页面设计
新闻页面主要由新闻标题,新闻图片,新闻正文,新闻日期和收藏按钮构成,我们首先实现实现前四个部分。
使用view组件对整个页面进行整体布局。
.wxml文件写入以下代码:
<view class='container'> <view class='title'>{{article.title}}</view> <view> <image src="{{article.poster}}" mode="widthFix"/> </view> <view class='content'>{{article.content}}</view> <view class='add_date'>时间:{{article.add_date}}</view> </view>
在.wxss文件中设置样式:
.container{ padding: 15rpx; text-align: center; } .title{ font-size: 14pt; line-height: 80rpx; } .poster image{ width: 700rpx; } .content{ text-align: left; font-size: 12pt; line-height: 60rpx; } .add_date{ font-size: 12pt; text-align: right; line-height: 30rpx; margin-right: 25rpx; margin-top: 20rpx; }
此时我们还没有添加页面跳转功能,因此直接普通编译是无法预览效果的,可以通过添加编译模式来实现对这个页面的效果预览:
为了预览效果,在js文件中写入临时数据:
data: { article:{ id:'264698', title:'测试标题', poster:'https://news.ouc.edu.cn/_upload/article/images/dd/19/ede76a4a4ebdb1d3ab278a12fdd8/9bb154f8-e33b-421a-b453-82c758a32405.jpg', content:'测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试', add_date:'2024-09-02' } },
当前效果如下所示:
4.逻辑实现
4.1 common.js中的公共函数
这里我首先完成的是本地静态的页面实现,因此在common.js中写入了数据,并且完成了getNewsList和GetNewsDetail两个公共接口供其他页面使用,具体数据和代码如下:
const news = [ {id: '264698', title: '中国海大志愿者完成第五届跨国公司领导人青岛峰会志愿服务', poster: 'https://news.ouc.edu.cn/_upload/article/images/dd/19/ede76a4a4ebdb1d3ab278a12fdd8/9bb154f8-e33b-421a-b453-82c758a32405.jpg', content: '测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试', add_date: '2024-09-02'}, {id: '304083', title: '贵州省人大干部综合能力提升培训班在中国海洋大学举办', poster: 'https://news.ouc.edu.cn/_upload/article/images/3a/4d/73b22a9b404f93e907238f2a2325/55606b28-53b8-412f-9420-74c7a30657b6.jpg', content: '测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试', add_date: '2022-08-09'}, {id: '305670', title: '中国海洋大学开展2024级本科生集中入学教育', poster: 'https://news.ouc.edu.cn/_upload/article/images/94/9e/509119874e5287e8c56ef708865b/11604054-e936-468b-a50e-a4233e475a53.jpg', content: '测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试', add_date: '2024-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 }
完成以后,在其他页面如果想要调用common.js中的公共借口就要引用js文件,在需要调用接口的页面的js文件的顶部添加以下代码:
var common=require('../../utils/common.js')
4.2首页逻辑
首先在js文件的onLoad函数中获取新闻列表,并更新到data属性中,用于页面的展示:
onLoad: function (options) { let list=common.getNewsList() this.setData({newsList:list}) },
这个时候就可以看到全部的三个新闻:
然后为新闻列表添加监听事件,点击后跳转页面,修改text组件的代码如下:
<text bind:tap="goToDetail" data-id='{{news.id}}'>{{news.title}}--{{news.add_date}}</text>
然后在js页面中为其设置事件函数,实现页面的跳转:
goToDetail:function(e){ let id=e.currentTarget.dataset.id; wx.navigateTo({ url: '../detail/detail?id='+id, }) },
此时已经可以跳转页面,但是新闻的内容是不正确的,显示的内容是固定的,并不是动态的。
4.3新闻页面逻辑
首先需要接受index页面点击后传输过来的数据,然后根据数据id查询相应的新闻内容:
onLoad(options) { let id=options.id let result =common.getNewsDetail(id) if(result.code=='200'){ this.setData({article:result.news}) } },
这个时候已经能够正确显示新闻的内容了:
之后开始实现收藏功能,主要是通过button按钮组件来实现的。
使用wx:if和wx:else组件来实现动态改变未收藏和已收藏的状态,并且每次只显示一个按钮。
.wxml文件代码如下:
<button wx:if='{{isAdd}}' plain bind:tap="cancelFavorites">已收藏</button> <button wx:else plain bind:tap="addFavorites">点击收藏</button>
.wxss文件中设置样式:
button{ width: 250rpx; height: 100rpx; margin: 20rpx auto; }
之后在js页面中实现对应的逻辑:
onLoad(options) { let id=options.id var article=wx.getStorageSync('id') if(article!=''){ this.setData({ article:article, isAdd:true }) } else{ let result =common.getNewsDetail(id) if(result.code=='200'){ this.setData({ article:result.news, isAdd:false }) } } },
同时,在js文件中添加两个事件函数,用于添加和取消收藏:
addFavorites:function(options){ let article=this.data.article wx.setStorageSync(article.id, article) this.setData({isAdd:true}) }, cancalFavorites:function(){ let article = this.data.article wx.removeStorageSync(article.id) this.setData({isAdd:false}) },
此时效果如下:
4.4个人中心页面逻辑
在my.wxml中添加按钮组件,用来获取用户的信息:
<view id="myLogin"> <block wx:if='{{isLogin}}'> <image src="{{src}}" id='myIcon'/> <text id='nickName'>{{nickName}}</text> </block> <button wx:else>未登录,点此登录</button> </view>
此时已经有了下面的按钮:
然后为按钮添加事件函数,获取用户信息并且将信息从传递给自定义的函数,用于收藏功能的实现,首先修改button组件:
<button wx:else open-type="getUserInfo" bindgetuserinfo="getMyInfo">未登录,点此登录</button>
之后再js文件中添加函数:
getMyInfo:function(e){ console.log(e.detail.userInfo) },
此时已经可以输出用户信息了:
之后修改函数,将信息更新到页面中:
getMyInfo:function(e){ console.log(e.detail.userInfo) let info=e.detail.userInfo this.setData({ isLogin:true, src:info.avatarUrl, nickName:info.nickName }) },
这个时候在页面就会显示用户的头像和名称了:
然后是收藏列表的实现,首先修改.wxml文件,修改收藏数据,实现动态的数字:
<text>我的收藏({{num}})</text>
在js文件中添加函数,用于更新页面中的列表:
getMyFavorites:function(){ let info=wx.getStorageSync(); let keys=info.keys; 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, num:num }); },
同时在getMyInfo函数中添加对以上函数的调用:
this.getMyFavorites();
此时已经能够实现收藏列表的动态更新了:
修改js中的onShow函数,如果修改会有即使的更新:
onShow() { if(this.data.isLogin){ this.getMyFavorites() } },
现在功能已经基本实现,下面实现通过收藏列表来进行新闻的查看,首先修改.wxml文件,添加事件:
<text bind:tap="toToDetail" data-id='{{news.id}}'>{{news.title}}--{{news.add_date}}</text>
然后在js文件添加函数:
goToDetail:function(e){ let id=e.currentTarget.dataset.id; wx.navigateTo({ url: '../detail/detail?id='+id, }) },
这样,所有的功能就全部实现了。
5.拓展功能实现
实现了本地静态数据后我又尝试了云端数据库的方式来存储新闻页面的内容。
首先在数据库中新建一个集合,并且写入相应的数据。
之后在app.js文件中进行数据库的初始化:
onLaunch: function () { wx.cloud.init( { env:"id", } )
在index.js的顶端添加数据库的引用:
const db=wx.cloud.database().collection("class5")
之后修改OnLond函数,通过数据库而不是本地静态读取数据:
onLoad: function (options) { let list=[] db.get({ success:(res)=>{ console.log(res.data) list=res.data this.setData({newsList:list}) } }) },
至此,通过数据库也可以实现新闻内容的读取。
## 三、程序运行结果
主页效果:
新闻页面效果:
收藏页面效果: