目录结构:
文件属性
- js
页面逻辑文件,用于创建页面对象,以及处理页面生命周期控制和逻辑处理。 - wxml
- json
设置当前页面工作时的 window 的设置,此处会覆盖 app.json 中的设置,也就是说只可以设置 window 中设置的属性 - wxss
项目架构
整个项目的文件构建:
[pages]: // 页面文件夹
[index]: // 独立的页面文件夹
index.wxml
index.wxss
index.json
index.js
[otherPage]:
[...page].xxx
[utils]: // 工具函数文件夹
utils.js // 工具函数文件
[assets]: // 静态资源文件夹
[images]:
xxx.png
app.js // required
app.json // required
app.wxss
页面设置
可以出现在两个文件:app.json 和 每个页面中的 [pageName].josn 文件全局配置
// app.json{
"pages": ["pages/index/index", "pages/logs/logs"],
"window": {
"backgroundTextStyle": "light", // 下拉刷新部分的颜色
"navigationBarBackgroundColor": "#fff", // 导航条的背景颜色
"navigationBarTitleText": "WeChat", // 调整导航条上的文本
"navigationBarTextStyle": "black" // 导航条文字颜色
},
"style": "v2", // 指定使用升级后的weui样式
"sitemapLocation": "sitemap.json" // 指明 sitemap.json 的位置
}
标签栏的配置
// app.json
"tabBar": {
"color": "#c0c0c0", // 文字颜色
"selectedColor": "#fff", // 选中文字颜色
"backgroundColor": "#2b3b49",// 背景
"borderStyle": "white",// 边框色
"position":"top", // 位置,在顶部时,没有图标
"list": [
{
"pagePath": "foo",
"text": "text",
"iconPath": "iconPath",
"selectedIconPath": "selectedIconPath"
},
{
"pagePath": "index",
"text": "text",
"iconPath": "iconPath",
"selectedIconPath": "selectedIconPath"
}
]
}
页面配置
// [pageName].json
{
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "微信接口功能演示",
"backgroundColor": "#eeeeee",
"backgroundTextStyle": "light"
}
独立定义每一个页面的属性,比如顶部颜色,是否允许下拉刷新等
页面的配置只能设置 app.json 中 window 配置型的内容,页面中配置项会覆盖 app.json
的 window 中的相同的配置项。
生命周期
// app.js
// app.js
App({
onLaunch(options) {
// Do something initial when launch.
},
onShow(options) {
// Do something when show.
},
onHide() {
// Do something when hide.
},
onError(msg) {
console.log(msg)
},
globalData: 'I am global data',
})
应用的生命周期
// [pageName].js
Page({
data: {
text: 'This is page data.',
},
onLoad: function (options) {
// 页面创建时执行
},
onShow: function () {
// 页面出现在前台时执行
},
onReady: function () {
// 页面首次渲染完毕时执行
},
onHide: function () {
// 页面从前台变为后台时执行
},
onUnload: function () {
// 页面销毁时执行
},
onPullDownRefresh: function () {
// 触发下拉刷新时执行
},
onReachBottom: function () {
// 页面触底时执行
},
onShareAppMessage: function () {
// 页面被用户分享时执行
},
onPageScroll: function () {
// 页面滚动时执行
},
onResize: function () {
// 页面尺寸变化时执行
},
onTabItemTap(item) {
// tab 点击时执行
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
},
// 事件响应函数
viewTap: function () {
this.setData(
{
text: 'Set some data for updating view.',
},
function () {
// this is setData callback
}
)
},
// 自由数据
customData: {
hi: 'MINA',
},
})
app.js 文件
// app.js
# 每一个js文件都有单独的作用域
# const app = getApp() 全局注册的app实例对象
App({ // App 用于创建一个应用的实例对象
onLanch: function(){
# 在整个应用启动时触发
# 只会触发一次
const app = getApp()
console.log(app.bar)
},
onShow: function (){
# 应用程序显示到屏幕上触发
# 每次成为焦点状态会触发
console.log(options)
},
onHide: function (){
// 隐藏程序到后台
},
onError: function(msg){
# msg 是一个字符串,不是一个错误对象
# 程序中代码出现异常会出错,之后触发
// 只能捕获运行阶段的异常
console.log(msg)
},
# 除了生命周期里面约定的钩子函数,还可以定义任何成员
# 定义在这里的成员可以在后续的每一页面中共享
otherFun: function (){
# 任何业务处理成员函数
//
},
otherVar: 'foo',
globalData: {
userInfo: null
}
})
页面的生命周期
// pages/foo/foo.js
# 注册一个 page 实例对象
Page({
/**
* 页面的初始数据
*/
data: {
# 暴露数据到页面上
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
# 适合去做数据的初始化
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
# 当页面准备好了 => 数据渲染完了,页面渲染完成。 == window.onload
# 只有页面加载才可以 设置标题
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
# 页面进入到焦点状态 =>在前台展示了
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
# 页面进入到后台状态
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
# 可以用于在页面卸载之前保存页面状态
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
模板语法
数据绑定
列表渲染
条件渲染
<!-- wx:if wx:elif wx:else hidden -->
<text wx:if="{{ isLoading }}">loading....</text>
<view wx:else>
<text>page was loading done</text>
</view>
// hidden 类似 wx:if 频繁切换用 hidden,不常使用用 wx:if
<text hidden="{{ !isLoading }}">loading...</text>
<text hidden="{{ isLoading }}">loading done!!!</text>
列表渲染
<view wx:for="{{ list }}" wx:for-item="person" wx:key="id">
<text>{{ person.id }}:</text>
<text>{{ person.name }}</text>
</view>
// block 渲染一个包含多节点的结构块 block 最终不会变成真正的 dom 元素
<block wx:for="{{[1,2,3,4]}}" wx:key="*this">
<view>{{index}}:</view>
<view>{{item}}</view>
</block>
事件处理
bind 关键字实现,bindtap、bindinput、bindchange
<input bindinput="handleInput" />
Page({
handleInput(e) {
console.log(e)
console.log('值被改变了!')
},
})
注意
绑定事件不能带参数,不能带括号,下面是错误写法// 错误 <input bindinput="handleInput(100)" />
事件传值:通过标签自定义属性的方式 和 value
<input bindInput="handleInput" data-item="100" />
事件触发时,获取数据
handleInput(e){
console.log(e.currentTarget.dataset)
console.log(e.detail.value)
}
样式 WXSS
小程序中使用 less
原生小程序不支持 less,其他基于小程序的框架大都支持。如: wepy、mpvue、taro 等。
在小程序中实现支持:
- 使用 vscode 编辑
- 安装插件 easy less
在 vscode 的配置下加入配置:
"less.compile":{
"outExt": ".wxss"
}
在要编写样式的地方,新建 less 文件,如 index.less,然后正常编辑即可。
常见组件
常见的布局组件
- view
替代原来的 div 标签 - text
文本标签;
只能嵌套 text
长按文字可以复制
可以对空格回车进行编码 - rich-text
富文本标签 - button
- image
图片标签;
image 组件默认宽度 320 高度 240
mode:图片裁剪、缩放的模式。
lazy-laod:图片懒加载
支持懒加载 - navigator
导航组件,类似超链接标签 - icon
- swiper
微信内置轮播图组件 - radio
- checkbook
创建自定义组件
类似于页面,新建文件夹 page/ components/ myHeader,由 json、wxml、wxss、js 文件组成
声明组件
需要在组建的 json 文件中{
"component": true
}
编辑组件
在 wxml 文件中编辑组件模板,在 wxss 文件中加入组件样式
slot 插槽 类似 vue 中的 slot<view>
{{innerText}}
<slot></slot>
</view>
.inner {
color: red;
}
注册组件
在组件的 js 文件中,需要使用 Component() 来注册组件,并提供组件的属性定义、内部数据和自定义方法// myHeader.js
Component({
properties: {
innerText: {
type: string,
value: 'default value',
},
data: {
somaData: {},
},
methods: {
customMethod: function () {},
},
},
})
声明引入 自定义组件
在页面的 json 文件中进行引用声明,还要提供对应的组件名和组件路径。// index.json
"usingComponents":{
"my-header": "/components/myHeader/myHeader"
}
页面中使用自定义组件
<view>
<my-header inner-text="some text">
<view>用来替代 slot 的内容</view>
</my-header>
</view>
自定义组件传参
父组件通过属性的方式给子组件传参
- 子组件通过事件的方式向父组件传参
父组件代码:
<tabs tabItem="{{tabs}" bindmytap="onMytab" />
// page.js
data: {
tabs: [
{ name: 'aaa', age: 12 },
{ name: 'bbb', age: 13 },
]
},
onMyTab(e){
console.log(e.detail)
}
子组件代码
<view>
<view class="tab_title">
<block wx:for="{{tabItems}}" wx:key="{{item}}">
<view bindtap="handleItemActive" data-index="{{index}}"
>{{item.name}}</view
>
</block>
</view>
<view class="tab_content">
<slot></slot>
</view>
</view>
// com.js
Component({
properties: {
tabItems: {
type: Array,
value: [],
},
},
/**
* 组件的初始数据
*/ data: {},
/**
* 组件的方法列表
*/ methods: {
handleItemActive(e) {
this.triggerEvent('mytap', 'haha')
},
},
})