zoukankan      html  css  js  c++  java
  • 微信小程序开发

    微信小程序开发

    • 开发环境搭建
    • 应用架构解析
    • 逻辑层
      • 注册程序
      • 注册页面
      • 模块化
      • API
    • 视图层
      • 数据绑定
      • 条件渲染和列表渲染
      • 模块
      • 事件
      • 引用
      • WXSS
      • 组件

      之前觉得微信小程序已经不行了,似乎没有任何生机,很多人可能都不知道有小程序这回事吧,但是最近在做vue的项目,发现美团和饿了么的微信公众号都连接到了小程序,主要特点就是非常像原生app,可以发送到桌面,使用感受就如同原生app,感觉还是很舒服的,所以觉得有必要尝试一下微信小程序的开发。。。嗯,现在已经是凌晨3点了,小程序啊。 

      根据上述的目录,我们主要讨论一下开发环境的搭建、应用架构、逻辑层、视图层。 

    一、开发环境搭建

      官网有工具的下载地址,我们直接点击下载即可,目前的最新版本是2017年5月26日更新的。 看来腾讯还是不会轻易放弃小程序的。 当然我们需要提前注册一下微信小程序的appid,然后登陆即可, 值得注意的是,如果我们使用的是教老版本的微信开发者工具,并且你已经绑定了微信公众号,那么就不能进入到小程序开发的界面。 进入之后,我们就可新建一个项目,使用微信小程序的快速启动工具构建一个具有基本架构的项目,就类似于vue的vue-cli一样。

      我们进入之后,可以看到基本的框架如下所示:

      通过这些文件,就生成了基本的小程序实例。  

       点击编辑即可进入编辑代码的界面,编辑完之后,我们可以通过点击左下角的编译按钮来编译,这样就可以看到修改代码之后的效果了!

    二、 应用架构解析

      我们看看最简单的小程序的目录结构:

    • pages
      • index
        • index.js
        • index.wxml
        • index.wxss
      • logs
        • logs.js
        • logs.json
        • logs.wxml
        • logs.wxss
    • utils
      • util.js
    • app.js
    • app.json
    • app.wxss

      首先比较突出的就是 wxss 和 wxml了, 其实就相当于css和html, 另外还有json的使用,主要是来配置小程序的,如颜色等。 毫无疑问app.js就是入口文件了。  不难看出 pages 就表示多个页面了。  还有一个公用的工具函数 util.js。如下所示:

    function formatTime(date) {
      var year = date.getFullYear()
      var month = date.getMonth() + 1
      var day = date.getDate()
    
      var hour = date.getHours()
      var minute = date.getMinutes()
      var second = date.getSeconds()
    
    
      return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
    }
    
    function formatNumber(n) {
      n = n.toString()
      return n[1] ? n : '0' + n
    }
    
    module.exports = {
      formatTime: formatTime
    }

    这段代码也非常简单,就是把当前的时间用某种形式标准化。 

      每一个小程序页面都是由相同路径下同名的四个同名、不同后缀的文件所组成的。如这里的 index.wxml、index.wxss、index.js、index.json。 

      那么我们知道wxml是页面结构、wxss是页面的样式、js是逻辑代码、json这个配置文件呢? 实际上json文件也是样式的配置,只是控制的属于app的,不是页面的,如最上面的导航条等等。  并且如果我们在一个页面的json文件中如果设置了和app.json文件中相同的内容,那么就会覆盖掉app.json中相同的配置样式。 

      注意: json文件同js文件是完全不同的,json是一种非常严格的文件格式。 

      其中的index页即主页,log页即日志页。如下是默认的主页:

      下面是默认的日志页:

      

      这是我对小程序启动的一些基本的记录。 

      如果我们把log.json文件中添加下面的内容(原来是没有内容的,使用的设置都是app.json文件中的设置): 

    {
      "backgroundTextStyle": "blue", 
      "navigationBarBackgroundColor": "blue",
      "navigationBarTextStyle": "blue",
      "navigationBarTitleText": "查看启动日志"
    }

      那么日志页就是这样的:

      我们注意看一下 app.json中的内容:

    {
      "pages":[
        "pages/index/index",
        "pages/logs/logs"
      ],
      "window":{
        "backgroundTextStyle":"light",
        "navigationBarBackgroundColor": "red",
        "navigationBarTitleText": "WeChat",
        "navigationBarTextStyle":"red"
      }
    }

      可以看到必须要在app.json中说明这个项目一共包含哪些页面,并且通过window的设置来告诉我们这是全局的。 注意:在index.json和log.json中最好不要使用这种全局的配置或压根就不要使用。

      我们先说说单个页面吧。 微信小程序要求页面文件名和目录的名称必须一致。比如这里的logs目录对应的一堆logs开头的文件,所以这样我们在使用的时候就不需要在js中import了。

      下面是js文件和模板文件:

    //index.js
    //获取应用实例
    var app = getApp()
    Page({
      data: {
        motto: 'Hello World',
        userInfo: {}
      },
      //事件处理函数
      bindViewTap: function() {
        wx.navigateTo({
          url: '../logs/logs'
        })
      },
      onLoad: function () {
        console.log('onLoad')
        var that = this
        //调用应用实例的方法获取全局数据
        app.getUserInfo(function(userInfo){
          //更新数据
          that.setData({
            userInfo:userInfo
          })
        })
      }
    })

     这个js也比较容易看,就是在点击之后进入log页面,在load(生命周期的钩子函数)后开始使用app这个全局实例的getUserInfo全局方法来获取到本地的userInfo, 并使用setData来修改data里的内容,这里也用了var that = this的形式,因为this指向的时app。 

    <!--index.wxml-->
    <view class="container">
      <view  bindtap="bindViewTap" class="userinfo">
        <image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>
        <text class="userinfo-nickname">{{userInfo.nickName}}</text>
      </view>
      <view class="usermotto">
        <text class="user-motto">{{motto}}</text>
      </view>
    </view>

    其中 bindViewTap就是绑定一个tap事件,当我们点击进入的时候就可以引导到: 

    wx.navigateTo({
    url: '../logs/logs'
    })

    所以就进入了 logs 页面。 

    其中的 Page 是框架提供的全局方法。 和vue类似的mvvm框架一样,采用了数据绑定、事件绑定、生命周期、路由这些。  下面是一个logs.json文件:

    {
        "navigationBarTitleText": "查看启动日志"
    }

    即json文件就是做一些基础的配置的。 因为小程序毕竟还是运行在微信上的, 所以这些配置文件log就是改一下标题栏颜色、文字之类的东西。   

    而通过getApp()我们可以得到app实例,这个实例中包含了一些全局的方法。 

    嗯,这个hello world级别的就是这么简单。

    三、逻辑层

      微信小程序的逻辑层就下面这些:

    • 注册程序
    • 注册页面
    • 模块化
    • API

     1. 注册程序

      注册程序是提供给我们的,是一个全局的App方法(传入一个对象), 这个作为应用的主入口,当然是写在app.js这个入口文件中的,可以监听一些应用生命周期的事件,然后配置一些全局变量。 

    //app.js
    App({
      onLaunch: function () {
        //调用API从本地缓存中获取数据
        var logs = wx.getStorageSync('logs') || []
        logs.unshift(Date.now())
        wx.setStorageSync('logs', logs)
      },
      getUserInfo:function(cb){
        var that = this
        if(this.globalData.userInfo){
          typeof cb == "function" && cb(this.globalData.userInfo)
        }else{
          //调用登录接口
          wx.login({
            success: function () {
              wx.getUserInfo({
                success: function (res) {
                  that.globalData.userInfo = res.userInfo
                  typeof cb == "function" && cb(that.globalData.userInfo)
                }
              })
            }
          })
        }
      },
      globalData:{
        userInfo:null
      }
    })

      这里的onLaunch是一个生命周期的钩子,然后getUserInfo相当于一个全局的方法(使用getApp()获取实例以后就可以调用,在Index.js里的), 而globalData作为app的属性自然就担任了全局变量这个角色了, 然后还使用了本地存储的api,来提高用户体验。

      

    2. 注册页面  

      Page方法就是用于注册页面的,页面也会有一些生命周期的钩子等。 另外,Page还有一个事件: 即onPullDownRefresh,即页面下拉刷新。 

        
    <view bindtap="viewTap"> click me </view>
    Page({
      viewTap: function() {
        console.log('view tap')
      }
    })

      除了使用bind + event作为属性名还可以使用catch + event, 区别在于后者可以继续阻止冒泡。 事件绑定函数同样还有一个参数event, 但是event包含了该节点的星星所以很快就可以完成逻辑定制。 

    3. 模块化

      目前的小程序并不支持node_modules的导入, 所以要用就可能复制过去,另外和webpack的模块化是类似的, 即小程序各个page的作用域是独立的,如果要对外暴露接口的话需要使用模块导出。

     

    // common.js
    function sayHello(name) {
      console.log(`Hello ${name} !`)
    }
    function sayGoodbye(name) {
      console.log(`Goodbye ${name} !`)
    }
    module.exports.sayHello = sayHello
    // module.exports = { sayHello: sayHello }

    这里要说的是: 微信小程序是完全支持es6语法的,不用担心兼容性的问题啦!  

    4. API

      小程序的API都通过wx这一个全局对象来访问的, 和运行在浏览器的JavaScript类似,wx也提供了如http请求、本地存储、绘图这一类的api, 除此之外,还有一些更为本地化的api,比如拨打电话、重力感应、交互反馈、支付这样的api。 可以查询小程序api。其实真的是非常方便的。

     

    四、视图层  

      微信小程序也是自制了一套标签,成为WXML(weixin Markup Language), 同样也是基于组件的。 与之配合的样式表称为 WXSS (weixin Style Sheet)。 

    1. 数据绑定

      数据绑定采用Mustache语法,也就是双大括号。值的注意的是大括号里支持一些ES6的表达式,比如说展开语法和简化的对象属性写法

        
    <template is="objectCombine" data="{{...obj1, ...obj2, e}}"></template>
    Page({
      data: {
        obj1: {
          a: 1,
          b: 2
        },
        obj2: {
          c: 3,
          d: 4
        },
        e: 5
      }
    })

    这样得到的结果就是: {a: 1, b: 2, c: 3, d: 4, e: 5}。  

    2. 条件渲染和列表渲染

    条件渲染和列表渲染很简单,就像vue.js里两个指令v-ifv-for,小程序里用的是wx:ifwx:for,用两个简单的DEMO过一下

    <!-- 条件渲染 -->
    <view wx:if="{{length > 5}}"> 1 </view>
    <view wx:elif="{{length > 2}}"> 2 </view>
    <view wx:else> 3 </view>
    <!-- 列表渲染 -->
    <view wx:for="{{array}}">
      {{index}}: {{item.message}}
    </view>

    3. 模板

      即我们需要定义一个模板来复用。

    <template name="msgItem">
      <view>
        <text> {{index}}: {{msg}} </text>
        <text> Time: {{time}} </text>
      </view>
    </template>
    <template is="msgItem" data="{{...item}}"/>

    4. 事件

      

    前面简单提了一下事件的两种绑定方式,现在简单列一下wx支持的一些冒泡事件名称:

    • touchstart 手指触摸动作开始
    • touchmove 手指触摸后移动
    • touchcancel 手指触摸动作被打断,如来电提醒,弹窗
    • touchend 手指触摸动作结束
    • tap 手指触摸后马上离开
    • longtap 手指触摸后,超过350ms再离开

    其余的事件都是不冒泡的,那些就因组件而异了,比如说<form />的submit等。然后之前也提过,事件参数就只有一个event,所以要传值的时候data-属性就显得很重要了,因为事件对象可以获取到一个dataset对象,对应都是就是各个自定义的data-属性。

    5. 视图的引用

    就像ejs里会有include一样,模板语言肯定是会有引用嵌套的功能的,wx里提供了两种方法,分别是importinclude,见DMEO

    <!-- item.wxml -->
    <template name="item">
      <text>{{text}}</text>
    </template>
    <import src="item.wxml"/>
    <template is="item" data="{{text: 'forbar'}}"/>

    也可以是include,

    <!-- index.wxml -->
    <include src="header.wxml"/>
    <view> body </view>
    <!-- header.wxml -->
    <view> header </view>

    6. wxss

        继承了css的大部分特性。 

      

      

     

      

      

  • 相关阅读:
    LightOJ 1313
    LightOJ 1285
    [坑] treap
    HDU 4511 小明系列故事——女友的考验 (AC自动机+DP)
    ZOJ 3765 Lights (伸展树splay)
    HDU 4818 RP problem (高斯消元, 2013年长春区域赛F题)
    SGU 104. Little shop of flowers (DP)
    HDU 3472 HS BDC (混合图的欧拉路径判断)
    POJ 1386 Play on Words (有向图欧拉路径判定)
    微信小程序上架需要增值电信业务经营许可证ICP?
  • 原文地址:https://www.cnblogs.com/zhuzhenwei918/p/6939391.html
Copyright © 2011-2022 走看看