项目配置文件app.json
顶层的app.json文件用于整个项目的配置,对于所有页面都有效。
必需的pages属性
window属性,用来设置小程序的窗口
tabBar属性,用来设置尾部的选项栏
项目总体样式app.wxss
pages/home/home是一个三层的文件路径。(这里不是说home里面还有个home文件夹,是说的home.js但是省略后缀了)
1.所有页面都放在pages子目录里面。
2.每个页面有一个自己的目录,这里是pages下面的home子目录,表示这个页面叫做home。页面的名字可以随便起,只要对应的目录确实存在即可。
3.小程序会加载页面目录pages/home里面的home.js文件,.js后缀名可以省略,所以完整的加载路径为pages/home/home.js。home.js这个脚本的文件名也可以随便起,但是习惯上跟页面目录同名。
WXML标签语言
其实就是放页面的内容的地方
标签表示一个区块,用于跟其他区块分隔,
<text class="title"> hello world </text>
组件就用来加载图片
<view>
<image
src="https://picsum.photos/200"
style="height: 375rpx; width: 375rpx;">
</image>
</view>
原生的组件可以提供图片轮播效果
<view>
<!-- swiper组件就是轮播组件,里面放置了三个swiper-item组件 -->
<swiper
indicator-dots="{{true}}"
autoplay="{{true}}"
style="height: 750rpx; width:375rpx;">
<!-- indicator-dots属性设置是否显示轮播点,autoplay属性设置是否自动播放轮播
{{...}}的语法,表示里面放置的是 JavaScript 代码 -->
<swiper-item>
<image src="https://picsum.photos/200"></image>
</swiper-item>
<swiper-item>
<image src="https://picsum.photos/250"></image>
</swiper-item>
<swiper-item>
<image src="https://picsum.photos/300"></image>
</swiper-item>
</swiper>
</view>
WXSS页面文件的布局
页面的内容的样式和桌面布局
home.wxss文件,这个文件设置的样式,只对 home 页面生效。这是因为每个页面通常有不一样的布局,所以页面布局一般不写在全局的app.wxss里面。
page {
/* 页面高度为整个屏幕高度 */
height: 100%;
/* 页面宽度为整个屏幕宽度, 如果一个元素的宽度是页面的一半,只要写成width: 375rpx即可*/
width: 750rpx;
/* 整个页面(page)采用 Flex 布局 */
display: flex;
/* 页面的一级子元素(这个示例是<view>)水平居中 */
justify-content: center;
/* 页面的一级子元素(这个示例是<view>)垂直居中 */
/* 同时水平居中和垂直中央,就相当于处在页面的中央 */
align-items: center;
}
Flex布局
各种页面元素的位置关系,称为布局(layout)
微信小程序中添加注释不可以直接打//,需要使用快捷键ctrl+K,ctrl+C(快捷键Ctrl+/也可以,更方便)
注释不可以加在<>里面
UI框架
使用WeUI,腾讯封装了一套 UI 框架 WeUI,可以拿来用
进入它的 GitHub 仓库,在dist/style目录下面,找到weui.wxss这个文件,将源码全部复制到你的app.wxss文件的头部。
{
“useExtendedLib”: {
“kbone”: true,
“weui”: true
}
}
这种引入weui,更轻量级,更简单
加入 WeUI 框架以后,只要为按钮添加不同的 class,就能自动出现框架提供的样式。
Home.wxml文件内容
<view>
<!-- weui-btn:按钮样式的基类
weui-btn_primary:主按钮的样式。如果是次要按钮,就使用weui-btn_default
weui-btn_loading:按钮点击后,操作正在进行中的样式。该类内部需要用<i>元素,加上表示正在加载的图标。
weui-btn_disabled:按钮禁止点击的样式。 -->
<button class="weui-btn weui-btn_primary"> 主操作 </button>
<button class="weui-btn weui-btn_primary">
<!-- 这里面的内容都是属于button的 -->
<!-- 这里面的i应该是图标的意思 -->
<i class="weui-loading"></i> 正在加载
</button>
<button class="weui-btn weui-btn_disabled"> 禁止点击 </button>
</view>
数据绑定
页面数据其实可以通过脚本传入,通过脚本改变页面,实现动态效果。
所谓"数据绑定",指的是脚本里面的某些数据,会自动成为页面可以读取的全局变量,两者会同步变动。也就是说,脚本里面修改这个变量的值,页面会随之变化;反过来,页面上修改了这段内容,对应的脚本变量也会随之变化。这也叫做 MVVM 模式。
Home.js规定数据绑定
Page()方法的配置对象有一个data属性。这个属性的值也是一个对象,有一个name属性。数据绑定机制规定,data对象的所有属性,自动成为当前页面可以读取的全局变量。也就是说,home页面可以自动读取name变量
Home.wxml加入数据内容
修改home.wxml文件,加入name变量
全局数据
上面这两个只对当前页面有效,如果某些数据要在多个页面共享,就需要写到全局配置对象里面
App.js
App()方法的参数配置对象有一个globalData属性,这个属性就是我们要在多个页面之间分享的值。事实上,配置对象的任何一个属性都可以共享,这里起名为globalData只是为了便于识别。
App({
globalData:{
// globalData属性的now属性
now: (new Date()).toLocaleString()
}
});
home.js
在页面脚本里面获取全局对象。
// 从页面获取 App 实例对象
const app = getApp();
Page({
data:{
// 把app.globalData.now赋值给页面脚本的now属性
now: app.globalData.now
}
});
Home.wxml
<view>
<text class="title"> 现在时间是{{now}} </text>
</view>
Now属性可以获得当前时间
事件
事件内容在wxml,回调函数在js
事件是小程序跟用户互动的主要手段。小程序通过接收各种用户事件,执行回调函数,做出反应
事件,在传播上分成两个阶段:先是捕获阶段(由上层元素向下层元素传播),然后是冒泡阶段(由下层元素向上层元素传播)。所以,同一个事件在同一个元素上面其实会触发两次:捕获阶段一次,冒泡阶段一次
小程序允许页面元素,通过属性指定各种事件的回调函数,并且还能够指定是哪个阶段触发回调函数。具体方法是为事件属性名加上不同的前缀。
<view>
<text class="title"> hello {{name}} </text>
<button bindtap="buttonHandler"> 点击 </button>
</view>
指定回调函数。打开home.js文件
动态提示toast
每次操作后,都显示一个动态提示,告诉用户操作的结果,这种效果叫做 Toast。
// 从页面获取 App 实例对象
const app = getApp();
Page({
data:{
name:'陈尊凡'
},
buttonHandler(event){
// this.setData()方法,可以更改配置对象的data属性,导致页面上的全局变量发生变化
this.setData({
name:'chenzunfan'
},function(){
wx.showToast({
title: '改名完成',
duration:700
})
})
}
});
对话框modal
制作一个对话框,即用户可以选择"确定"或"取消"
const app = getApp();
Page({
data:{
name:'陈尊凡'
},
buttonHandler(event){
const that = this;
wx.showModal({
title: '操作确认',
content: '你确定要修改吗?',
// success属性指定对话框成功显示后的回调函数
success(res){
// 由于success()回调函数不是直接定义在Page()的配置对象下面,this不会指向页面实例
if(res.confirm){
that.setData({
name:'chenzunfan'
},function(){
wx.showToast({
title: '操作完成',
duration:700
})
})
}else if(res.cancel){
console.log('用户点击取消')
}
}
})
}
});
API使用
WXML渲染语法
WXML 的数组循环语法,就是一个很简便的方法。
Home.js
Page({
data:{
items:['事项A','事项B','事项C']
}
})
Home.wxml
<view>
<text class="title" wx:for="{{items}}">
<!-- 当前数组成员的位置序号(从0开始)绑定变量index,成员的值绑定变量item -->
{{index}}、{{item}}
</text>
</view>
客户端数据储存
小程序允许将一部分数据保存在客户端(即微信 App)的本地储存里面(其实就是自定义的缓存)。下次需要用到这些数据的时候,就直接从本地读取,这样就大大加快了渲染。
Home.wxml
<view>
<text class="title" wx:for="{{items}}">
<!-- 当前数组成员的位置序号(从0开始)绑定变量index,成员的值绑定变量item -->
{{index}}、{{item}}
</text>
<!-- 输入框有一个input事件的监听函数inputHandler(输入内容改变时触发 -->
<input placeholder="输入新增事项" bindinput="inputHandler"/>
<!-- 按钮有一个tap事件的监听函数buttonHandler(点击按钮时触发) -->
<button bindtap="buttonHandler"> 确定 </button>
</view>
Home.js
Page({
data:{
items:[],
inputValue:''
},
inputHandler(event){
this.setData({
// 每当用户的输入发生变化时,先从事件对象event的detail.value属性上拿到输入的内容,
// 然后将其写入全局变量inputValue
inputValue: event.detail.value || ''
})
},
buttonHandler(event){
// 从inputValue拿到用户输入的内容,确定非空以后,就将其加入items数组
const newItem = this.data.inputValue.trim();
if(!newItem) return ;
const itemArr = [...this.data.items, newItem];
// wx.setStorageSync()方法,将items数组存储在客户端
wx.setStorageSync('items', itemArr);
// this.setData()方法更新一下全局变量items,进而触发页面的重新渲染
this.setData({items: itemArr});
},
// 页面的生命周期方法,页面加载后会自动执行该方法,页面初始化
onLoad(){
// 打开页面,通过wx.getStorageSync()方法,从客户端取出以前存储的数据,显示在页面上
const itemArr = wx.getStorageSync('items') || [];
this.setData({items: itemArr})
}
})
…(三个点) 代表展开数组,可以简单理解为把this.data.items中的每个元素,复制到中括号里了,
必须牢记的是,客户端储存是不可靠的,随时可能消失(比如用户清理缓存)。用户换了一台手机,或者本机重装微信,原来的数据就丢失了。所以,它只适合保存一些不重要的临时数据,最常见的用途一般就是作为缓存,加快页面显示。
远程数据请求
小程序可以从外部服务器读取数据,也可以向服务器发送数据。
微信规定,只有后台登记过的服务器域名,才可以进行通信。不过,开发者工具允许开发时放松这个限制。按照上图,点击开发者工具右上角的三条横线(“详情”),选中"不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书" 。这样的话,小程序在开发时,就可以跟服务器进行通信了。
下面,我们在本地启动一个开发服务器。为了简单起见,我选用了 json-server 作为本地服务器,它的好处是只要有一个 JSON 数据文件,就能自动生成 RESTful 接口。
Home.js
Page({
data: {item:[]},
onLoad(){
const that = this;
// wx.request()方法就是小程序的网络请求 API,通过它可以发送 HTTP 请求
wx.request({
url: 'http://localhost:3000/items',
success(res){
that.setData({items: res.data});
}
})
}
})
组件
如果要在页面上展示当前用户的身份信息,可以使用小程序提供的组件。
userNickName:用户昵称
userAvatarUrl:用户头像
userGender:用户性别
userCity:用户所在城市
userProvince:用户所在省份
userCountry:用户所在国家
userLanguage:用户的语言
<view>
<!-- type属性指定所要展示的信息类型 -->
<open-data type="userAvatarUrl"></open-data>
<open-data type="userNickName"></open-data>
</view>
不需要用户授权,也不需要登录,所以用起来很方便。但也是因为这个原因,小程序不允许用户脚本读取返回的信息。
获取用户个人信息
如果想拿到用户的个人信息,必须得到授权。官方建议,通过按钮方式获取授权。
实际开发中,可以先用wx.getSetting()方法判断一下,用户是否已经授权过。如果已经授权过,就不用再次请求授权,而是直接用wx.getUserInfo()方法获取用户信息。
,新的微信开发工具做出了一些调整。后续的开发不再支持getUserInfo
, 使用新的getUserProfile
. 文档地址:
https://developers.weixin.qq.com/community/develop/doc/000cacfa20ce88df04cb468bc52801?idescene=6
Home.wxml
<view>
<text class="title"> hello {{name}}</text>
<button open-type="getUserInfo" bindtap="getUserProfile">
授权获取用户个人信息
</button>
</view>
Home.js
Page({
data: {name:''},
getUserProfile(event){
wx.getUserProfile({
desc: 'test feature',
success(res){
this.setData({
name: res.userInfo.nickName
})
},
fail:(reason)=>{
console.log(reason.errMsg)
}
})
}
})
多页面的跳转
真正的小程序不会只有一个页面,而是多个页面,所以必须能在页面之间实现跳转。
app.json配置文件的pages属性就用来指定小程序有多少个页面。
pages数组包含两个页面。以后每新增一个页面,都必须把页面路径写在pages数组里面,否则就是无效页面。排在第一位的页面,就是小程序打开时,默认展示的页面。
Home.wxml
<view>
<text class="title"> hello {{name}}</text>
<navigator url="../second/second"> 前往第二页 </navigator>
</view>
Second.wxml
<view>
<text class="title"> 这是第二页 </text>
<!-- <navigator>就是链接标签,只要用户点击就可以跳转到url属性指定的页面 -->
<navigator url="../home/home"> 前往首页 </navigator>
</view>
小程序也提供了页面跳转的脚本方法wx.navigateTo()。
Home.wxml
<view>
<text class="title"> hello 这是首页{{name}}</text>
<button bindtap="buttonHandler"> 前往第二页 </button>
</view>
Home.js
Page({
buttonHandler(event){
wx.navigateTo({
url: '../second/second',
})
}
})