• 开发一个微信小程序(3):编写公众号文章列表


    本篇讲一下如何把微信公众号中发布的文章移植到小程序中

    具体展示内容以及列表样式,我参考了订阅号助手中的「历史图文素材」,如下

    所以在小程序中需要实现以下功能:

    1. 获取已发布的素材;
    2. 将数据渲染到前端,每条数据包含标题、概要、图片(这些字段接口都有返回);
    3. 调整列表样式;
    4. 点击文章跳转至详情;

    1、获取已发布的素材

    在之前一篇文章中介绍了如果通过接口获取公众号素材,传送门:开发一个微信小程序(1):获取文章列表

    打开根目录下app.json,先创建2个文件夹 wx_articlewx_article_detail

    最开始我的想法是通过接口来实时拿到微信公众号的文章,但是经过一番操作发现行不通,原因是:微信不允许直接在小程序中调用微信公众号的接口(主要是会暴露一些敏感信息,例如AppID)

    然后我把调用公众号接口相关的功能写到了服务端(用flask即可),本地部署好服务后,尝试在小程序中调用自己定义的接口,结果发现小程序不允许直接调用ip地址,需要配置域名

    接着我修改本地host文件,把ip和域名做了一个映射,使用postman通过域名调用flask接口时,提示成功,然后尝试在小程序调用,发现依然不行,这次提示我的域名不安全,不是https

    接着我又去阿里云购买了一个域名,同时申请了一个免费的ssl证书,把域名和我本地ip绑定,同时修改flask启动方式,这样就能用https访问接口了,经过postman试验调用成功,然后尝试在小程序调用,发现又失败了,这次提示我的域名没有进行备案?

    心态快炸了,没想到卡在了这里,微信小程序的限制也太多了

    最后我决定先跳过这里,把公众号文章的数据提取到一个js文件中,然后在小程序中,直接去读这个js文件来获取数据,这样我就不必卡在这里,可以继续进行后面的学习了~

    1.1 创建一个js文件,存放文章数据

    在根目录下创建一个文件夹 data,然后在data下创建一个文件wx_article_data.js

    里面的数据,是我通过接口拿到的,都粘贴到了这个文件中

    1.2 读取并处理数据

    打开 /pages/wx_article/wx_article.js,编辑如下代码

    // pages/wx_article/wx_article.js
    
    //引入本地数据
    var wxArticleData = require("../../data/wx_article_data.js")
    
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        page: 1,
        posts: [],
        isloading: false,  //定一个标识符,默认为false,表示当前没有发送请求
      },
    
      //提取本地存储的微信公众号数据
      get_wx_article() {
    
          //开始取数据时,将isloading置为true
          this.setData({
            isloading: true  //为true时,表示正在发起请求
          })
    
          //展示loading效果
          wx.showLoading({
            title: '努力加载中...',
          })
        if (this.data.page === 1) {
          this.setData({
            posts: [...this.data.posts, ...wxArticleData.wxData.slice(0, 10)]  //第一次取前10个
          })
        }
        else {
          this.setData({
            //后续当page>1时,从下标开始取10个
            posts: [...this.data.posts, ...wxArticleData.wxData.slice(this.data.page*10-10, this.data.page*10)]
          })
        }
        
        //取完数后
        wx.hideLoading()  //隐藏loading效果
        //取数后,将isloading置为false
        this.setData({
          isloading: false  
        })
        
      },
    
      //通过编程式导航跳转到非tabBar页面
      gotodetail(e) {
        // console.log(e);
        const item = e.currentTarget.dataset['item'];
        // console.log(item);
        const article_url = item.url;
        const jpg_url = item.jpg_url;
        wx.navigateTo({
          url: '/pages/wx_article_detail/wx_article_detail?article_url='+
          encodeURIComponent(article_url)+'&jpg_url='+encodeURIComponent(jpg_url)
        })
      },
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad(options) {
        this.get_wx_article()
      },
    
      /**
       * 生命周期函数--监听页面初次渲染完成
       */
      onReady() {
        wx.setNavigationBarTitle({
          title: '公众号文章',  //把这个页面的标题自定义设置一下
        })
      },
    
      /**
       * 生命周期函数--监听页面显示
       */
      onShow() {
    
      },
    
      /**
       * 生命周期函数--监听页面隐藏
       */
      onHide() {
    
      },
    
      /**
       * 生命周期函数--监听页面卸载
       */
      onUnload() {
    
      },
    
      /**
       * 页面相关事件处理函数--监听用户下拉动作
       */
      onPullDownRefresh() {
        //请求前,需要重置参数
        this.setData({
          page: 1,
          posts: [],
        })
        this.get_wx_article()  //下拉刷新调用这个函数,重新发起请求
        wx.stopPullDownRefresh()  //真机上,刷新完后,调用这个方法,关闭下拉刷新
      },
    
      /**
       * 页面上拉触底事件的处理函数
       */
      onReachBottom() {
        if(this.data.isloading) return  //如果isloading为true,则退出onReachBottom这个方法
        this.setData({
          page: this.data.page + 1  //上拉触底时,给页码加1,这样再发起请求时,就请求到了下一组的数据
        })
        this.get_wx_article()  //调用获取随笔的方法
      },
    
      /**
       * 用户点击右上角分享
       */
      onShareAppMessage() {
    
      }
    })

    主要是 get_wx_article() 方法,它的作用是读取 wx_article_data.js 中的数据并进行处理

    每次提取10个,上拉页面触底时,加载下一组数据

    data中定义了一个参数page,如果page=1,则取前10个数据

    if (this.data.page === 1) {
          this.setData({
            posts: [...this.data.posts, ...wxArticleData.wxData.slice(0, 10)]  //第一次取前10个
          })
        }

    如果page>1, 则从下标开始往后取10个

     else {
          this.setData({
            //后续当page>1时,从下标开始取10个
            posts: [...this.data.posts, ...wxArticleData.wxData.slice(this.data.page*10-10, this.data.page*10)]
          })
        }

    在上拉触底事件中,给page+1

    /**
       * 页面上拉触底事件的处理函数
       */
      onReachBottom() {
        if(this.data.isloading) return  //如果isloading为true,则退出onReachBottom这个方法
        this.setData({
          page: this.data.page + 1  //上拉触底时,给页码加1,这样再发起请求时,就请求到了下一组的数据
        })
        this.get_wx_article()  //调用提取本地存储的微信公众号数据的方法
      },

    2、将数据渲染到前端 & 调整列表样式

    打开 /pages/wx_article/wx_article.wxml

    <!--pages/wx_article/wx_article.wxml-->
    <!-- <text>pages/wx_article/wx_article.wxml</text> -->
    
    <!-- 文章列表 -->
    <view class="box">
        <view class="items" wx:for="{{posts}}" wx:key="media_id" bindtap="gotodetail" data-item="{{item}}">
              <view class="father">
                <view class="son1">
                  <text class="title">{{item.title}}</text>
                  <text class="digest">{{item.digest}}</text>
                </view>
                <view class="son2">
                  <image src="{{item.jpg_url}}" mode="aspectFill"></image>
                </view>
              </view>
              <!-- <view class="bottom-element">
                  <text class="little-text">阅读:({{item.ViewCount}}) 评论:({{item.CommentCount}})</text>
                  <text class="post-date">{{tools.splitDate(item.PostDate)}}</text>
              </view> -->
        </view>
    </view>

     用for循环渲染数据,同时添加编程式导航,使得点击文章能够跳转至详情,使用bindtap绑定事件gotodetail

    同时传递一个参数itemitem的值就是for循环的item对象,写法data-item="{{item}}"

    gotodetail()方法如下

      //通过编程式导航跳转到非tabBar页面
      gotodetail(e) {
        // console.log(e);
        const item = e.currentTarget.dataset['item']; //接收页面传来的参数item
        // console.log(item);
        const article_url = item.url;  //获取item中的url
        const jpg_url = item.jpg_url; // 获取item中的jpg_url
        wx.navigateTo({
          url: '/pages/wx_article_detail/wx_article_detail?article_url='+
          encodeURIComponent(article_url)+'&jpg_url='+encodeURIComponent(jpg_url)
          //这里对文章url和图片url做了转码处理,因为url中包含很多特殊字符,直接传递会丢失
        })
      },

    接下来再调整样式

    主要是把标题放上面,概要放下面,图片放右侧

    打开/pages/wx_article/wx_article.wxss

    /* pages/wx_article/wx_article.wxss */
    
    .items {
      height: 150rpx;
      border-bottom: 15rpx solid #efefef;
      /* border-radius: 8rpx; */
      line-height: 50rpx;
      /* margin: 10rpx; */
      position: relative;
      padding-top: 20rpx;
      background-color: rgb(255, 255, 255);  /*设置每张小卡片的颜色*/
    }
    
    .father{
      display: flex;
    }
    .son1{
       80%;
      display: flex;
      flex-direction: column;  /*使元素纵向布局(默认为横向)*/
    }
    .son2{
       20%;
      display: flex;
    }
    image{
      height: 90%;
       100%;
      margin-right: 20rpx;
      margin-left: 10rpx;
    }
    
    .title{
      font-size:32rpx;
      margin-left: 20rpx;
      margin-right: 20rpx;
      display: -webkit-box;  /*设置为弹性盒子*/
      overflow:hidden; /*超出隐藏*/
      text-overflow: ellipsis; /*显示省略号*/
      -webkit-line-clamp: 1; /*多少行后显示省略号,这里设置为第一行超出后显示省略号*/
      word-break:break-all; /*强制英文单词自动换行,可要可不要*/
      -webkit-box-orient: vertical; /* 从上到下垂直排列子元素*/
    }
    
    .digest {
      font-size: 27rpx;
      color: gray;
      margin-top: 30rpx;
      margin-left: 20rpx;
      display: -webkit-box;  /*设置为弹性盒子*/
      overflow:hidden; /*超出隐藏*/
      text-overflow: ellipsis; /*显示省略号*/
      -webkit-line-clamp: 1; /*多少行后显示省略号,这里设置为第一行超出后显示省略号*/
      word-break:break-all; /*强制英文单词自动换行,可要可不要*/
      -webkit-box-orient: vertical; /* 从上到下垂直排列子元素*/
    }

    3、文章详情

    如果我们拿到公众号文章的url后,可以使用<web-view>标签来展示详情

    前提是要把公众号与小程序进行关联,打开微信公众平台,找到如下位置进行关联即可

     

    对应代码如下

    /pages/wx_article_detail/wx_article_detail.js

    // pages/wx_article_detail/wx_article_detail.js
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        query: {} ,// 接收navigator传来的参数
        article_url: "",
        jpg_url: ""
      },
    
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad(options) {
        this.setData({
          query: options,  //把navigator传来的参数赋给query
          article_url: decodeURIComponent(options.article_url),
          jpg_url: decodeURIComponent(options.jpg_url)
        })
      },
    
      /**
       * 生命周期函数--监听页面初次渲染完成
       */
      onReady() {
        wx.setNavigationBarTitle({
          title: '文章详情',  //把这个页面的标题自定义设置一下
        })
      },
    
      /**
       * 生命周期函数--监听页面显示
       */
      onShow() {
    
      },
    
      /**
       * 生命周期函数--监听页面隐藏
       */
      onHide() {
    
      },
    
      /**
       * 生命周期函数--监听页面卸载
       */
      onUnload() {
    
      },
    
      /**
       * 页面相关事件处理函数--监听用户下拉动作
       */
      onPullDownRefresh() {
    
      },
    
      /**
       * 页面上拉触底事件的处理函数
       */
      onReachBottom() {
    
      },
    
      /**
       * 用户点击右上角分享
       */
      onShareAppMessage() {
    
      }
    })

     pages/wx_article_detail/wx_article_detail.wxml 

    <!--pages/wx_article_detail/wx_article_detail.wxml-->
    <web-view src="{{article_url}}"></web-view>
    <!-- <text>{{article_url}}</text> -->

    OK,这样就完成了公众号文章列表功能页面

     

     

     
  • 相关阅读:
    Manacher算法(一个字符串中找到最长回文子串)
    tomcat之负载均衡(apache反响代理tomcat)
    【转】Tomcat集群Cluster实现原理剖析
    负载均衡集群之LVS持久链接
    负载均衡集群之LVS的DR模型详解(Diretor Routing)
    负载均衡集群之LVS算法和模型
    负载均衡集群之LVS配置命令
    mysql之6备份恢复
    mysql之主从复制
    haproxy之配置文件解析
  • 原文地址:https://www.cnblogs.com/hanmk/p/16359534.html
Copyright © 2020-2023  润新知