新闻微信小程序

二、实验步骤

新建项目

新建一个空的微信小程序项目。

配置文件
  1. 在pages页面下配置index相关文件,logs相关文件以及detail相关文件;

  2. 在utils文件夹下配置common.js文件,在image文件夹下导入相关图片素材;

  3. 新建images文件夹,在文件夹下导入所需图片素材;

导航栏设计与实现

使用navigation-bar组件配置上导航栏,使用custom-tab-bar组件配置底部导航栏,使用内置的icon图标,通过onChange函数更新图标

onChange(event) {
      this.updateActiveTabBar(event.detail),
      wx.switchTab({
        url: this.data.list[event.detail].pagePath,
      })
    }
页面设计与实现
首页

设计新闻浏览页面如下:

  1. 使用swiper标签实现新闻轮播图的功能:

    <swiper class="swiper-container" style="height: 415rpx; width: 750rpx; display: block; box-sizing: border-box" indicator-dots indicator-color="white" autoplay interval="3000" circular>
       <block wx:for="{{swiperList}}">
          <swiper-item>  
            <image src="{{item}}" mode="aspectFit" style="width: 750rpx; height: 415rpx; display: inline-block; box-sizing: border-box"></image>  
          </swiper-item> 
        </block>
    </swiper>

    对应JavaScript函数实现功能:

    data: {
        swiperList: [
          'https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/newsimage1.jpg',
          'https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/newsimage2.jpg',
          'https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/newsimage3.jpg'
        ],
    }

  1. 使用van-divider标签分割面板

    <van-divider
      contentPosition="center"
      customStyle="color: #8b8b8b; border-color: #8b8b8b; font-size: 14px;"
    >
      最新消息
    </van-divider>
  2. 使用view标签、image标签和text标签实现新闻列表功能

    </van-divider>
        <view id="news-list">
            <view class='list-item' hover-class="hover-item" hover-start-time="50" hover-stay-time="200" 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}}\n{{news.add_date}}</text>  
        </view>
    </view>

    goToDetail函数和onLoad通过读取common.js中的news接口来实现新闻列表的输出:

    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
        })
      },

    对应的wxss代码,在原有的基础上对界面进行了优化。

    /* 列表项目 */  
    .list-item {  
      display: flex;  
      flex-direction: row;  
      border-bottom: 1rpx solid gray;  
      padding: 10rpx 0; /* 上下间隔 */  
      margin-bottom: 10rpx; /* 底部间隔 */  
      border-radius: 10rpx; /* 圆角 */  
      background-color: #fff; /* 背景色,可选 */  
      transition: all 0.3s ease; /* 过渡效果 */  
    }  
      
    /* 新闻图片 */  
    .list-item image {  
      width: 230rpx;  
      height: 150rpx;  
      margin: 10rpx;  
      border-radius: 14rpx; /* 圆角 */  
    }  
      
    /* 新闻标题 */  
    .list-item text {  
      flex: 1; /* 占用剩余空间 */  
      line-height: 60rpx;  
      font-size: 10pt;  
      color: #333; /* 默认颜色 */  
    }  
      
    .hover-item {  
      background-color: #f9f9f9;  
    }  
     
    新闻页面
    1. 使用view,image标签实现新闻内容的显示。

    <view class ='container'>
      <view class ='title'>{{article.title}}</view>
      <view class ='poster'>
        <image src='{{article.poster}}'mode ='widthFix'></image>
      </view>
      <view class ='content'>{{article.content}}</view>
      <view class='add_date'>时间:{{article.add_date}}</view>
    </view>
    data: {
        comment: '', // 用户输入的评论  
        comments: [], // 存储所有提交的评论
        formattedTime: '', // 用于存储格式化后的时间 
        nickName:'匿名用户',
        src:'/images/back1.png',
        article:{
    ​
        }
      },
      goToDetail: function(e) {
        //获取携带的data-id数据
        let id = e.currentTarget.dataset.id;
        //携带新闻id进行页面跳转
        wx.navigateTo({
          url: '../detail/detail?id=' + id
        })
      },
      getMyInfo:function(e){
        let info = e.detail.userInfo;
        this.setData({
          nickName:info.nickName,
          src:info.avatorUrl
        })
      },
    ​
      onLoad:function(options) {
        let id = options.id
        var article = wx.getStorageSync(id)
        if(article != ''){
          this.setData({article:article,
            isAddsc:true,
          })
        }
        else{
          let result = common.getNewsDetail(id)
          if(result.code == '200'){
            this.setData({article:result.news,
              isAddsc:false,
            })
          }
        }
      },
    1. 使用button标签实现收藏和取消收藏功能。

    <view class="dzpl">
      <button wx:if ='{{isAddsc}}' plain bindtap='cancelFavorites'>★已收藏</button> 
      <button wx:else plain bindtap='addFavorites'>☆ 收藏</button> 
    </view>

    通过addFavorites和addFavorites函数,结合if判断语句和isAddsc的状态实现收藏和取消收藏功能。

      addFavorites:function(options){
        let article =this.data.article;
        wx.setStorageSync(article.id,article);
        this.setData({isAddsc:true });
      },
     addFavorites:function(){
        let article = this.data.article;
        wx.removeStorageSync(article.id);
        this.setData({isAddsc:false });
      },
    我的主页
    1. 使用image、text和button标签实现用户登录功能,读取并显示用户的头像和昵称

      <view id='myLogin'>
          <block wx:if ='{{isLogin}}'>
            <image id='myIcon'src='{{src}}'></image>
            <text id='nickName'>{{nickName}}</text>
        </block>
        <button wx:else open-type="getUserInfo" bindgetuserinfo="getMyInfo">未登录,点此登录</button> 
      </view>

      对应的JavaScript代码:

      Page({
        data: {
          nickName:'未登录',
          src:"/images/back1.png",
          newsList:[{
          }],
          myList:[{
          }],
          num: 0,
          num2: 0
        },
        getMyInfo:function(e){
          let info = e.detail.userInfo;
          this.setData({
            isLogin:true,
            src:info.avatorUrl,
            nickName:info.nickName
          })
          this.getMyFavorites();
        },
      1. 使用text、view、image标签实现我的收藏功能。

        <view id="myFavorites">
          <text>我的收藏</text>
          <text id="number"> {{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}}" mode=""/>
              <text bindtap = 'goToDetail' data-id = '{{news.id}}'>◆ {{news.title}}\n{{news.add_date}}</text>
            </view>
          </view>
        </view>

        JavaScript代码:

        getMyFavorites:function(){
            let info =wx.getStorageInfoSync();
            let keys =info.keys;
            let num =keys.length-1;
            let myList =[];
            
            for(var i = 0;i<num;i++){
              let obj =wx.getStorageSync(keys[i]);
              myList.push(obj);
            //将新闻添加到数组中
            }
            //更新收藏列表
            this.setData({
            newsList:myList,
            num:num
            });
            },
            goToDetail: function(e) {
              //获取携带的data-id数据
              let id = e.currentTarget.dataset.id;
              //携带新闻id进行页面跳转
              wx.navigateTo({
                url: '../detail/detail?id=' + id
              })
            },

        wxss代码:

        #myLogin{
          background-color:#8B1A1A; height:350rpx; display:flex;
          flex-direction:column; align-items:center; justify-content:space-around;
          }
        #myIcon{
          width:200rpx;
          height:200rpx;
          border-radius:50%;
          }
        #nickName{
          color:white;
          font-size: 20px;
          font-weight: bold; /* 加粗字体 */ 
          }
        #myFavorites{
          padding:20rpx;
          background-color:#ffffff; 
          height: 800rpx;
          margin-top: 20rpx;
          }
        #myWorks{
            padding:20rpx;
            background-color:#ffffff; 
            height: 800rpx;
            margin-top: 20rpx;
          }

    ~ 额外添加功能

    在新闻详情页面实现评论功能,功能包括:

    1. 检测评论输入框内容为空时,进行提示“内容不能为空!”;

    2. 发表评论后附带时间戳;

    3. 并获取用户头像和昵称进行显示;

    <!-- 评论功能 -->
    <view class="container2">  
      <view class="input-area">  
        <textarea placeholder="请输入你的评论..." bindinput="inputChange" data-key="comment" value="{{comment}}"></textarea>  
        <button bindtap="submitComment" open-type="getUserInfo" bindgetuserinfo="getMyInfo">提交评论</button>  
      </view>  
      <view class="comment-list">  
      <van-divider
      contentPosition="center"
      customStyle="color: #8b8b8b; border-color: #8b8b8b; font-size: 14px;">
      评论区
      </van-divider>
        <block wx:for="{{comments}}" wx:key="index">  
          
          <view class="comment-item">  
            <!-- {{item.content}} - {{item.formattedTime}}  -->
            <image id="pltx" src="{{src}}" mode=""/>
            {{nickName}}:{{item}}  
            <text id="pltime">\n {{formattedTime}}</text>
          </view>  
        </block>  
      </view>  
    </view>

    javaScript代码:

      // 处理输入框内容变化  
      inputChange: function(e) {  
        const key = e.currentTarget.dataset.key;  
        this.setData({  
          [key]: e.detail.value  
        });  
      },  
    ​
    // 提交评论  
      submitComment: function() {  
        if (this.data.comment.trim() !== '') {  
          const newComments = [...this.data.comments, this.data.comment];  
          this.setData({  
            comments: newComments,  
            comment: '' // 清空输入框  
          });  
          const timestamp = 1609459200000; // 例如:2021年1月1日 00:00:00 UTC 的时间戳  
        // 调用函数处理时间戳  
          this.setData({  
            formattedTime: this.formatTime(timestamp)  
          });  
        } else {  
          wx.showToast({  
            title: '评论不能为空',  
            icon: 'none'  
         });  
        }  
      },  
      formatTime: function(timestamp) {  
        const date = new Date(timestamp);  
        const year = date.getFullYear();  
        const month = String(date.getMonth() + 1).padStart(2, '0');  
        const day = String(date.getDate()).padStart(2, '0');  
        const hour = String(date.getHours()).padStart(2, '0');  
        const minute = String(date.getMinutes()).padStart(2, '0');  
        const second = String(date.getSeconds()).padStart(2, '0');  
        return `${year}-${month}-${day}`;  
      },

    wxss代码:

    .bindinput{
      border: 2px solid rgb(105, 105, 105);
      padding: 8px;
      width: 160px;
      height: 12px;
      border-radius: 8px; 
    }
    button {  
      color: white; 
      background-color: #920000; 
      font-size: 16px; 
      text-align: center;
      border: none; 
      border-radius: 8px; 
      cursor: pointer;  
      margin-left: 8px;
      height: 42px;
    }
    ​
    #pltime{
      color: #808080; /* 灰色 */  
      text-align: right;
      font-size: 12px; 
    }
    #plp{
      color: #acacac; /* 灰色 */  
      text-align: right; 
      font-size: 18px; 
    }
    ​
    .dzpl {  
      display: flex; 
      flex-direction: row; 
      align-items: center; 
      justify-content: space-between;   
      padding: 0px; 
    }  
      
    .dzpl button {  
      margin: 0px 140px; 
    }
    #pltx{
      width: 70rpx;  
      height: 70rpx;  
      border-radius: 15rpx; /* 圆角 */  
      margin-bottom: -20rpx;
    }
  1. 在我的界面添加创作者功能,可以自行定义并发表文章,使用云开发,云数据库进行存储。

    <view class="container">  
      <picker mode="selector" value="{{stuIndex}}" range="{{stuName}}" range-key="name" bindchange="bindSchoolChange">  
        <view class="picker" style="color: white;">  
          新闻类型:{{stuName[stuIndex].name}}  
        </view>  
      </picker>  
    ​
      <picker mode="selector" value="{{schoolIndex}}" range="{{schools}}" range-key="name" bindchange="bindSchoolChange">  
        <view class="picker" style="color: white;">  
          是否原创:{{schools[schoolIndex].name}}  
        </view>  
      </picker>  
    ​
      <picker mode="selector" value="{{subjectIndex}}" range="{{subjects}}" range-key="name" bindchange="bindSubjectChange">  
        <view class="picker" style="color: white;">  
          设置权限:{{subjects[subjectIndex].name}}  
        </view>  
      </picker> 
      <view class="noUse"></view>
    ​
    <!-- pages/myWorks/myWorks.wxml -->  
    <view class="container">  
      <view class="input-container">  
        <input type="text" placeholder="请输入题目" class="title-input" maxlength="100" bindinput="handleTitleInput"/>  
      </view>  
      <view class="input-container">  
        <textarea placeholder="请输入文章内容" class="content-input" bindinput="handleContentInput"></textarea>  
      </view>  
      <image class="uploaded-image" src="{{imageUrl}}" mode="widthFix" hidden="{{!imageUrl}}"></image>  
    ​
      <button bindtap="uploadImage" style="color: white;">上传图片</button>  
      <button bindtap="saveToWorks" style="color: white;">保存到我的作品</button>  
      </view>
    </view>

    JavaScript代码:

      saveToWorks: function() {  
        const db = wx.cloud.database(); 
        const collection = db.collection('works'); 
        let newData = {  
          title: this.data.title,  
          content: this.data.content,  
          imageUrl: this.data.imageUrl, 
          createTime: new Date().getTime(),  
        };  
      
        // 保存到数据库  
        collection.add({  
          data: newData,  
          success: res => {  
            // 保存成功的回调  
            wx.showToast({  
              title: '保存成功',  
              icon: 'success',  
              duration: 2000  
            });  
          },  
          fail: err => {  
            // 保存失败的回调  
            wx.showToast({  
              title: '保存失败',  
              icon: 'none',  
              duration: 2000  
            });  
            console.error(err);  
          }  
        });  
      }, 

三、程序运行结果

除原始的以下九项功能外,还添加了评论发表和创作者中心功能,可以实现自己编辑发表文章,并进一步优化了页面结构。

(1)首页需要包含幻灯片播放效果和新闻列表;

(2)幻灯片至少 要有3幅图片自动播放;

(3)点击新闻列表可以打开新闻全文;

(4)阅读新闻全文的页面需要显示新闻标题、图片、正文和日 期;

(5)允许 点击按钮将当前阅读的新闻添加到本地收藏夹中;

(6)已经收藏过的新 闻也可以点击按钮取消收藏;

(7)未登录状态下显示登录按钮,用户点击以后可以显示;

(8)登录后读取当前用户的收藏夹,展示收藏的新闻列表;

(9)收 藏夹中的新闻可以直接点击查看内容;

(10)未登录状态下收藏夹显示为空

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值