一、实验目标
1、综合所学知识创建完整的前端新闻小程序项目;能够在开发过程中熟练掌握真机预览、调试等操作。
二、实验步骤
1.准备阶段:
(1)准备相关的新闻以及图片链接,作为小程序开发的的素材
(2)可以在网上下载tabBar的图标素材,进行抠图,这样可以美化自己的小程序
(3)搭建微信开发者工具的编译环境,这次实验除了创建index文件夹外,还需要创建两个同类型不同名的my,detail文件夹,对应三个页面。
2.开始编程,下列是源代码以及代码相关作用的注释
(1)编辑前端UI界面(共三个界面),代码如下
app.json
{
"pages": [
"pages/incdex/index",
"pages/detail/detail",
"pages/main/main"
],
"window": {
"navigationBarBackgroundColor": "#328EEB",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的新闻网",
"backgroundColor": "#eeeeee",
"backgroundTextStyle": "light",
"enablePullDownRefresh": false
},
//设置tabBar,两个按钮:‘首页’与‘我的’
"tabBar": {
"color": "#000000",
"selectedColor": "#328EEB",
"list": [
{
"pagePath": "pages/incdex/index",
"text": "首页",
"iconPath": "images/index1.png", //未选中时的图标
"selectedIconPath": "images/index2.png" //选中时的图标
},
{
"pagePath": "pages/main/main",
"text": "我的",
"iconPath": "images/my1.png", //未选中时的图标
"selectedIconPath": "images/my2.png" //选中时的图标
}
]
},
"sitemapLocation": "sitemap.json"
}
app.wxss
.news-item{
display: flex;
flex-direction: row;
border-bottom: 1rpx solid black;
align-items: center;
}
.img{
height: 150rpx;
width: 230rpx;
/* margin:10rpx 向周围扩充10rpx的宽度 */
margin:10rpx;
}
.news-item text{
width: 100%;
line-height: 60rpx;
font-size: 40rpx;
font-family: kaiti; /*设置字体为楷体*/
}
index.wxml
<!--pages/detail/detail.wxml-->
<!-- <text>pages/detail/detail.wxml</text> -->
<!-- 幻灯片 -->
<!-- indicator-dots:幻灯片播放时是否会显示小点点 -->
<!-- autoplay:幻灯片是否会自动播放 -->
<!-- interval:每隔多长时间自动播放到下一个幻灯片 -->
<!-- duration:播放动画这个过程所需要的时间为500ms -->
<swiper indicator-dots="true" autoplay="true" interval="5000" duration="500">
<!-- 给定wx:key便于循环 -->
<!-- swiperImage为储存图片的数组 -->
<view wx:for="{{swiperImage}}" wx:key="swiper{{index}}">
<swiper-item>
<image src="{{item.src}}"></image>
</swiper-item>
</view>
</swiper>
<!-- 新闻列表 -->
<view class="news-list">
<view class="news-item" wx:for="{{newslist}}" wx:key="{{item.id}}" bindtap="goToDetail" data-id="{{item.id}}">
<image src="{{item.poster}}" class="img"></image>
<text>{{item.title}}——{{item.add_date}}</text>
</view>
<!-- 加载更多新闻按钮 plain:镂空-->
<button plain="true">加载更多</button>
</view>
index.wxss
/* pages/incdex/index.wxss */
/* pages/detail/detail.wxss */
swiper{
height:400rpx;
width:100%
}
/* 类似于后代选择器? */
swiper image{
height: 100%;
width: 100%;
}
.news-list{
min-height: 600rpx;
padding: 15rpx;
}
main.wxml
<!-- 登录页面 -->
<view class="myLogin">
<!-- 封装成块 -->
<block wx:if="{{isLogin}}">
<image src="{{src}}"></image>
<text>{{nickName}}</text>
</block>
<button wx:else bindtap="getUserProfile"> 未登录,点此登录 </button>
</view>
<!-- 收藏列表 -->
<view class="myFavorite">
<text>我的收藏({{number}})</text>
<view class="news-list">
<view class="news-item" wx:for="{{newslist}}" wx:key="{{item.id}}" bindtap="goToDetail" data-id="{{item.id}}">
<image src="{{item.poster}}" class="img"></image>
<text>{{item.title}}——{{item.add_date}}</text>
</view>
</view>
</view>
main.wxss
/* 登录界面 */
.myLogin{
height: 400rpx;
background-color: #328EEB;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
}
.myLogin image{
height: 220rpx;
width: 220rpx;
border-radius: 50%;
}
.myLogin text{
color: white;
font-family: fangsong;
}
.myFavorite{
padding: 3%;
}
detail.wxml
<view class="container">
<view class="title">{{article.title}}</view>
<view class="poster">
<image src="{{article.poster}}"></image>
</view>
<view class="content">
<text>{{article.content}}</text>
</view>
<view class="add_date">{{article.add_date}}</view>
<button wx:if="{{isAdd}}" plain bindtap="cancelFavorite">❤已收藏</button>
<button wx:else plain bindtap="addFavorite">💔未收藏</button> //通过wx:if来判断isAdd的值,从而确定文章是否被收藏
</view>
detail.wxss
/* 整体样式 */
.container{
padding: 15rpx;
}
.title{
font-size: 35rpx;
line-height: 35rpx;
font-family: fangsong;
text-align: center;
}
.poster image{
width: 100%;
}
.content{
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;
}
(2)实现每个页面后端的内核的实现,下列是相关代码
index.js
// pages/incdex/index.js
var common = require('../../utils/common')
//保证可以调用common.js
Page({
/**
* 页面的初始数据
*/
data: {
swiperImage:[
{src:""},
{src:""},
{src:""}
],
newslist:[]
},
goToDetail:function(res){
//获取data-id的数据
let id = res.currentTarget.dataset.id
// console.log(res)
//携带新闻id进行页面跳转
wx.navigateTo({
url: '../detail/detail?id=' + id,
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
let list = common.getNewList()
this.setData({
newslist:list
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
main.js
// pages/main/main.js
Page({
/**
* 页面的初始数据
*/
data: {
number:0,
nickName:'未登录',
src:'/images/index1.png',
newslist:[]
},
//获取个人信息
getUserProfile:function(res){
wx.getUserProfile({
desc: '获取个人信息',
success:(res) => {
let info = res.userInfo;
this.setData({
src:info.avatarUrl,
nickName:info.nickName,
isLogin:true
})
}
})
//获取新闻列表
this.getMyFavorite()
},
//更新number
getMyFavorite:function(res){
let info = wx.getStorageInfoSync()//读取本地缓存信息
let keys = info.keys//获取全部key信息
let num = keys.length//获取key数量
let myList = [];
for (var i = 0; i < num; i++){
let obj = wx.getStorageSync(keys[i])
myList.push(obj)
}
console.log(myList)
//更新收藏列表
this.setData({
newslist:myList,
number:num
})
},
goToDetail:function(res){
//获取data-id的数据
let id = res.currentTarget.dataset.id
// console.log(res)
//携带新闻id进行页面跳转
wx.navigateTo({
url: '../detail/detail?id=' + id,
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
canIUseGetUserProfile: true
wx.clearStorage()
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
if(this.data.isLogin){
this.getMyFavorite()
}
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
detail.js
// pages/detail/detail.js
var common = require('../../utils/common')
//保证可以调用common.js
Page({
/**
* 页面的初始数据
*/
data: {
article:{
id:'',
title:'',
poster:'',
add_date:'',
content:'”。'
},
isAdd:false
},
//添加收藏
addFavorite:function(){
let article = this.data.article
wx.setStorageSync(article.id, article)
this.setData({
isAdd:true
})
},
//取消收藏
cancelFavorite:function(){
let article = this.data.article
wx.removeStorageSync(article.id)
this.setData({
isAdd:false
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
//检验是否携带id号进入页面
// console.log(options.id)
let id = options.id
// let result = common.getNewsDetail(id)
// if(result.code == 200){
// this.setData({
// article:result.news
// })
// }
//检查当前新闻是否在收藏夹中
var newarticle = wx.getStorageSync(id)
if (newarticle != ''){
this.setData({
isAdd:true,
article:newarticle
})
}
//不存在
else
{
let result = common.getNewsDetail(id)
if(result.code == 200){
this.setData({
article:result.news
})
}
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
(3)将各个程序的内核”连接“起来,实现页面与页面之间的跳转
common.js
const news = [
{
id:'',
title:'',
poster:'',
add_date:'',
content:''
},
{
id:'',
title:'',
poster:'',
add_date:'',
content:''
},
{
id:'',
title:'',
poster:'',
add_date:'',
content:' '
}
]
//获取新闻列表
function getNewList()
{
let list = [];
for (var i = 0; i<news.length; i++){
let obj = {};
obj.id = news[i].id;
obj.poster = news[i].poster;
obj.content = news[i].content;
obj.add_date = news[i].add_date;
obj.title = news[i].title;
list.push(obj);//从写得一成不变的到可以改变的来慢慢转变
}
return list;
}
//获取新闻内容
function getNewsDetail(newsID){
let message = {
code:'404',
news:{}
}
for(var i = 0; i < news.length; i++){
//当新闻id匹配到数据库里的ID时便更新新闻(message)
if(newsID == news[i].id){
message.code = '200';
message.news = news[i];
return message;
break;
}
}
}
//暴露接口
module.exports = {
getNewList:getNewList,
getNewsDetail:getNewsDetail
}
(4)测试运行与调试,上传代码,设置为体验版,进入测试阶段