目录结构:
文件属性
- js
页面逻辑文件,用于创建页面对象,以及处理页面生命周期控制和逻辑处理。 - wxml
- json
设置当前页面工作时的 window 的设置,此处会覆盖 app.json 中的设置,也就是说只可以设置 window 中设置的属性 - wxss
项目架构
整个项目的文件构建:
[pages]: // 页面文件夹[index]: // 独立的页面文件夹index.wxmlindex.wxssindex.jsonindex.js[otherPage]:[...page].xxx[utils]: // 工具函数文件夹utils.js // 工具函数文件[assets]: // 静态资源文件夹[images]:xxx.pngapp.js // requiredapp.json // requiredapp.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.jsApp({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].jsPage({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.jsComponent({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.jsdata: {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.jsComponent({properties: {tabItems: {type: Array,value: [],},},/*** 组件的初始数据*/ data: {},/*** 组件的方法列表*/ methods: {handleItemActive(e) {this.triggerEvent('mytap', 'haha')},},})
