最小程序组成1

官网 下载开发者工具安装好。

新建一个目录。一个最小程序组成如下:

//app.js
App({});
{
  "pages": [
    "pages/home"
  ]
}
//pages/home.js
Page({});
<!--pages/home.wxml-->
<view>
  <text>hello world</text>
</view>

调用逻辑:首先运行 app.jsApp() 检查了 app.json。在此例中,将其中 pages/home.js 加以处理,其 Page() 编译 pages/home.wxml

项目配置 app.json

app.json 文件配置了小程序的全局参数,包括 pages 列表和 window 字典,和 其他pages 存储了所有待编译的页面,window 包括了这堆页面的全局设定;常用 navigationBarBackgroundColornavigationBarTitleText 两个参数。一个示例如下:

{
  "pages": [
    "pages/home"
  ],
  "window":{
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "标题",
    "navigationBarTextStyle":"black"
  }
}

既然有“全局设定”,也就有局部设定。对于一个页面 ${NAME}.js,其 window 设定存储在该目录下 ${NAME}.json 中,会覆盖全局的 window 设定。例如

{
  "navigationBarBackgroundColor": "#000",
  "navigationBarTitleText": "Title"
}

程序启动

App() 必须在 app.js 中调用,必须调用且只能调用一次。不然会出现无法预期的后果。

参考 App,我们可以设置小程序的各种全局回调函数(启动/切换前后台…)。

WXML2

微信的 WXML 很像 HTML,主要有以下不同

元素类型/组件

大致对应表

HTML WXML
div view, block
p, h text

更多的可以参考 组件。微信提供了丰富的微信味的原生组件,看起来不错。

数据绑定

类似于 Vue 模板,WXML 使用 {{data}} 格式绑定数据,可以在组件的参数和内容里。要声明一个绑定变量,要在 ${NAME}.jsPage.data 中设置对应数据,并配合函数处理数据变动。

控制流

类似于 Vue,WXML 通过 wx:for, wx:if, wx:elif, wx:else 来控制渲染。例如

<!--wxml-->
<view wx:for="{{$array}}"> {{item}} </view>

<view wx:if="{{$view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{$view == 'APP'}}"> APP </view>
<view wx:else="{{$view == 'MINA'}}"> MINA </view>

特别的,从语义上微信推荐使用 block 作为控制流的承载组件 ,尽管 blockview 本质上没有任何区别。

模板

以后学吧…

WXSS

除了一个有些画蛇添足的 rpx 之外和 CSS 没啥两样。

WXS

和 ES6 没啥区别。详见 WXS 语法参考

响应式系统

在不考虑模块化的情况下,可以在 ${NAME}.js 中在 Page 的全局方法,用 this.setData 来更改数据。 注意不要用箭号函数,因为 this 作用域的问题。 例如:

<!--pages/home.wxml-->
<view>
  <text>{{txt}}</text>
  <button type="primary" plain="true" bind:tap="clicked">按钮</button>
</view>
// pages/home.js
Page({
  data:{
    txt: "Hello, world!"
  },
  clicked: function(){this.setData({txt: "Nonono"})}
});

这里包括 JavaScript 语法在内的许多坑

this 归属权

示例代码一目了然

s={a:1, f: function(){console.log(this.a)}, ff: {a:0, f: function(){console.log(this.a)}}};
t={a:2, f: ()=>console.log(this.a), ff: {a:4, f: ()=>console.log(this.a)}};
a=3
s.f() // 输出 1,从作为方法**调用**的**对象**中继承
t.f() // 输出 3,从**定义**它的**函数/上下文**(若为函数外,则 undefined)中继承

因为这样的问题,在 Page 对象中定义的函数一定要用 function() 代替 ()=>

如果要从一个毫不相关的对象中调用 setData,那么只能这样变相调用

var pagethis;
var pagedata = {
    data: {},
    onLoad: function(){
        pagethis=this
    },
}
var anotherobj{
    setData: (data){pagethis.setData(data)},
}

总之,在任何函数作为参数传递,且用到了 this 的时候要务必小心。

参考