微信小程序初探
小程序是一种不需要下载安装即可使用的应用,它实现了应用「触手可及」的梦想,用户扫一扫或搜一下即可打开应用。也体现了「用完即走」的理念,用户不用关心是否安装太多应用的问题。应用将无处不在,随时可用,但又无需安装卸载。 ——张小龙
微信小程序框架
微信小程序分为视图层和逻辑层,视图层包含WXML(类似HTML)、WXSS(类似css),逻辑层包含javascript文件。视图层通过事件通知逻辑层,而逻辑层通过控制data来更新视图。此外,微信还提供了API、组件、配置文件,使微信小程序的开发更加简单。
在开发微信小程序时,我们通过网络请求请求数据,对数据进行一定的处理绑定到视图即可,由于组件的存在,简单的展示变得更加简单。涉及网络请求、媒体、文件、缓存、位置、设备、支付、二维码等功能时,都可以去调用相应的API。所以,微信小程序的开发足够简单,可以快速开发并实现。
当然,利弊是共存的,微信小程序开发起来虽然简单,但是限制也较多、灵活性却不足。在微信小程序中,要更新视图就只能修改data,而视图层也只能通过事件向逻辑层传递交互信息。前端传统的Dom操作在微信小程序中是不可用的,因为window、document在微信小程序中都不存在,所以,只要涉及操作Dom的代码均不可复用。微信小程序WXML提供的标签也比HTML要少很多,但是常见的标签都是有的,WXSS支持的样式也比CSS要少一些。如果要将H5页面移植到微信小程序,要修改的地方还比较多:
WXML标签与HTML标签并不一致,要重写;
微信小程序无DOM交互能力,涉及DOM操作的代码需要在小程序中单独设计;
网络请求、媒体、文件、缓存、界面等相关内容需要使用小程序提供的API来实现,API的使用比较简单;
与上述内容无关的JS逻辑代码是可以复用的;
css代码可复用率高,除了一些复杂的CSS3样式外,基本移植可用。小程序额外提供了flex、rpx的实现,做响应式页面变得更加容易。
综上,微信小程序开发简单,码农们可以快速上手,开发出一个可用的小程序。但是,微信小程序限制也不少,不能操作DOM,支持的HTML标签和CSS样式少一些,做一些炫酷的动画或者复杂的功能就比较困难。H5页面移植到微信小程序要修改的地方也还比较多,主要是WXML标签、JS和HTML的交互及小程序提供的API功能部分。
微信小程序开发姿势
如果你要开始开发一款微信小程序了,那么正确的步骤是什么呢?我也不知道啊。。。以下我的个人推荐步骤:
先了解微信小程序为何而生,从产品的角度去思考微信小程序的利与弊(对于程序员思考为什么小程序要如此设计、为什么里面有各种限制是非常有帮助的),推荐《一篇文章读懂微信小程序(应用号)是什么?》、《你的产品适不适合做微信小程序?》;
整体认识小程序的框架、设计理念、开发的利弊;
通读微信小程序官网;
仔细阅读小程序官网的开发部分(https://mp.weixin.qq.com/debu...,下载微信小程序开发者工具,体验官网提供的Demo;
开始开发微信小程序。
模块化
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对小程序进行全局的配置,在每个页面中可以进行有关配置(只能配置页面内的配置项,比全局配置要少)。在全局配置中,可以配置的内容为:
pages,设置页面路径,第一个路径即为默认初始页,所有的页面路径均需要配置;
window,设置默认页面的窗口表现,如状态栏、导航条、标题、窗口背景色等(可以在页面中配置,覆盖全局配置);
tabBar,设置tab的表现,可以设置图片、文字等;
networkTimeout,网络超时时间;
debug,设置是否开启 debug 模式。
组件
与H5相比,WXML提供的组件种类并不算多,但是常用的都有,开发个小程序不成问题。其组件中提供了一些便捷的属性,还是很方便的,但是属性与H5相比仍然不全面。
视图容器:view(类似div)、scroll-view(类似带滚动条的div)、swiper(滑块视图容器);
表单组件:button、checkbox、form、input、label等;
基础内容:icon(小程序提供的图标)、text(行内文本)、progress(进度条);
媒体组件:audio、image(background-image的形式有很多坑,最好用image)、video;
地图、画布、导航、客服会话等。
API
微信小程序提供的API还是挺多,用起来也还不错。
网络:请求(http请求,使用手感不错)、上传、下载、WebSocket(服务器能支持就很爽了);
媒体:图片、录音、音频控制、视频控制(目前感觉这部分提供的API仍然不足);
界面:提示框、弹框、导航条设置、跳转、下拉刷新、绘图等;
数据缓存、设备(罗盘、扫码、拨打电话、重力感应等)、文件等;
开放接口:登录、微信支付、用户信息、模板消息、分享等。
原文作者: zhaopeifei
共同学习,写下你的评论
评论加载中...
作者其他优质文章