微信小程序初试

前段时间,微信公布了这样一个重磅炸弹 – 小程序。从没想过,原本作为平台之上的产物向上提升成为平台,因为原本的android应用容量不大,作为小程序这样的存在再次存于微信这样的大体量应用上。

文档中介绍的说法是:
微信小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验。
我还是太年轻了,毕竟是微信,敢想也敢做,不得不说腾讯的野心真是大。

原本在他刚出现时就想体验一把了,结果并不是所有人都能体验,而且毕竟刚刚开始还是有许多问题的,所以等到现在~

安装

  1. 小程序有自己的开发软件:
    微信开发者工具
    功能还是很齐全的除了还有些坑以外还是很不错的。当然用webstorm,vscode,甚至atom,sublime也能进行开发。
    他的文件使用了自己的一套格式名称,但依旧是以js进行开发。

  2. 安装之后还需要一些其他的操作才能进入开发
    首先是需要在微信公众平台中进行注册。
    注册完成后进入小程序管理平台,在这里可以管理小程序的权限,查看数据报表,发布小程序等操作。
    接下来在菜单中的进行如下操作:
    开发设置
    保存AppID,等会儿会用到的。
    以及第四步,将需要开发的接口保存在request合法域名内,否则开发时无法进行网络访问。本次还是使用gank的接口进行开发,感谢代码家大大。当然其实这一步不需要也可以,在开发时可以进行一些设置的修改

开发

那么首先,安装完微信开发者工具后打开并登陆,右下角点击添加新项目,这里除了项目目录项目名称外还需要上面步骤中获取到的appId,新建项目。

  1. 目录结构:
    本次使用干货集中营的api。
├── pages                       页面文件夹
│   ├── index                   首页文件夹
│   │   └── index.js            首页js
│   │   └── index.wxml          首页html
│   │   └── index.wxss          首页style
│   ├── main                    主页文件夹
│   │   └── main.js             主页js
│   │   └── main.wxml           主页html
│   │   └── main.wxss           主页style
│   ├── article                 文章页文件夹
│   │   └── article.js          文章页js
│   │   └── article.wxml        文章页html
│   │   └── article.wxss        文章页style
├── utils                       工具文件夹
│   └── Constants.js            全局共享常量
│   └── util.js                 工具类  
├── app.js                      配置js
├── app.json                    小程序配置页
├── app.wxss                    配置style
└── project.config.json         工具配置
  1. 首先是首页:
    效果:
    首页
    点击banner上的图片后:
    首页2
  • index.wxml:

    <view class="container">
      <view class="userinfo">
        <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
        <block wx:else>
          <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>
          <text class="userinfo-nickname">{{userInfo.nickName}}\n小程序试手小Demo</text>
        </block>
      </view>
      <modal no-cancel="true" hidden="{{modalHidden}}" bindconfirm="onConfirmClick">
          <view >
              <image class="modalImage" src="{{meizhi[current].url}}" mode="widthFix"></image>
          </view>
      </modal>
      <swiper class='banner' indicator-dots="true" autoplay="{{isScroll}}" bindchange="EventHandle">
        <block wx:for="{{meizhi}}">
          <swiper-item>
            <image src="{{item.url}}" mode="aspectFit" class="banner-image" bindtap="onImageClick" binderror="imageError"/>
          </swiper-item>
        </block>
      </swiper>
      <button class="enter-main" bindtap="enterMain">进入主页   → </button>
    </view>
    

    上方获取微信头像和昵称是新疆项目时本身自带的内容,修改了一些显示方式和位置,在下方留下足够空间添加了一个banner和一个进入主页的按钮,并且点击banner时能够跳出一个浏览大图的dialog。

  • index.js:

    const app = getApp()
    var Constants = require('../../utils/Constants.js');
    var Util = require('../../utils/util.js');
    
    Page({
      data: {
        userInfo: {},
        hasUserInfo: false,
        modalHidden: true,
        canIUse: wx.canIUse('button.open-type.getUserInfo'),
        meizhi: [],
        current: 0,
        isScroll: true,
      },
      //事件处理函数
      bindViewTap: function() {
        wx.navigateTo({
          url: '../logs/logs'
        })
      },
      onLoad: function () {
        that = this;
        if (app.globalData.userInfo) {
          this.setData({
            userInfo: app.globalData.userInfo,
            hasUserInfo: true
          })
        } else if (this.data.canIUse){
          // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
          // 所以此处加入 callback 以防止这种情况
          app.userInfoReadyCallback = res => {
            this.setData({
              userInfo: res.userInfo,
              hasUserInfo: true
            })
          }
        } else {
          // 在没有 open-type=getUserInfo 版本的兼容处理
          wx.getUserInfo({
            success: res => {
              app.globalData.userInfo = res.userInfo
              this.setData({
                userInfo: res.userInfo,
                hasUserInfo: true
              })
            }
          })
        }
        requestMeizhi();
      },
      getUserInfo: function(e) {
        console.log(e)
        app.globalData.userInfo = e.detail.userInfo
        this.setData({
          userInfo: e.detail.userInfo,
          hasUserInfo: true
        })
      },
      imageError: function (e) {
        this.setData({
          meizhi: ['../logo.png', '../logo.png', '../logo.png', '../logo.png', '../logo.png']
        })
      },
      EventHandle:function(event){
        console.info(event)
          this.setData({
            current: event.detail.current,
          })
      },
      onImageClick: function (event) {
        this.setData({
           modalHidden: false,
           isScroll: false,
        })
      },
      onConfirmClick: function (event) {
        this.setData({
          modalHidden: true,
          isScroll: true
        });
      },
      enterMain: function(e) {
        wx.navigateTo({
          url: Constants.PAGE_MAIN,
        })
      },
    
      /**
         * 生命周期函数--监听页面显示
         */
      onShow: function () {
        this.setData({
          isScroll: true,
        })
      },
      /**
       * 生命周期函数--监听页面隐藏
       */
      onHide: function () {
        this.setData({
          isScroll: false,
        })
      },
    });
    var that;
    
    function requestMeizhi() {
      wx.request({
        url: "https://gank.io/api/data/福利/8/1",
        header: {
          "Content-Type": "application/json"
        },
        success: function (res) {
          if (res == null ||
            res.data == null ||
            res.data.results == null ||
            res.data.results.length <= 0) {
            console.error(Constants.ERROR_DATA_IS_NULL);
            return;
          }
          that.setData({
            meizhi: res.data.results,
          })
        }
      });
    }
    

    包括几个部分,一个是userinfo,这是自带的部分,请求也写好了的。然后是下方banner的请求,数据保存于meizhi数组中,每次只请求前8张。然后是dialog显示的部分,显示时获取当前的资源用于dialog显示,以及停止banner的自动播放。最后是一些点击事件。

  • index.wxss:

    .userinfo {
      display: flex;
      flex-direction: row;
      align-items: center;
      margin-top: -50px;
    }
    
    .userinfo-avatar {
      width: 128rpx;
      height: 128rpx;
      margin: 10rpx;
      border-radius: 50%;
      align-items: right;
    }
    
    .userinfo-nickname {
      margin-left: 15px;
      font-size: 15px;
      color: #666666;
    }
    
    .usermotto {
      margin-top: 50px;
    }
    
    .banner-image{
      display: initial
    }
    
    .banner{
      box-shadow: 1px 0px 6px #cccccc;
      padding: 5px;
      border-radius: 1%;
      margin: 10px;
      margin-top: 40px;
      width: 70%;
      height: 600rpx;
      position: center;
    }
    
    .modalImage{
        margin: auto;
        width: 100%;
        height: 1000rpx
    }
    
    .enter-main{
      box-shadow: 1px 1px 1px #cccccc;
      position: relative;
      border-radius: 0;
      color: #fff;
      font-size: 14px;
      margin-top: 40px;
      background-color: #26a69a;
    }
    

    android里有的cardview,同样这里也可以使用一些style属性表现出来。

  1. 列表主页:
    效果预览:
    列表页
  • main.wxml:

    <view>
        <loading hidden="{{hidden}}">
            加载中...
        </loading>
        <view class="card" wx:for="{{AndroidList}}">
            <view class="title-container" id="{{item.url}}&title={{item.desc}}"  bindtap="onItemClick">
             <image class="tag" src="./text.png" ></image>
              <text class="title">{{item.desc}}</text>
            </view>
            <view class="text-container" id="{{item.url}}&title={{item.desc}}" bindtap="onItemClick">
              <text class="author">作者:{{item.who}}</text>
              <text class="time">发布时间:{{item.publishedAt}}</text>
            </view>
        </view>
    </view>
    

    一个请求时显示的加载中的loading组件,主页上为一个列表。

  • main.js:

    const app = getApp()
    var Constants = require('../../utils/Constants.js');
    var Util = require('../../utils/util.js');
    
    Page({
      data: {
        AndroidList: [],
        hidden: false,
        nextPage: 1,
      },
      onLoad: function () {
        that = this;
        this.setData({
          nextPage: 1,
        })
        requestAndroid(this.data.nextPage);
      },
      onPullDownRefresh(){
        console.info(e.detail)
        this.setData({
          hidden: false,
        })
        requestAndroid(this.data.nextPage);
      },
      onReachBottom(){
        this.setData({
          hidden: false,
        })
        requestAndroid(this.data.nextPage);
      },
      onItemClick(event){
        console.info(event.currentTarget.id)
        wx.navigateTo({
          url: Constants.PAGE_ARTICLE + '?id=' + event.currentTarget.id
        });
      }
    })
    
    var that;
    
    function requestAndroid(page){
      console.info(page);
      wx.request({
        url: 'https://gank.io/api/data/Android/20/' + page,
        header: {},
        success: function (res) {
          res.data.results = modifyTime(res.data.results);
          if (page == 1) {
            that.setData({
              AndroidList: res.data.results,
              nextPage: page + 1,
              hidden: true,
            })
          } else {
            that.setData({
              AndroidList: that.data.AndroidList.concat(res.data.results),
              nextPage: page + 1,
              hidden: true,
            })
          }
        }
      })
    }
    
    function modifyTime(AndroidList){
      for(var i=0;i<AndroidList.length;i++){
        AndroidList[i].publishedAt = AndroidList[i].publishedAt.substring(5,10);
      }
      return AndroidList;
    }
    

    主要是列表的请求以及loading是否显示的标志位,另外添加了一个上拉加载功能。

  • main.wxss:

    .card{
      box-shadow: 0px 1px 2px #999;
      margin: 15px;
      padding: 10px;
    }
    .title-container{
      flex-direction: row;
    }
    .tag{
      width:14px;
      height: 14px;
      margin-right: 5px;
      margin-top: 2px;
    }
    .text-container{
      margin-top: 10px;
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      align-items: center;
    }
    .title{
      font-size: 15px;
    }
    .author{
      color: #999999;
      font-size: 12px;
    }
    .time{
      color: #999999;
      position: right;
      font-size: 12px;
    }
    

    同样列表页使用一个card的样式显示,这里遇到了一个问题,单个item内标题前添加一个小的图标,没有找到text自带的方法,就自己添加了一个image,又想做到标题长度超过两行省略的动作,但是这样的代码会导致图标和标题不在同一行,暂时还未解决这个问题。

  1. 文章页面:
    小程序非常坑爹的不能打开外链,就是他并没有webview这个功能。很气,又拿他没办法。
    效果预览:
    列表页
  • article.wxml:

    <view class="container">
      <text class="description">小程序不能打开外链,这有啥用??</text>
      <text class="title">标题:{{title}}</text>
      <image class="imangry" src="./shengqi.jpg" mode="widthFix"></image>
      <text class="url">链接:{{url}}</text>
      <button class="copy" bindtap='onClick'>{{isCopy?"已复制":"复制"}}</button>
    </view>
    
  • article.js:

    Page({
      data: {
        url: '',
        title: '',
        isCopy: false,
      },
      onLoad: function (options) {
        console.info(options.id);
        console.info(options.title);
        this.setData({
          url: options.id,
          title: options.title,
        })
      },
      onClick: function(event){
        wx.setClipboardData({
          data: this.data.url,
          })
        this.setData({
          isCopy: true,
        })
        wx.getClipboardData({
          success: function(res) {
            console.info(res)
          },
          fail: function(res) {},
          complete: function(res) {},
        })
      }
    })
    

    将列表页由点击事件传递过来的url和标题显示于本页,并提供复制。

  • article.wxss:

    .container{
      padding: 10px;
    }
    .description{
      margin: 20px;
      font-size: 18px;
      color: #555;
      align-items: left;
    }
    .title{
      font-size: 14px;
      align-items: left;
      margin: 10px;
      color: #555;
    }
    .imangry{
      width: 70%;
    }
    .url{
      font-size: 12px;
      color: #777;
      margin: 20px;
    }
    .copy{
      box-shadow: 1px 1px 1px #cccccc;
      position: relative;
      width: 70%;
      border-radius: 0;
      color: #fff;
      font-size: 14px;
      margin-top: 20px;
      background-color: #26a69a;
    }
    

    无奈的添加一个表情。

  1. 各个配置页面只列出修改了的文件:
  • Constants.js:

    //url相关
    var BASE_URL = "https://gank.io/api";
    
    //error相关
    var ERROR_DATA_IS_NULL = "获取数据为空,请重试";
    
    //各个page的URL
    var PAGE_MAIN = "/pages/main/main";
    var PAGE_INDEX = "/pages/index/index";
    var PAGE_ARTICLE = "/pages/article/article";
    
    
    module.exports = {
      BASE_URL: BASE_URL,
      ERROR_DATA_IS_NULL: ERROR_DATA_IS_NULL,
      PAGE_MAIN: PAGE_MAIN,
      PAGE_INDEX: PAGE_INDEX,
      PAGE_ARTICLE: PAGE_ARTICLE
    }
    

    一些全局共享的常量。

  • app.json

    {
      "pages":[
        "pages/index/index",
        "pages/main/main",
        "pages/article/article"
      ],
      "window":{
        "backgroundTextStyle":"light",
        "navigationBarBackgroundColor": "#26a69a",
        "navigationBarTitleText": "干货集中营",
        "navigationBarTextStyle":"white"
      },
      "networkTimeout": {
        "request": 10000,
        "connectSocket": 10000,
        "uploadFile": 10000,
        "downloadFile": 10000
      },
      "debug": true
    }
    

总结

总的来说,小程序开发还是很方便的,作为纯安卓开发者入手也是很快,只需要一些js基础,不过js和java在逻辑上还是很像的。当然他提供的功能还有许多尚未完善,也有许多的坑还没有填上,期待其发展。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值