首页 > 代码库 > 微信小程序开发入门

微信小程序开发入门

微信小程序

首先说下结构吧,看看小程序到底长什么样子

技术分享

这是一个微信提供的自己的开发工具,相当于xcode吧,由此也可以看出腾讯的野心并不小啊,左边的就是编辑调试什么的,往右就是一个模拟器,你可以选择iPhone各种型号或者安卓各种型号,在往后这就是目录结构了。

先说一下小程序的代码结构吧,首先他的app service 至少由这三个文件组成,app.js,这个是脚本代码,App()函数就在这里面实现,可以监听处理小程序的生命周期函数,声明全局变量。app.json json文件这个一般都是对程序进行配置的,这里面一般都是放pages页面组成啊,还有window或者其他页面的样式 颜色等。app.wxss,这个就是一个style sheet,样式表,你如果不想在自己的pages中单独的声明一些样式,可以直接使用这里的。

然后除了系统提供的,我们要想开发小程序肯定要创建自己的页面,每个自己的页面都有四个文件index.js index.json index.wxml ,index.wxss。

技术分享

 

 

那这些文件里到底都有些什么呢 ,下面看图:

技术分享

index.wxss 就想成css吧,其实就是样式表 什么color marin padding width height  这些

 

技术分享

这个就是index.json 没什么太大的作用 就是一些配置信息 

 

技术分享

这个就比较重要了 index.js 就是一些监听函数或者自定义函数 和page 的注册等

 

技术分享

这个就是index.wxml  就相当于html 看这样子就觉得长得挺像,就负责页面具体长什么样子,由一些控件节点堆成的,里面绑定数据和函数

 

小程序并不是web view,不是H5的界面,是一种类似react-native 的用JS和类XML结构写的接近于原生的app

小程序的开发框架的目标是通过尽可能简单,高效的方式让开发者可以在微信中开发具有原生APP体验的服务

框架提供了自己的视图层描述语言wxml和wxss ,就类似于HTML 和CSS,以及基于JavaScript的逻辑层框架,并在视图层和逻辑层间提供了数据传输和事件系统,可以让开发者方便的聚焦于数据与逻辑之上。

框架的核心是一个响应的数据绑定,这点和native的MVC MVVM 和react-native的state,props等数据绑定响应绑定一样的,框架都是让数据与视图尽可能简单的保持同步,当数据发生改变时,只需要在逻辑层修改数据,视图层就会自动的响应更新。可以通过下面一个例子来看:

// this is our view 

<view> Hello {{name}} </view>  // 是不是感觉很像HTML的写法呢,别急下面的更像

<button bindtap=“changeName”>click me </button> 这其实就是一个按钮挂接一个function ,函数名称叫changeName,按钮的标题叫click me

//  this is  app service

var helloData = http://www.mamicode.com/{

name:“world”

}

// page 是一个函数,注册一个页面,主要是当前页面的一些方法和数据绑定,接收一个object参数,指定页面的初始数据data,生命周期函数,事件处理函数,生命周期函数有onLoad 页面加载 ,onShow 页面显示,onReady 页面展示完成,onHide 页面隐藏,onUnload 页面卸载

Page({

data:helloData,

changeName:function(e){

this.setData({

name:”bob”

})

}  })

 

app.js 小程序的脚本文件  可以在这个文件中处理小程序的生命周期函数,声明全局变量。调用API

app.json  是对整个小程序的全局配置,可以在这个文件中配置小程序是由哪些页面组成,配置小程序的窗口背景色,配置导航条的样式,配置默认标题,该文件不可添加任何注释

app.wxss 是小程序的公共样式表,我们可以在页面组件的class属性上直接使用app.wxss中声明的样式规则

每一个小程序页面都是由4个不同的后缀文件的组成如:index.js index.wxml  index.json index.wxss,微信小程序的每一个页面的【路径+页面名】(page/component/index)都要写在app.json文件中的pages里面,且pages中的第一个页面是小程序的首页

作用域:在JS文件中声明的变量和函数只在该文件中有效,不同文件中可以声明相同名字的变量和函数,不会相互影响 

通过全局函数 getApp()可以获取全局的应用实例,如果需要全局的数据可以在app.js的APP()函数中设置如:

App({

globalData:1

}) // app.js

var app = getApp()

app.globalData ++ // a.js

模块化 

将一些公共的代码抽离成一个单独的js 文件作为一个模块,模块只有通过module.exports 或者exports才能对外暴露接口,这点很js 

// common .js

function sayHello(name){

console.log(‘hello$(name)’)

}

module.exports.sayHello = sayHello

在需要使用这些模块的文件中,使用require(path)将公共代码引入

var common = require(‘common.js’)

Page({

helloCommon:function(){

common.sayHello(‘hello’)

}

})

 

App() 函数用来注册一个小程序,只能在app.js中注册,且只能注册一次

在App()函数中不要调用getApp(),使用this即可拿到实例

不要在onLaunch的时候调用getCurrentPage()这时候page还没有生成

通过getApp()获取到小程序的实例后不要私自调用生命周期函数

// app.js

App({

  onLaunch: function() { 

    // Do something initial when launch.

  },

  onShow: function() {

      // Do something when show.

  },

  onHide: function() {

      // Do something when hide.

  },

  one rror: function(msg) {

    console.log(msg)

  },

  globalData: ‘I am global data‘

})

// other.js

var appInstance = getApp()

console.log(appInstance.globalData)

 Page

Page() 函数用来注册一个页面,接受一个object参数,其指定页面的初始数据,生命周期函数,事件处理函数

通常在一个页面的index.js 下

Page({

  data: {

    text: "This is page data."

  },

  onl oad: function(options) {

    // Do some initialize when page load.

  },

  onReady: function() {

    // Do something when page ready.

  },

  onShow: function() {

    // Do something when page show.

  },

  onHide: function() {

    // Do something when page hide.

  },

  onUnload: function() {

    // Do something when page close.

  },

  onPullDownRefresh: function() {

    // Do something when pull down.

  },

  onReachBottom: function() {

    // Do something when page reach bottom.

  },

  onShareAppMessage: function () {

   // return custom share data when user share.

  },

  // Event handler.

  viewTap: function() {

    this.setData({

      text: ‘Set some data for updating view.‘

    })

  },

  customData: {

    hi: ‘MINA‘

  }

})

 

初始化数据

初始化数据将作为页面的第一次渲染,data将会以json 的形式由逻辑层传至渲染层,渲染层可以通过wxml对数据进行绑定

<view>{{text}}</view>

<view>{{array[0].msg}}</view>

Page({

  data: {

    text: ‘init data‘,

    array: [{msg: ‘1‘}, {msg: ‘2‘}]

  }

})

 

setData 函数用于将数据从逻辑层发送到视图层,同时改变对应的this.data 的值

直接修改this.data的值无效,这点有点类似this.setState,无法改变页面的状态,还会造成数据的不一致

 

index.wxml 是页面的结构文件

<view class="container">

  <view  bindtap="bindViewTap" class="userinfo">

    <image class="userinfo-avatar" src="http://www.mamicode.com/{{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>

本例中使用了<view/> <image/><text/>来搭建页面结构,绑定数据和交互处理函数

index.js  是页面的脚本文件,在这个文件中可以监听并处理页面的生命周期函数,获取小程序实例,声明并处理数据,响应页面交互事件等

//获取应用实例

var app = getApp()

Page({

  data: {

    motto: ‘Hello World‘,

    userInfo: {}

  },

  //事件处理函数

  bindViewTap: function() {

    wx.navigateTo({

      url: ‘../logs/logs‘

    })

  },

  onl oad: function () {

    console.log(‘onLoad‘)

    var that = this

    //调用应用实例的方法获取全局数据

    app.getUserInfo(function(userInfo){

      //更新数据

      that.setData({

        userInfo:userInfo

      })

    })

  }

})

 

index.wxss 是页面的样式表 采用的是flex布局

.userinfo {

  display: flex;

  flex-direction: column;

  align-items: center;

}

 

.userinfo-avatar {

  width: 128rpx;

  height: 128rpx;

  margin: 20rpx;

  border-radius: 50%;

}

 

.userinfo-nickname {

  color: #aaa;

}

 

.usermotto {

  margin-top: 200px;

}

 

当页面有自己的样式表时,会覆盖app.wxss中的样式,如果不指定页面的样式表,可以在页面的结构文件中直接使用app.wxss中指定的样式规则

index.json 也是非必要的,当页面有自己的配置文件时会覆盖在app.json中的相同的配置项,如果没有指定的页面配置文件,则在该页面直接使用app.json 中的默认配置

 

逻辑层

小程序的逻辑层是由JS编写,由于并不是运行在浏览器上,所以在web上的一些能力都无法使用,如document,window等

增加App Page函数,进行程序和页面的注册

增加getApp 和 getCurrentPages方法,分别用来获取当前的APP实例和当前的页面栈

每个页面有独立的作用域,并提供模块化能力

开发者写的所有代码最终会打包成一份javaScript代码,在小程序启动的时候运行,直到小程序销毁

 

数据绑定

WXML中的动态数据均来自对应page的data

简单绑定 用双大括号将变量括起来 如:<view> {{message}} </view>

Page({

data:{

message:’hello world’

}

})

 

组件属性 需要在双引号之内

<view id=“item -{{id}}”></view>

Page({

data:{id:0} })

控制属性 需要在双引号之内

<view wx:if=“{{condition}}”> </view>

Page({ data:{condition:true} })

关键字需要写在双引号之间  <checkbox checked=“{{false}}” </checkbox>

运算  可在{{}}内进行简单的运算 三元运算 算数运算 逻辑判断  字符串运算  数据路径计算 数组 对象

条件渲染

在框架中可以用 wx:if=“{condition}” 来判断是否需要渲染该代码块

列表渲染

在组件中使用wx:for 控制属性绑定一个数组,即可使用数组中的各项的数据重复渲染该组件

默认数组的当前项的下标变量名默认为index,数组当前项的变量名默认为item 

<view wx:for=“{{}array}”>

{{index}}:{{item.message}}

</view>

Page({

data:{

array:[{

message:’foo’,

}, {

message:’bar’,

}]

}

})

使用wx:for-item可以指定数组当前元素的变量名 使用wx:for-index 可以指定数组当前下标的变量名

模板 template

可以在模板中定义代码片段,然后在不同的地方调用

定义模板 使用name 属性作为模板的名字

<template name=“”msgItem>

<view>

<text>{{index}}:{{msg }}</text>

<text>Time:{{time}}</text>

</view>

</template>

使用is属性,声明需要使用的模板,然后将模板的data传入

<template is=“msgItem” data=http://www.mamicode.com/“{{…item}}”/>

Page({

data:{

item:{

index:0,

msg:’this is  a template’,

time:’2016-06-06’

}

}

})

is 属性可以使用双引号语法来动态决定具体需要渲染哪个模板

<template name=“old”>

<view>odd</view>

</template>

<template name=“even”>

<view>even</view>

</template>

<block wx:for=“{{[1,2,3,4,5]}}”>

<remplate is=“{{item%2 ==0 ? ‘even’ : ‘odd’}}”>

</block>

模板拥有自己的作用域,只能使用data传入的数据

 

事件

在组件上绑定一个事件处理函数,如bindtap,当用户点击该组件的时候会在该页面对应的page中找到对应的事件处理函数

<view id =“tapTest” data-hi=“wechat” bindtap=“tapName”>click me </view>

在相应的page中定义事件处理函数参数是event

Page({

tapName:function(event){

consol.log(event)

}

})

 

微信小程序开发入门