2024年夏季《移动软件开发》实验报告
一、实验目标
1、综合所学知识创建完整的前端新闻小程序项目;能够在开发过程中
熟练掌握真机预览、调试等操作。
二、实验步骤
1.项目创建
填写名称、目录、选择AppID,选择不使用云服务,模板选择JS基础模板
2. 页面配置
2.1 创建页面文件
(1) 将app.json中pages属性中的“pages/logs/logs"删除
(2) 将app.json文件pages属性中追加pages/detail/detail和pages/my/my
(3)保存修改后会自动生成detail和my目录
2.2 删除和修改文件
(1)删除utils文件夹及其内部所有内容
(2)删除pages文件夹下的logs目录及其内部所有内容
(3)删除index.wxml和index.wxss中的所有代码
(4)删除index.js中的所有代码,并且输入关键词”page“找到第二个选项按回车键让其自动补全函数
(5)删除app.wxss中的所有代码
(6)删除app.js中的全部代码,并且输入关键词”app“找到第二个选项按回车键让其自动补全函数
2.3 创建其它文件
images目录:存放图片
utils:存放公有js文件
提供 common.js、图片文件(images)、以及 index 页面的代码,其它部分的代码大家自
己完成,下载地址:https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/demo4_file.zip
3. 视图设计
3.1 导航栏和tabBar设计
app.json
{
"pages": [
"pages/index/index",
"pages/detail/detail",
"pages/my/my"
],
"window": {
"navigationBarTextStyle": "white",
"navigationBarTitleText": "我的新闻网",
"navigationBarBackgroundColor": "#328EEB"
},
"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.2 页面设计
首页设计
- 幻灯片 :组件
- 新闻列表:,内部数组循环
pages/index/index.wxml
<!--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}}"></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>
pages/index/index.wxss
/*新闻列表区域样式*/
/*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;
}
swiper{
height: 400rpx;
}
swiper image{
width: 100%;
height:100%;
}
pages/index/index.js
Page({
/**
* 页面的初始数据
*/
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'}
],
}
})
个人界面设计
- 登录面板
- 用户微信头像和昵称
- 我的收藏
- 收藏的新闻列表
pages/my/my.wxml
<!-- 登录面板 -->
<view id='myLogin'>
<block wx:if="{{isLogin}}">
<image id='myIcon' src='{{src}}'/>
<text id='nickName'>{{nickName}}</text>
</block>
<button wx:else open-type="getUserInfo" bindgetuserinfo="getMyInfo">未登录,点击登录</button>
</view>
<!-- 我的收藏 -->
<view id="myFavorites">
<text>我的收藏({{num}})</text>
<!-- 收藏的新闻列表 -->
<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 bind:tap="goToDetail" data-id="{{news.id}}">◇{{news.title}}——{{news.add_date}}</text>
</view>
</view>
</view>
pages/my/my.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
#new-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;
}
新闻页设计
pages/detail/detail.wxml
<view class="container">
<view class="title">{{article.title}}</view>
<view class="poster">
<image src="{{article.poster}}" mode="widthFix"/>
</view>
<view class="content">{{article.content}}</view>
<view class="add_date">时间:{{article.add_date}}</view>
<button wx:if="{{isAdd}}" plain bind:tap="cancelFavorites">❤已收藏</button>
<button wx:else plain bind:tap="addFavorites">❤点击收藏</button>
</view>
pages/detail/detail.wxss
.container{
padding: 15rpx;
text-align: center;
}
.title{
font-size: 14pt;
line-height: 80rpx;
}
.poster image{
width: 100%;
}
.content{
text-align: left;
font-size: 12pt;
line-height: 60rpx;
}
.add_data{
font-size: 12pt;
text-align: right;
line-height: 30rpx;
margin-right: 25rpx;
margin-top: 20rpx;
}
button{
width: 250rpx;
height: 100rpx;
margin: 20rpx auto;
}
4. 逻辑实现
common.js直接使用文章开头压缩包内文件
//模拟新闻数据
const news = [
{id: '264698',
title: '中国海大志愿者完成第五届跨国公司领导人青岛峰会志愿服务',
poster: 'https://news.ouc.edu.cn/_upload/article/images/dd/19/ede76a4a4ebdb1d3ab278a12fdd8/9bb154f8-e33b-421a-b453-82c758a32405.jpg',
content: '8月27日至29日,第五届跨国公司领导人青岛峰会在青岛国际会议中心举办。为全面做好服务保障,确保峰会顺利举行,中国海洋大学招募选派115名志愿者参与峰会志愿服务,志愿者们以饱满的热情完成本次大会的各项工作,累计服务时长3000余小时,用实际行动展现中国海大青年风采。',
add_date: '2024-08-31'},
{id: '304083',
title: '贵州省人大干部综合能力提升培训班在中国海洋大学举办',
poster: 'https://news.ouc.edu.cn/_upload/article/images/3a/4d/73b22a9b404f93e907238f2a2325/55606b28-53b8-412f-9420-74c7a30657b6.jpg',
content: ' 8月26日至30日,贵州省人大干部综合能力提升培训班(第三期)在中国海洋大学举办。贵州省人大常委会党组成员于杰,中国海洋大学党委常委、副校长王雪鹏出席开班式,贵州省人大常委会副秘书长、机关党组成员闵红棕主持开班式。',
add_date: '2024-08-30'},
{id: '305670',
title: '中国海洋大学开展2024级本科生集中入学教育',
poster: 'https://news.ouc.edu.cn/_upload/article/images/94/9e/509119874e5287e8c56ef708865b/11604054-e936-468b-a50e-a4233e475a53.jpg',
content: '为帮助2024级本科生尽快适应大学生活,8月27日,学校在崂山校区体育馆举行了2024级本科生集中入学教育。',
add_date: '2024-08-29'}
];
//获取新闻列表
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
}
4.1 首页逻辑
- 新闻列表展示
pages/index/index.js
// pages/index/index.js
var common = require('../../utils/common.js') //引用公共JS文件
Page({
/**
* 页面的初始数据
*/
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'}
],
},
/**
* 自定义函数--跳转新页面浏览新闻内容
*/
goToDetail: function(e) {
//获取携带的data-id数据
let id = e.currentTarget.dataset.id;
//携带新闻id进行页面跳转
wx.navigateTo({
url: '../detail/detail?id=' + id
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
//获取新闻列表
let list = common.getNewsList()
//更新列表数据
this.setData({
newsList: list
})
}
})
- 点击跳转新闻内容
pages/index/index.wxml
<!--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}}"></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>
pages/index/index.js添加函数
// pages/index/index.js
var common = require('../../utils/common.js') //引用公共JS文件
Page({
/**
* 页面的初始数据
*/
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'}
],
},
/**
* 自定义函数--跳转新页面浏览新闻内容
*/
goToDetail: function(e) {
//获取携带的data-id数据
let id = e.currentTarget.dataset.id;
//携带新闻id进行页面跳转
wx.navigateTo({
url: '../detail/detail?id=' + id
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
//获取新闻列表
let list = common.getNewsList()
//更新列表数据
this.setData({
newsList: list
})
}
})
4.2 新闻页逻辑
- 显示对应新闻
- 添加/取消新闻收藏
pages/detail/detail.js
// pages/detail/detail.js
var common = require('../../utils/common.js') //引用公共JS文件
Page({
goToDetail: function(e){
//获得携带的data-id
let id=e.currentTarget.dataset.id;
//携带新闻ID进行页面跳转
wx.navigateTo({
url: '../detail/detail?id='+id,
})
},
/**
* 页面的初始数据
*/
data: {
num: 0
},
/**
* 生命周期函数--监听页面加载
*/
onLoad:function(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
})
}
}
},
//添加收藏夹
addFavorites:function(options){
let article=this.data.article;
wx.setStorageSync(article.id,article);
this.setData({isAdd:true});
},
//取消收藏
cancelFavorites:function(){
let article = this.data.article;
wx.removeStorageSync(article.id);
this.setData({isAdd:false});
}
})
pages/detail/detail.wxml
<view class="container">
<view class="title">{{article.title}}</view>
<view class="poster">
<image src="{{article.poster}}" mode="widthFix"/>
</view>
<view class="content">{{article.content}}</view>
<view class="add_date">时间:{{article.add_date}}</view>
<button wx:if="{{isAdd}}" plain bind:tap="cancelFavorites">❤已收藏</button>
<button wx:else plain bind:tap="addFavorites">❤点击收藏</button>
</view>
4.3 个人中心页逻辑
- 获取微信用户信息
- 获取收藏列表
- 浏览收藏的新闻
pages/my/my.wxml
<!-- 登录面板 -->
<view id='myLogin'>
<block wx:if="{{isLogin}}">
<image id='myIcon' src='{{src}}'/>
<text id='nickName'>{{nickName}}</text>
</block>
<button wx:else open-type="getUserInfo" bindgetuserinfo="getMyInfo">未登录,点击登录</button>
</view>
<!-- 我的收藏 -->
<view id="myFavorites">
<text>我的收藏({{num}})</text>
<!-- 收藏的新闻列表 -->
<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 bind:tap="goToDetail" data-id="{{news.id}}">◇{{news.title}}——{{news.add_date}}</text>
</view>
</view>
</view>
pages/my/my.js
// pages/my/my.js
Page({
getMyInfo:function(e){
let info=e.detail.userInfo;
this.setData({
isLogin:true,
src:info.avatarUrl,
nickName:info.nickName
})
//获取收藏列表
this.getMyFavorites();
},
getMyFavorites:function(){
//获取收藏夹
let info = wx.getStorageInfoSync();
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
});
},
onShow: function(){
//如果已登录
if(this.data.isLogin){
//更新收藏列表
this.getMyFavorites()
}
},
goToDetail:function(e){
//获取携带的data-id数据
let id = e.currentTarget.dataset.id;
//携带新闻Id跳转
wx.navigateTo({
url: '../detail/detail?id='+id,
})
},
/**
* 页面的初始数据
*/
data: {
}
})
三、程序运行结果
列出程序的最终运行结果及截图。
四、问题总结与体会
描述实验过程中所遇到的问题,以及是如何解决的。有哪些收获和体会,对于课程的安排有哪些建议。
问题总结
在实验过程中,我遇到了以下几个主要问题,并尝试了不同的方法来解决它们:
-
图片显示问题
- 问题描述:在
detail
页面的wxss
文件中,.poster image
的width
属性设置为100%
时,图片无法正常显示。 - 解决方法:通过尝试将
width
改为700rpx
后,图片成功显示。这个问题可能是由于rpx(responsive pixel)单位在特定场景下与百分比(%)的兼容性差异导致的。我猜测在detail
页面的布局中,使用百分比宽度可能导致了图片超出了其父容器的可视范围或者计算出错,而使用rpx单位则能更准确地控制图片的显示尺寸。
- 问题描述:在
-
数据链接失效
- 问题描述:在
swiperImg
数组中,原始的图片链接已经失效。 - 解决方法:根据实验文档中的提示,我找到了新的图片链接,并替换掉了原有的失效链接。这要求我在项目文件中进行相应的修改,并确保链接的有效性。
- 问题描述:在
-
tabBar显示问题
- 问题描述:在初始配置tabBar时,图标和文本显示不正确或者无法切换。
- 解决方法:检查
app.json
中的tabBar
配置,确保每个页面的路径、文本和图标都正确无误。同时,确认在首页和个人中心页中使用了正确的<tabBar>
组件,并且没有重复的tabBar配置导致冲突。
-
收藏功能实现
- 问题描述:在新闻页中实现收藏功能时,遇到了数据同步和状态更新的问题。
- 解决方法:通过查阅文档和示例代码,我学会了如何使用小程序的本地存储(
wx.setStorageSync
和wx.getStorageSync
)来保存和读取用户的收藏数据。同时,通过监听页面加载和卸载事件,确保了数据的实时更新和同步。
收获与体会
- 技能提升:通过这次实验,我更加深入地理解了小程序的页面结构、数据绑定、事件处理以及API的使用。尤其是在处理图片显示、数据同步和tabBar配置等问题时,我的动手能力和解决问题的能力得到了显著提升。
- 团队协作:虽然实验是独立完成的,但实验过程中遇到的问题和解决方法让我意识到在团队合作中,沟通和共享资源的重要性。特别是在面对复杂问题时,团队协作能够更快地找到解决方案。
- 项目规划:在实验开始前,对项目的整体规划和需求分析非常重要。这有助于我在开发过程中有条不紊地进行,避免了一些不必要的返工和错误。
- 学习方法:通过查阅文档、搜索网络资源和尝试不同的解决方案,我学会了更加高效地学习新知识和解决问题的方法。这些方法不仅在本次实验中发挥了重要作用,也将对我的未来学习和工作产生积极影响。
对课程安排的建议
- 提供更多资源:在课程中提供更多有用的资源和链接,如API文档、示例代码和常见问题解答等,方便学生在遇到问题时能够及时找到解决方案。
- 强化基础训练:在教授新知识之前,加强对学生基础知识的训练,确保他们具备扎实的基础知识和技能。