为了账号安全,请及时绑定邮箱和手机立即绑定

微信小程序初探

小程序是一种不需要下载安装即可使用的应用,它实现了应用「触手可及」的梦想,用户扫一扫或搜一下即可打开应用。也体现了「用完即走」的理念,用户不用关心是否安装太多应用的问题。应用将无处不在,随时可用,但又无需安装卸载。 ——张小龙

微信小程序框架

https://img1.sycdn.imooc.com//5b57e51d000199cc08100467.jpg

微信小程序分为视图层和逻辑层,视图层包含WXML(类似HTML)、WXSS(类似css),逻辑层包含javascript文件。视图层通过事件通知逻辑层,而逻辑层通过控制data来更新视图。此外,微信还提供了API、组件、配置文件,使微信小程序的开发更加简单。

在开发微信小程序时,我们通过网络请求请求数据,对数据进行一定的处理绑定到视图即可,由于组件的存在,简单的展示变得更加简单。涉及网络请求、媒体、文件、缓存、位置、设备、支付、二维码等功能时,都可以去调用相应的API。所以,微信小程序的开发足够简单,可以快速开发并实现。

当然,利弊是共存的,微信小程序开发起来虽然简单,但是限制也较多、灵活性却不足。在微信小程序中,要更新视图就只能修改data,而视图层也只能通过事件向逻辑层传递交互信息。前端传统的Dom操作在微信小程序中是不可用的,因为window、document在微信小程序中都不存在,所以,只要涉及操作Dom的代码均不可复用。微信小程序WXML提供的标签也比HTML要少很多,但是常见的标签都是有的,WXSS支持的样式也比CSS要少一些。如果要将H5页面移植到微信小程序,要修改的地方还比较多:

  1. WXML标签与HTML标签并不一致,要重写;

  2. 微信小程序无DOM交互能力,涉及DOM操作的代码需要在小程序中单独设计;

  3. 网络请求、媒体、文件、缓存、界面等相关内容需要使用小程序提供的API来实现,API的使用比较简单;

  4. 与上述内容无关的JS逻辑代码是可以复用的;

  5. css代码可复用率高,除了一些复杂的CSS3样式外,基本移植可用。小程序额外提供了flex、rpx的实现,做响应式页面变得更加容易。

综上,微信小程序开发简单,码农们可以快速上手,开发出一个可用的小程序。但是,微信小程序限制也不少,不能操作DOM,支持的HTML标签和CSS样式少一些,做一些炫酷的动画或者复杂的功能就比较困难。H5页面移植到微信小程序要修改的地方也还比较多,主要是WXML标签、JS和HTML的交互及小程序提供的API功能部分。

微信小程序开发姿势

如果你要开始开发一款微信小程序了,那么正确的步骤是什么呢?我也不知道啊。。。以下我的个人推荐步骤:

  1. 先了解微信小程序为何而生,从产品的角度去思考微信小程序的利与弊(对于程序员思考为什么小程序要如此设计、为什么里面有各种限制是非常有帮助的),推荐《一篇文章读懂微信小程序(应用号)是什么?》《你的产品适不适合做微信小程序?》

  2. 整体认识小程序的框架、设计理念、开发的利弊;

  3. 通读微信小程序官网

  4. 仔细阅读小程序官网的开发部分(https://mp.weixin.qq.com/debu...,下载微信小程序开发者工具,体验官网提供的Demo;

  5. 开始开发微信小程序。

模块化

JavaScript模块化

微信小程序中,JS文件中声明的变量和函数只在该文件中有效;不同的文件可以声明相同名字的变量和函数,不会相互影响。如果需要获取全局的应用实例,可以在App()中设置。

// app.jsApp({
  globalData: 1
})// a.js// The localValue can only be used in file a.js.var localValue = 'a'// Get the app instance.var app = getApp()// Get the global data and change it.app.globalData++

此外,可以通过require()引入其他JS文件,在文件中可以通过module.exports来暴露模块接口。

// common.jsfunction sayHello(name) {  console.log(`Hello ${name} !`)
}module.exports.sayHello = sayHello
// index.jsvar common = require('common.js')
Page({  helloMINA: function() {
    common.sayHello('MINA')
  }
})

WXML模块化

WXML可以通过模板(template)来组织标签,使WXML拆分合理、清晰易读。使用template标签来定义模版,使用name属性指定模版名称;通过import标签来引入模版,并使用is属性来指定使用的模版名称,data传入属性。

// template/msgItem.wxml<template name="msgItem">
  <view>
    <text> {{index}}: {{msg}} </text>
    <text> Time: {{time}} </text>
  </view></template>
// index.wxml<import class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./template/msgItem.wxml" />
<template is="msgItem" data="{{...item}}"/>

WXSS模块化

使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。

/** common.wxss **/.small-p {  padding:5px;
}
/** app.wxss **/@import "common.wxss";.middle-p {  padding:15px;
}

视图层与逻辑层交互

视图层包含类似HTML的WXML、基本等同于CSS的WXSS,逻辑层则包含ES,去除了window、document等对象及方法,提供了一些API。视图层通过事件来通知逻辑层交互,逻辑层通过修改data来更新视图。

简单交互例子

<view id="tapTest" data-name="Payton" bindtap="tapName"> {{userName}}, Click me! </view>
Page({    data: {        userName: 'xxx'
    },    tapName: function(e){
        wx.showToast({            title: 'hi,' + this.data.userName + 'I`m ' + e.currentTarget.dataset.name,            icon: 'success',            duration: 2000
        })
    }
})

WXML中的动态数据均来自对应 Page 的 data。数据绑定使用双大括号将变量包起来,数据改变(this.setData())时就会更新视图,更新方式类似于虚拟dom。而事件的定义需要在标签属性中指定事件处理函数名称,事件处理函数在Page({})中定义,如果事件处理函数需要传递参数,则要在标签的data-中定义,但是一般情况下,我们是不需要传递参数的,因为大部分的数据我们可以在事件处理函数中只是使用this.data.的方式取得。

修改data

在小程序中,要使用this.setData()的方式来修改data,进而更新视图。但是,当要修改data中的二级数据时,将不会进行合并修改。如:

Page({    data: {        userInfo: {            name: 'payton',            sex: 1
        },        tip: 'hello, world'
    },    onLoad: function(){
        this.setData({tip: 'hello, world!'}) // 进行合并修改,userInfo不变
        this.setData({userInfo: {name: 'peyton'}}) // 二级数据,整体修改。userInfo中sex消失,userInfo为{name: 'peyton'}
    }
})

很多时候,我们在修改data时,是希望只修改我们传入的参数,而原有的参数不进行变更的,如上面我们只希望修改name,而sex保持和原来一致。所以,我们可以采取一下方式:

this.setData({    userInfo: {
        name: 'peyton',
        sex: this.data.userInfo.sex
    }
})

但是这种方式很麻烦,而且很容易造成忘记一些内容,或者修改属性名时很容易漏掉。所以,我们设计了一个函数,来实现这种深层次数据的合并修改。使用下面的方式,便可以进行合并了。

// util.jsfunction mergeObject(to, source) {    var from;    var symbols;    for(var s = 1; s < arguments.length; s++) {        from = Object(arguments[s]);        for(var key in from) {            if(hasOwnProperty.call(from, key)) {
                to[key] = from[key];
            }
        }
    }    return to;
};module.exports.mergeObject = mergeObject;
var util = require('../util.js');
Page({
    ...
    onLoad: function(){        this.setData({tip: 'hello, world!'}) //进行合并修改,userInfo不变
        this.setData({            userInfo: util.mergeObject(this.data.userInfo, {                name: 'peyton'
            })
        }) // 合并修改,sex不会消失。userInfo为{name:'peyton',sex:1}
    }
})

插入HTML

在开发H5页面时,我们通常要使用innerHTML来修改一个标签内的HTML,在小程序中,我们无法手动修改DOM。比如:后台传递过来一短内容,这段内容要展现在页面中,但是其中包含图片,且图片数目不定。我们就没有办法通过js来构造HTML片段,并插入到视图中。在开发花样直播时,有时候一个用户发送的内容中包含表情,也就是图片,此时,使用小程序的data是无法解析标签的,这个功能实现起来就很麻烦。我的实现方式如下:

// msg.wxml<block wx:for="{{contents}}" wx:for-item="content">
    <text wx:if="{{content.type == 'text'}}" class="content">{{content.text}}</text>
    <image wx:if="{{content.type == 'image'}}" class="emoji" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="{{content.src}}"></image>
</block>
// 后台传递的content: 主播好漂亮/:149/ (注:/:149/表示微笑表情) if (...) {    return {        type: 'text',
        text: text
    }
} else if (..){    return {        type: 'image',
        src: src
    }
}

也就是要将后台传递的内容转成数组,并且需要标明类型,再根据条件渲染,分别渲染成文字和图片。由于我这里的需求只需要关注展示文字和表情,所以这种方式处理起来就OK。但是,如果后台传递的是文章类型的内容(包含图片、标题等等),需要转换成多种格式,再自己写就会很麻烦了。这个时候推荐使用wxParse(https://github.com/icindy/wxP...,支持HTML及markdown解析,其实现思路其实和上面方式类似。使用wxParse的话,可以将H5版本构造的html片段直接传入wxParse,wxParse会进行解析,最终转换成小程序版本。不过,有同事用过,不过反馈说页面中图片多的话,用wxParse会比较卡,我自己没有尝试过,此处就不再多说。

小程序组件及API

小程序本身提供了很多组件和API,使用这些组件和API可以很方便的进行开发,极大的加快开发进程。目前来说,有些组件和API还有些小坑,目前仍在动态完善中。关注此部分,官网上全面很多,此处只做简述。

配置

在小程序中,可以通过app.json对小程序进行全局的配置,在每个页面中可以进行有关配置(只能配置页面内的配置项,比全局配置要少)。在全局配置中,可以配置的内容为:

  1. pages,设置页面路径,第一个路径即为默认初始页,所有的页面路径均需要配置;

  2. window,设置默认页面的窗口表现,如状态栏、导航条、标题、窗口背景色等(可以在页面中配置,覆盖全局配置);

  3. tabBar,设置tab的表现,可以设置图片、文字等;

  4. networkTimeout,网络超时时间;

  5. debug,设置是否开启 debug 模式。

组件

与H5相比,WXML提供的组件种类并不算多,但是常用的都有,开发个小程序不成问题。其组件中提供了一些便捷的属性,还是很方便的,但是属性与H5相比仍然不全面。

  1. 视图容器:view(类似div)、scroll-view(类似带滚动条的div)、swiper(滑块视图容器);

  2. 表单组件:button、checkbox、form、input、label等;

  3. 基础内容:icon(小程序提供的图标)、text(行内文本)、progress(进度条);

  4. 媒体组件:audio、image(background-image的形式有很多坑,最好用image)、video;

  5. 地图、画布、导航、客服会话等。

API

微信小程序提供的API还是挺多,用起来也还不错。

  1. 网络:请求(http请求,使用手感不错)、上传、下载、WebSocket(服务器能支持就很爽了);

  2. 媒体:图片、录音、音频控制、视频控制(目前感觉这部分提供的API仍然不足);

  3. 界面:提示框、弹框、导航条设置、跳转、下拉刷新、绘图等;

  4. 数据缓存、设备(罗盘、扫码、拨打电话、重力感应等)、文件等;

  5. 开放接口:登录、微信支付、用户信息、模板消息、分享等。

    原文作者:  zhaopeifei

    原文链接: https://segmentfault.com/a/1190000008196781

点击查看更多内容
6人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消