文档:https://developers.weixin.qq.com/miniprogram/dev/quickstart/basic/file.html#js-交互逻辑
普通快速模板
开发目录
├── app.js
├── app.json
├── app.wxss
├── pages
│ │── index
│ │ ├── index.wxml
│ │ ├── index.js
│ │ ├── index.json
│ │ └── index.wxss
│ └── logs
│ ├── logs.wxml
│ └── logs.js
└── utils
.json 后缀的 JSON 配置文件
.wxml 后缀的 WXML 模板文件
.wxss 后缀的 WXSS 样式文件
.js 后缀的 JS 脚本逻辑文件
分析图片 从下往上 =>
project.config.json:整个项目的配置文件。
app.js:整个应用程序入口文件。
app.json:入口文件配置信息。
app.wxss:应用程序全局样式文件。
wxss = WeiXin Style Sheet微信样式表,类似于css文件。
utils文件夹:工具包文件所在目录。自行封装的模块。供其他小程序页面使用。类似于vue中的过滤器概念,工具包中可以定义一些格式化的函数等。
pages文件夹:小程序各个页面的视图,业务逻辑,样式,配置文件所在目录。特别注意:在小程序中每一个页面都拥有独立的视图,业务逻辑,样式,配置文件。和vue的类比如下:
index/index.js相当于vue中的
wxml = WeiXian Markup Language微信标记语言,类似于html或xml。
各文件之间的关联关系:
pages文件夹下的每一个文件夹,如index,logs等,内部包含四个文件,但四个文件并不是必须的,如.json文件就可以没有。并且每个文件的文件名称(不包含后缀名称)一般约定对应文件夹的名称,如:index文件夹中四个文件命名分别为:index.json,
index.js, index.wxss,
index.wxml。这是一种约定好的风格。每个文件夹相当于vue中定义的一个页面级组件。和当前小程序的入口配置文件app.json有对应(很重要的关联),如:
“pages”: [ “pages/index/index”, “pages/logs/logs” ]
每个文件夹中的四个文件之间的关联关系,微信已帮我们做过封装,不用开发者再引入。如index.json,index.js,index.wxml,index.wxss自去产生关系。在渲染视图index.wxml时会自动使用index.wxss样式文件,自动使用index.js业务逻辑文件及配置文件index.json。工具包文件是自行封装的模块包,要想在其他页面中使用,必须引入。 引入方法如:const util =
require(’…/…/utils/util.js’) 类似于node.js中的引入模块包。
project.config.json - 项目配置文件
应用程序启动时候,会自动读取配置文件,约定一些规则
()里面是解释
{
"description": "项目配置文件(什么项目,包含哪些功能)",
"packOptions(包选项)": {
"ignore": []
},
"setting": {
"urlCheck(是否校验url地址)": true,
"es6": true,
"postcss(css格式化)": true,
"minified(压缩)": true,
"newFeature(版本迭代新特性)": true
},
"compileType(编译类型-定义的项目名称)": "miniprogram",
"libVersion": "2.0.4",
"appid(开发和上线的AppID有可能不一样)": "wx7acb670e00b40e5b",
"projectname": "demo-%E6%99%AE%E9%80%9A%E6%A8%A1%E6%9D%BF",
"debugOptions": {
"hidedInDevtools(本地)": []
},
"isGameTourist(游戏是true)": false,
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"game": {
"currentL": -1,
"list": []
},
"miniprogram": {
"current": -1,
"list": []
}
}
}
运行时候最先执行的是
app.js(唯一的入口地址)
小程序里面三大对象:1,应用程序App({ }) 2,页面page({}) 3,组件component({})
组件开发
就一个App({ })
在其他页面调用可以:
const app = getApp() 获取
//app.js整个应用程序的入口文件
//App()对象,是应用程序对象,在其他页面可以通过getApp()方法获取当前应用程序对象实例。
//如:index/index.js中const app = getApp()
App({
// 应用程序启动时执行的钩子事件。只执行一次。
onLaunch: function () {
// 展示本地存储能力getStorageSync()是微信提供的两步获取缓存的api,以后看到wx.开头的都是微信的api,具体有文件可参考。setStorageSync()用来设置缓存。
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
console.log(res)
}
})
// 获取用户信息
wx.getSetting({
success: res => {
console.log(res)
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
console.log(res)
this.globalData.userInfo = res.userInfo
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
console.log('1234567890-')
this.userInfoReadyCallback(res)
}
}
})
}
}
})
},
// 全局数据,在app.js的配置项中定义的数据可以供所有的页面使用,在其他页面中通过const app = getApp()获取当前应用程序实例后,就可以通过app.globalData.userInfo访问此处定义的数据。
globalData: {
userInfo: null,
person: {
name: 'dsh2',
age: 20
}
},
//自定义的属性也可以在其它页面中访问。一般不建议这样使用,建议把数据放到globalData中。
person: {
name: 'dsh1',
age: 19
}
})
app.wxss全局的样式文件–所有页面共享
/**app.wxss**/
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 200rpx 0;
box-sizing: border-box;
}
rpx 是微信小程序解决自适应屏幕尺寸的尺寸单位。微信小程序规定屏幕的宽度为750rpx。
app.json-当前应用程序的配置文件
{
"pages":[
"pages/index/index",
"pages/logs/logs"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle":"black"
}
}
配置各个项的含义:
pages字段 —— 用于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个目录。
window字段 —— 定义小程序所有页面的顶部背景颜色,文字颜色定义等。
project.config.json
{
"description": "项目配置文件",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": true,
"postcss": true,
"minified": true,
"newFeature": true
},
"compileType": "miniprogram",
"libVersion": "2.3.0",
"appid": "wx671ce38d22d3c5ae",
"projectname": "demo",
"debugOptions": {
"hidedInDevtools": []
},
"isGameTourist": false,
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"game": {
"currentL": -1,
"list": []
},
"miniprogram": {
"current": -1,
"list": []
}
}
}
- 开发文档
wxml 模板
在网页的一般开发流程中,我们通常会通过 JS 操作 DOM (对应 HTML 的描述产生的树),以引起界面的一些变化响应用户的行为。
例如,用户点击某个按钮的时候,JS 会记录一些状态到 JS 变量里边,同时通过 DOM API 操控 DOM 的属性或者行为,进而引起界面一些变化。当项目越来越大的时候,你的代码会充斥着非常多的界面交互逻辑和程序的各种状态变量,显然这不是一个很好的开发模式,
因此就有了 MVVM 的开发模式(例如 React, Vue),提倡把渲染和逻辑分离。简单来说就是不要再让 JS 直接操控 DOM,JS 只需要管理状态即可,然后再通过一种模板语法来描述状态和界面结构的关系即可。
需要把一个 Hello World 的字符串显示在界面上。
WXML 是这么写 :
<text>{{msg}}</text>
JS 只需要管理状态即可:
this.setData({ msg: "Hello World" })
通过 {{ }} 的语法把一个变量绑定到界面上,我们称为数据绑定。
完整的描述状态和界面的关系,还需要 if/else, for等控制能力
,在小程序里边,这些控制能力都用 wx: 开头的属性来表达。
js交互
在前边的 QuickStart 例子中,在 pages/index/index.js 就调用了 wx.getUserInfo 获取微信用户的头像和昵称,最后通过 setData 把获取到的信息显示到界面上
<view>{{ msg }}</view>
<button bindtap="clickMe">点击我</button>
点击 button 按钮的时候,我们希望把界面上 msg 显示成 "Hello World"
,于是
我们在 button 上声明一个属性: bindtap ,
在 JS 文件里边声明了 clickMe 方法来响应这次点击操作:
Page({
clickMe: function() {
this.setData({ msg: "Hello World" })
}
})
小程序启动
首先 把整个小程序的代码包下载到本地
紧接着通过 app.json 的 pages获得所有页面路径
写在 pages 字段的第一个页面就是这个小程序的首页
微信客户端就把首页的代码装载进来,通过小程序底层的一些机制,就可以渲染出这个首页。
小程序启动之后,在 app.js 定义的 App 实例的 onLaunch 回调会被执行:
App({
onLaunch: function () {
// 小程序启动之后 触发
}
})
举个例子
<!-- This is our View -->
<view> Hello {{name}}! </view>
<button bindtap="changeName"> Click me! </button>
// This is our App Service.
// This is our data.
var helloData = {
name: 'WeChat'
}
// Register a Page.
Page({
data: helloData,
changeName: function(e) {
// sent data change to view
this.setData({
name: 'MINA'
})
}
})
开发者通过框架将逻辑层数据中的 name 与视图层的 name 进行了绑定
,所以在页面一打开的时候会显示 Hello WeChat!;
当点击
按钮的时候,视图层会发送 changeName 的事件给逻辑层
,逻辑层找到并执行对应的事件处理函数
;
回调函数触发后,逻辑层执行 setData
的操作,将 data 中的 name 从 WeChat 变为 MINA,因为该数据和视图层已经绑定了,从而视图层会自动改变为 Hello MINA!。