一、实验目标
1、综合所学知识创建完整的前端新闻小程序项目; 2、能够在开发过程中熟练掌握真机预览、调试等操作。。
二、实验步骤
列出实验的关键步骤、代码解析、截图。
1、需求分析
本项目一共需要3个页面,即首页、新闻页和个人中心页,其中首页和个人中心页需要以 tabBar的形式展示,可以点击tab图标互相切换。
首页功能需求如下:
(1)首页需要包含幻灯片播放效果和新闻列表;
(2)幻灯片至少要有3幅图片自动播放;
(3)点击新闻列表可以打开新闻全文。
新闻页功能需求如下:
(1)阅读新闻全文的页面需要显示新闻标题、图片、正文和日期;
(2)允许 点击按钮将当前阅读的新闻添加到本地收藏夹中;
(3)已经收藏过的新闻也可以点击按钮取消收藏。
个人中心页功能需求如下:
(1)未登录状态下显示登录按钮,用户点击以后可以显示微信头像和昵称。
(2)登录后读取当前用户的收藏夹,展示收藏的新闻列表。
(3)收藏夹中的新闻可以直接点击查看内容。
(4)未登录状态下收藏夹显示为空。
2、创建项目,配置如图![](https://img-blog.csdnimg.cn/d088b9273dd74a029893243a1834baee.png)
3、页面配置
3.1创建页面
在app.json中的pages属性下添加pages/detail/detail和pages/my/my,保存后生成detail 页面和my页面
3.2删除文件
删除 index.wxml和index.wxss全部代码
删除index.js中全部代码,输入关键词page,找到Page选项回车自动补全函数
删除app.wxss中全部代码
删除app.js中全部代码,输入关键词app,找到App选项回车自动补全函数
3.3添加文件
在根目录下创建images和util文件夹,分别用于存储图片素材和JS文件
①添加图片文件,如图所示为tabBar所用图标文件,将图片拖入images文件夹即可
②创建公共JS文件
右击utils文件夹,选择“新建文件”,输入"common.js"回车后即创建公共函数common.js 本次实验已经准备好资源包,①②步内容可以将提供的资源包直接解压,将images和 utils文件夹拖动移入小程序根目录
图片为创建images和utils后的目录结构
4、视图设计
4.1导航栏设计
在app.json中修改window属性配置导航栏效果
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#DC143C",
"navigationBarTitleText": "我的新闻网",
"navigationBarTextStyle": "white"
}
4.2tabBar设计
首先在app.json中追加tabBar的相关属性代码,属性解释见注释
"tabBar": {
"color": "#000",//颜色
"selectedColor": "#328eeb",//选中时的颜色
"list": [
{
"pagePath" : "pages/index/index",//切换页面的路径
"iconPath": "images/index.png",//tab图标
"selectedIconPath": "images/index_blue.png",//选中时tab图标
"text":"首页"//tab名字 },
{
"pagePath" : "pages/my/my",
"iconPath": "images/my.png",
"selectedIconPath": "images/my_blue.png", "text":"我的"
}
]
}
4.3页面设计
4.3.1首页设计
修改index.wxml文件
swiper滑块容器官方文档
`<!--pages/index/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:for-item="news" wx:key="{{news.id}}">`
`<image src='{{news.poster}}'></image>`
`<text bindtap='goToDetail' data-id='{{news.id}}'>◇{{news.title}}——{{news.add_date}}</text>`
`</view>`
`</view>`
对应 index.wxss代码如下
`swiper{`
`height: 400rpx;`
`}`
`/*swiper图片*/`
`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;`
`}`
在index.js文件中录入测试数据实现布局和样式效果的预览,临时新闻素材可以从 common.js文件中复制获取
4.3.2个人中心页设计
修改my.wxml文件
`**<!--登陆面板-->**`
`**<view id="myLogin">**`
`**<block wx:if="{{isLogin}}">**`
`**<image id="myIcon" src="{{src}}"></image>**`
`**<text id="nickName">{{nickName}}</text>**`
`**</block>**`
`**<button wx:else bindtap="getUserInfo">未登录,点此登录</button>**`
`**</view>**`
`**<!-- 我的收藏 -->**`
`**<view id="myFavorites">**`
`**<text>我的收藏({{num}})</text>**`
`**<!-- 收藏的新闻列表 -->**`
`**<view id="news-list">**`
`**<view class="list-item" wx:for="{{newList}}" wx:for-item="news" wx:key="{{news.id}}">**`
`**<image src="{{news.poster}}"></image>**`
`**<text bindtap="goToDetail" data-id='{{news.id}}'>@{{news.title}}--{{news.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;`
`}`
由于”我的收藏“所展现的新闻列表与首页一样,为了减少代码冗余,讲新闻列表的样式 设计代码移动到app.wxss中全局使用,可以将index.wxss中的原新闻列表样式代码删除
为了进行布局和样式效果的预览,需要在my.js文件的data中录入测试数据
4.3.3新闻页设计
修改detail.wxml代码
`<view class="container">`
`<view class="titls">{{article.title}}</view>`
`<viex class="poster">`
`<image src="{{article.poster}}" mode="widthFix"></image>
</viex>`
`<view class="content">{{article.content}}</view>`
`<view class="add_date">时间:{{article.add_date}}</view>`
`<button wx:if="{{isAdd}}"plain bindtap='cancleFavorites'>@已收藏</button>`
`<button wx:else plain bindtap='addFavorites'>@点击收藏</button>`
`</view>`
修改detail.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;`
`}`
`button{`
`width: 250rpx;`
`height: 100rpx;`
`margin: 20rpx auto;`
`}`
为了进行布局和样式效果的预览,需要在detail.js文件的data中录入测试数据
想要展示样式效果还需要切换编译选项,点击编译左侧,在弹出下拉窗中选择第二项, 如图,修改启动页面为detail
新闻展示效果
5、逻辑实现
5.1公共逻辑
代码已包含在common.js文件中,不需要自己编写,可以视common.js为服务器 解释如下:
一般而言我们获取数据都是从网站服务器,本实验采用本地模拟新闻数据代替
5.2首页逻辑
①新闻列表获取
新闻存储在newList变量中,因此在加载首页时(即启动onLoad函数)获取新闻,并赋 值给newList
`onLoad: function (options) {`
`let id = options.id`
`//检查当前新闻是否在收藏夹中`
`var article = wx.getStorageSync(id)`
`//已存在`
`if(article != ""){`
`this.setData({`
`article:article,`
`isAdd:true`
`})`
`}`
`else{`
`//common.js文件为我们提供了根据新闻编号查询新闻的接口`
`let result = common.getNewsDetail(id)`
`if(result.code == '200'){`
`this.setData({`
`article:result.news,`
`isAdd : false`
`})`
`}`
`}`
`},`
②点击新闻跳转详情
在index.wxml的新闻列表项目的组件添加点击事件,data-id属性携带新闻ID编号用 于查询对应新闻
`<!--新闻列表-->`
`<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 bindtap='goToDetail' data-id='{{news.id}}'>◇{{news.title}}——{{news.add_date}}</text>`
`</view>`
`</view`onload
index.js中定义goToDetail点击事件函数
`goToDetail: function(e) {`
`//获取携带的data-id数据`
`let id = e.currentTarget.dataset.id;`
`//携带新闻id进行页面跳转`
`wx.navigateTo({`
`url: '../detail/detail?id=' + id`
`})`
`},`
此时点击首页的新闻标题,那么就可以跳转到detail界面,由于detail界面尚未设置接受 函数,因此跳转到的页面内容仍为临时数据内容
5.3新闻页逻辑
①显示对应新闻
在首页逻辑中我们在跳转到detail界面时传递了新闻id,现在在新闻页接受id,并查询对 应的新闻内容
保存后,再点击首页新闻标题即可进入对应新闻内容,如点击第三条新闻
②添加/取消新闻收藏
修改detail.wxml代码,追加两个组件作为添加/取消新闻收藏按钮,且通过wx:if和 wx:else属性使其每次只存在一个
`<view class="container">`
`<view class="titls">{{article.title}}</view>`
`<viex class="poster">`
`<image src="{{article.poster}}" mode="widthFix"></image>
</viex>`
`<view class="content">{{article.content}}</view>`
`<view class="add_date">时间:{{article.add_date}}</view>`
`<button wx:if="{{isAdd}}"plain bindtap='cancleFavorites'>@已收藏</button>`
`<button wx:else plain bindtap='addFavorites'>@点击收藏</button>`
`</view>`
**对应wxss
对应wxss样式
`button{`
`width: 250rpx;`
`height: 100rpx;`
`margin: 20rpx auto;`
`}`
先修改onload函数,利用wx.getStorageSync(id)返回值判断是否已经收藏当前新 闻,收藏isAdd = true 否则为 false
然后在detail.js中添加addFavorites和cancleFavorites事件函数
收藏功能使用到微信小程序API wx.setStorageSync(),能够非常简单实现添加收藏,获取收藏内容等功能
`onLoad: function (options) {`
`let id = options.id`
`//检查当前新闻是否在收藏夹中`
`var article = wx.getStorageSync(id)`
`//已存在`
`if(article != ""){`
`this.setData({`
`article:article,`
`isAdd:true`
`})`
`}`
`else{`
`//common.js文件为我们提供了根据新闻编号查询新闻的接口`
`let result = common.getNewsDetail(id)`
`if(result.code == '200'){`
`this.setData({`
`article:result.news,`
`isAdd : false`
`})`
`}`
`}`
`},`
`addFavorites(options){`
`let article = this.data.article`
`wx.setStorageSync(article.id, article);`
`this.setData({`
`isAdd : true`
`})`
`},`
`cancleFavorites(options){`
`let article = this.data.article`
`wx.removeStorageSync(article.id)`
`this.setData({isAdd:false})`
`},`
点击第一条新闻,跳转页面后显示未收藏,点击“点击收藏”,按钮显示为“已收藏”
回到主界面,再进入第一条新闻,显示已收藏
5.4个人中心逻辑
①获取微信用户信息
修改my.wxml代码,追加组件作为登录按钮,并使用wx:if和wx:else属性让未登录时只显 示按钮,登陆后只显示头像和昵称
`<!--登陆面板-->`
`<view id="myLogin">`
`<block wx:if="{{isLogin}}">`
`<image id="myIcon" src="{{src}}"></image>`
`<text id="nickName">{{nickName}}</text>`
`</block>`
`<button wx:else bindtap="getUserInfo">未登录,点此登录</button>`
`</view>`
`<!-- 我的收藏 -->`
`<view id="myFavorites">`
`<text>我的收藏({{num}})</text>`
`<!-- 收藏的新闻列表 -->`
`<view id="news-list">`
`<view class="list-item" wx:for="{{newList}}" wx:for-item="news" wx:key="{{news.id}}">`
`<image src="{{news.poster}}"></image>`
`<text bindtap="goToDetail" data-id='{{news.id}}'>@{{news.title}}--{{news.add_date}}`
`</text>`
`</view>`
`</view>`
`</view>`
在my.js中编写getUserInfo函数,获取用户信息,并将信息更新到动态数据上
`getUserInfo(){`
`let that = this`
`wx.getUserProfile({`
`desc: 'desc',`
`success(res){`
`console.log(res.userInfo)//这里可以在控制台输出用户信息`
`res = res.userInfo`
`that.setData({`
`isLogin : true,`
`src : res.avatarUrl,//设置用户头像`
`nickName : res.nickName//设置用户昵称`
`})`
`}`
`})`
`},`
②获取收藏列表 修改my.wxml代码,将“我的收藏(1)”的“1”改为动态数据效果
修改my.wxml文件
在my.js中的data中初始化num为0
继续在my.js中追加getMyFavorites函数,用于展示真正的新闻收藏列表。
`getMyFavorites(){`
`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(key[i])`
`myList.push(obj)//将新闻添加到新闻数组中`
`}`
`this.setData({`
`newsList:myList,//更新我的收藏新闻列表`
`num:num`
`})`
`},`
`goToDetail(e){`
`//获取携带的data-id数据`
`let id = e.currentTarget.dataset.id;`
`//携带新闻ID进行页面跳转`
`//?后面加参数名 + 后面为传递的参数值`
`wx.navigateTo({`
`url : '../detail/detail?id=' + id`
`})`
`},`
然后在getUserInfo()中调用该函数
this.getMyFavorites()
初始化my.js中data的newsList为空,即删除临时新闻列表数据
这样收藏的功能实际上是将收藏信息保存到本地缓存,用户登录后读取缓存信息,将新 闻放到“我的收藏”,并不算真正意义上的收藏,要想事项真正意义的收藏,则应该将用 户信息和其收藏信息一并保存,如一并保存到云数据库,在读取用户信息后,到云数据 库查询用户信息,进而读取用户收藏。
考虑到登陆成功后用户还可以手动更改新闻的收藏状态,因此修改my.js中的onShow函 数(生命周期函数–监听页面显示),判断如果是登陆状态就刷新一下收藏列表。
③浏览收藏的新闻 点击收藏的新闻和在首页点击新闻跳转功能相似 修改my.wxml,在显示新闻标题的title的组件添加点击函数goToDetail,并传递新闻id
`<!-- 我的收藏 -->`
`<view id="myFavorites">`
`<text>我的收藏({{num}})</text>`
`<!-- 收藏的新闻列表 -->`
`<view id="news-list">`
`<view class="list-item" wx:for="{{newList}}" wx:for-item="news" wx:key="{{news.id}}">`
`<image src="{{news.poster}}"></image>`
`<text bindtap="goToDetail" data-id='{{news.id}}'>@{{news.title}}--{{news.add_date}}`
`</text>`
`</view>`
`</view>`
`</view>`
在my.js中编写gotoDetail函数实现页面跳转,与首页新闻跳转一致
`goToDetail(e){`
`//获取携带的data-id数据`
`let id = e.currentTarget.dataset.id;`
`//携带新闻ID进行页面跳转`
`//?后面加参数名 + 后面为传递的参数值`
`wx.navigateTo({`
`url : '../detail/detail?id=' + id`
`})`
`},`
6、清除临时数据
在进行页面设计阶段,为了展示页面布局和样式效果,我们使用了一些临时数据,为避 免临时数据影响整体逻辑效果,进行清除,删除值即可。
①首页index.js:data中的临时新闻列表数据newsList
②新闻业页detail.js:data中的临时新闻数据article
③个人中心页my.js:data中的临时收藏夹新闻数据(上面步骤中我们已删除),临时昵 称nickName和临时头像路径src
三、程序运行结果
列出程序的最终运行结果及截图。
1、首页
2、新闻页
3、个人中心页
四
、问题总结与体会
描述实验过程中所遇到的问题,以及是如何解决的。有哪些收获和体会,对于课程的安排有哪些建议。
1、问题:
①更新我的收藏num报错。报错信息提示key未定义,位置在my.js的第22行,错把keys 写为key,不是因为获取num值报错而是因为使用未定义变量导致函数报错,无法正常显 示num和我的收藏新闻列表。
2、收获
①掌握更多组件使用方法:swiper,block
②学会使用wx:for及其配套的wx:key和wx:for-item等实现循环处理组件
③学会使用id,class等样式选择器
④了解了样式的作用域,如app.wxss样式可以作用于全局,通过全局样式可以避免代码 冗余
⑤强化了小程序设计流程思维:页面布局=》页面样式设计=》引入临时数据完善页面设 计=》逻辑实现