微信小程序开发-从起步到放弃

Author Avatar
ciaoly 2017年10月22日
  • 在其它设备中阅读本文章

最近凑热闹试着开发微信的小程序, 从开始到入坑再到放弃, 写个博客以示纪念

官方文档在这里


1. 目录结构

├─pages
│  ├─index
│  │  ├─index.wxml
│  │  ├─index.wxss
│  │  └─index.js
│  └─logs
├─template
│  ├─template.wxml
│  ├─template.js
│  └─template.wxss
├─app.json
├─app.wxss
└─app.js

小程序的每一个界面的主要呈现是"page", 相当于安卓中的"Activity". 在小程序的根目录下的 app.xml app.wxss app.json 是整个小程序的公共文件. 其中: app.json 是小程序配置文件 ( 相当于apk中的 AndroidManifest ); app.wxss 是全局样式表, app.js 是全局js.

2. 配置文件

全局配置文件 app.json 记录了整个小程序的配置, 小程序中每一个能够呈现的页面 (Page) 都需要在 app.json 中注册 , app.json 也可以配置小程序的窗口(Window 包括了小程序页面上面的导航栏)样式

app.json 文件的语法是 json 语法, 文件中中使用一个 key 为pages 的数组来记录页面, 使用 key 为window 的数组保存小程序的窗口配置

{
  "pages":[
    "pages/index/index",
    "pages/active/active",
    "pages/details/details",
    "pages/search/search",
    "pages/cashier/cashier",
    "pages/checkout/checkout",
    "pages/status/status"
  ],

  "window":{
    "navigationBarBackgroundColor": "#00aaff",
    "navigationBarTitleText" : "一个Demo",
    "navigationBarTextStyle":"#fff",
    "enablePullDownRefresh" : false
  }
}

3. 布局文件 wxml

wxml 是微信小程序的布局文件的后缀名, 其本质上是一个xml文件( 类似 apk 的布局文件 xml). 可以使用微信小程序提供的 组件库 来组建布局.

在微信小程序中, 页面布局中的数据是可以动态指定的. 为页面设置数据的方法是数据绑定, 而不是像web中那样使用DOM对象来动态设置. (*微信小程序中没有DOM对象.)

在wxml中可以使用 Mustache 语法(双大括号) 来实现绑定数据/动态渲染的功能. 查看微信小程序文档

<view>{{viewData}}</view>
<!--这个view显示的内容是由变量viewData指定-->

<view wx:if={{ifDisplay}}/>
<!--这个view的显示与否由ifDisplay变量指定-->

<block wx:for={{list}} wx:for-item="item" wx:key="index">
       <view>{{item.data}}</view>
</block>
<!--循环遍历list, 将list中每一个item的name值作为元素<view>的值, 总共渲染list.length个<view> -->
<!-- 注意, block标签只是一个块级标记而已, 实际显示时并不会渲染block>

4. JavaScript

微信小程序中的JavaScript脚本采用标准的JavaScript语法, 支持ES6, 不支持jQuery库. JavaScript脚本负责数据绑定/逻辑处理/事件处理 每个page的js脚本都要有一个Page( Object) 函数, 在页面(page)中使用到的所有的函数和数据都作为page函数参数(Object对象)的 key:value 键值对在Page()函数里注册.

微信小程序框架里包含了小程序的生命周期函数以及一些事件函数, 可以通过重写这些函数来实现一些功能(比如启动加载/下拉刷新/上拉加载等). 查看微信小程序文档

var app = getApp();
Page( {
    data : {
        data1: '',
        data2: [],
        data3: 0
    },
    onReady : function(  ) {
        //TODO
    },

    onShow : function() {
        //TODO
    },

    onPullDownRefresh: function() {
        //TODO
    }

    myFunction : function( e ) {
        //TODO
        //必须使用page的setData()函数才能将变化的数据重新绑定到页面上, 直接修改page.data属性会造成数据和页面显示不一致的错误
        this.setData({
            data2: [1, 2, 3]
        });
    },
});

5. WXSS

wxss文件的本质是css文件, 使用标准的css语法, 使用时按照css的标准即可.

6. 自定义组件(view)

  微信小程序中自定义view相比于安卓是很不舒服的一种体验.   实现自定义view需要设计view的界面/数据和逻辑驱动  

    view的数据: 使用wxml定义模板, 模板可以实现类似于自定义view的功能. 使用 <template> 标签来指定或者使用一个模板, 可以通过设置 <template> 标签的data属性. 例如:

    <!--定义一个template-->
    <template name="list-view">
        <scroll-view>
            <block wx:for={{list}}>
            <view>{{item}}</view>
            </block>
        </scroll-view>
    </template>
    <!--使用这个template并绑定数据-->
     <template is="list-view" data="{{list}}"/> 

       注意, 在使用模板前需要在 wxml 文件里先使用 <import> 标签导入模板的wxml文件.

  
    view的界面: 可以使用WXSS来控制view的渲染. 注意渲染时的类选择器的类名不要和page中的类名冲突. 在需要渲染自定义的view的wxss中使用 @import "../customed-view.wxss"; 来导入自定义view的wxss文件.
  
    view的逻辑驱动: 使用js文件来实现逻辑驱动. 应该设置命名空间以防止js中变量名的冲突. 可以使用模块化的设计来实现自定view的逻辑驱动的封装.

7. 模块化

模块化在微信小程序的官方文档里有详细的介绍, 微信小程序的模块化和node中的模块化用法类似, node中每一个js文件都是一个模块, 使用 require ('path'); 获得模块的实例. require函数的返回值是一个js module的module.exports 对象的引用, 因此:

/*向module.exports中添加属性
** require返回: {name: 'chaol'}
*/
module.exports.name = 'chaol'; 

/*将module.exports指向一个对象
**require返回: {name: 'object'}
*/
module.exports = {name: 'object'};

8. 实现一个tab切换功能

这是我从书上看到的一个tab栏切换页面的实现方案, 将它的大致的思路记录下来.

  1. 实现tab-view 1.定义tab-view模板
<!--wxml-->
<template name="tab-view" class="tab-container">
    <view class="tab-container" bindtop="onTabClicked">
        <block wx:for="{{pages}}" wx:key="index" wx:for-item="item">
            <text class="tab-button" data-index="{{index}}">{{item.name}}</text>
        </block>
    </view>
</template>
//wxss
.tab-container{
    width: 100%;
    display: flex;
}
  • 在页面中引用tab-view
<!--wxml文件-->
<import "../View/tab-view.wxml"/>
<template is="{{currentPage.page}}" data="{{pageData}}"/>
<template is="tab-view" data="{{pages}}"/>
//wxss文件
@import "../View/tab-view.wxss"
//js文件
var page1=require("../template/page1.js"),
    page1=require("../template/page2.js"),
    page3=require("../template/page3.js");
Page([
    data: {
        currentPage: {name: 页面1, page: "page1", obj: page1},
        pages :[{name: "页面1", page: "page1", obj: page1},
            {name: "页面2", page: "page2", obj: page2},
            {name: "页面3", page: "page3", obj: page3}]
    },
    //TODO
    onTabClicked: function(event){
        var index=event.currentTarget.dataset.index;
        this.setData({currentPage: this.data.pages[index]});
        //在这里还需要实现页面业务逻辑和页面数据的合并
        //TODO
    }
]);
  1. 实现切换
    • 定义页面
<!--page1.wxml-->
<template name="page1">
    <view>{{page1Text}}</view>
</template>
  • 业务逻辑和页面数据合并
//...此处衔接以上js
    onTabClicked: function(event){
        var index=event.currentTarget.dataset.index;
        this.setData({currentPage: this.data.pages[index].page});
        this.bindFunAndData(this, this.data.pages[index].obj);
    },

    bindFunAndData: function(currentPage, targetPage){
        var p;
        for ( p in targetPage ) {
          currentPage[p] = targetPage[p]
        }
    }

大致就到这里了. 包括网络请求和传感器在内的API都可以在微信小程序官方文档里查到.

注意:

1. 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。
2. 单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据。
3. 请不要把 data 中任何一项的 value 设为 undefined ,否则这一项将不被设置并可能遗留一些潜在问题.
4. 微信小程序的页面在渲染时需要转换成HTML并由系统的webview进行渲染, 所以应尽量减少页面的重绘, 页面需要更新时尽量使用```setData()``` 

我的水平有限, 如若读者发现文中错误还望不吝指出, 感激不尽!