文件目录结构
1)app
app.js :小程序的入口
app.json :小程序的全局配置
app.wxss/scss :小程序全局样式
2)pages
pages文件夹包含多个页面文件夹。每个文件夹包含4类文件,
对于页面index来说,有:
index.js :页面逻辑
index.json:页面配置
index.wxss/scss:页面样式
index.wxml:页面结构
3)其他
project.config.json :项目公共配置
project.private.config.json:项目个人配置
sitemap.json:设置是否允许被微信索引
全局配置-app.json
主要包括3个常见的配置项目:pages 、window 、tabbar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| { "pages":[ "pages/cate/cate", "pages/cart/cart", "pages/profile/profile", "pages/index/index" ] "entryPagePath":"pages/page_2/page_2", "window":{ "navigationBarTitleText":"导航条标题", "navigationBarBackgroundColor": "#f3514f", "enablePullDownRefresh": true, "backgroundColor": "#efefef", "backgroundTextStyle":"dark" }, "tabBar":{ "selectedColor": "#f3514f", "color":"#666", "list":[ { "text":"首页", "pagePath": "pages/index/index", "iconPath": "/images/tabbar/index.png", "selectedIconPath": "/images/tabbar/index-active.png" }, { "text":"购物车", "pagePath": "pages/cart/cart", "iconPath": "/images/tabbar/cart.png", "selectedIconPath": "/images/tabbar/cart-active.png" }, { "text":"分类", "pagePath": "pages/cate/cate", "iconPath": "/images/tabbar/cate.png", "selectedIconPath": "/images/tabbar/cate-active.png" }, { "text":"我的", "pagePath": "pages/profile/profile", "iconPath": "/images/tabbar/profile.png", "selectedIconPath": "/images/tabbar/profile-active.png" } ] }, }
|
页面配置-page.json
当前页面配置若设置了和全局配置,会覆盖全局配置,否则沿用全局设置。
1 2 3 4 5 6
| { "usingComponents": {}, "navigationBarTitleText": "商品分类", "navigationBarBackgroundColor": "#00AF92", "enablePullDownRefresh": true }
|
页面结构-page.wxml
wxml是小程序中用来编写页面结构的文件格式。
wxml提供了view、image、text、navigator等标签,在小程序中也称标签为组件
1 2 3 4
| "setting": { "useCompilerPlugins": [ "sass" ],
|
1)view组件/page组件
wxml就是由各种组件层层嵌套形成的,由此构成页面。
我们使用view组件包裹其他组件,形成块状结构,而整个页面又被一个page组件包裹。
1 2 3 4 5
| page{ height: 100vh; background-color: lightgreen; }
|
2)swiper组件-轮播图
swiper-item是轮播图组件swiper中的一个子页面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <view class = "swiper-container"> <swiper autoplay = "true" //是否自动切换 interval = "2000" //切换间隔ms indicator-dots = "true"//是否显示dots circular = "true" //最后一格是否向右切换 indicator-color="#efefef" //设置dots颜色 indicator-active-color="#f3514f"> <swiper-item>first-item</swiper-item> <swiper-item>second-item</swiper-item> <swiper-item>third-item</swiper-item> </swiper> </view>
|
对应的scss:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| .swiper-container{ swiper{ height: 360rpx; background-color:white; swiper-item{ &:first-child{ background-color: yellow; text-align:center; line-height: 180rpx; } &:nth-child(2){ background-color: lightgreen; text-align:center; line-height: 180rpx; } &:last-child{ background-color: skyblue; text-align:center; line-height: 180rpx; } } } }
|
3)image组件-图片
1 2 3 4 5 6
| <image src = "/images/" //文件路径 mode = "aspectfit" //图片的裁切和缩放方式 show-menu-by-longpress = "true" //长按图片加载菜单(收藏、保存、分享等) lazy-load = "true" //懒加载(在滑动到该图片时,才加载该图片) > </image>
|
4)text组件-文本
1 2 3 4 5
| <text user-select="true" //是否可被长按选取 space = "emsp" //是否显示连续空格,以及空格格式(emsp - 中文空格,ensp - 英文空格) > hello world </text>
|
5)navigator组件-跳转
在必要时,使用navigator组件包裹其他组件,例如imgae和text,可以实现单击跳转功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <navigator src = "/pages/index/index" oepn-type = "switchTab" // open-type说明: // navigate ---- 跳转后存在返回按钮,只能跳转到非tabbar页面 // redirect ---- 跳转后无返回按钮,只能跳转到非tabbar页面 // switchTab ---- 跳转到某个tabbar页面 // reLaunch ---- 关闭所有页面,并打开某个页面 // nevigateBack ---- 返回上一个页面 // 若使用navigateBack属性,还可以设置 delta = "数字" 来设置返回前n页 > 跳转到首页 <image ...> ... </image> <text ...> ... </text> </navigator>
|
1 2 3 4 5 6 7 8
| <scroll-view class = "scroll_container_x" scroll-x = "true" //横线滑动 //或者scroll-y,可以实现纵向滑动 > <view>1</view> <view>2</view> <view>3</view> </scroll-view>
|
对应的scss文件样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| .scroll_container_x{ width:100%; height:80rpx; white-space:nowrap; background-color : white; view{ display:inline-block; width:100%; height:80rpx; &:nth-child(1){ background-color: blueviolet; } &:nth-child(2){ background-color: burlywood; } &:nth-child(3){ background-color: chartreuse; } } }
|
7)botton组件
1 2 3
| <button type = "primary" // 按钮样式,比如 :warn 、default bindtap = "handler" //按下按钮后触发的函数(事件),定义在js文件中 >按钮名</button>
|
对应的js文件
1 2 3 4 5 6 7
| page([ ... handler(event){ console.log("handler事件被触发了") }, ... ])
|
1
| <input type = "text" bindinput = "getInputVal"> </input>
|
对应的js文件
1 2 3 4 5 6 7
| page([ ... getInputVal(event){ console.log(event.detail.value) }, ... ])
|
事件系统-page.js
1)事件冒泡
bind:tap会在该事件触发后,继续向上触发其父节点的事件,这被叫做“事件冒泡”。
如下,childTap事件触发后,parentTap事件也被触发。
1 2 3
| <view bind:tap = "parentTap"> <botton type = "default" bind:tap = "childTap">按钮</botton> </view>
|
catch:tap不会向上冒泡。如果想阻止事件冒泡,可以将如上代码改为:
1 2 3
| <view bind:tap = "parentTap"> <botton type = "default" catch:tap = "childTap">按钮</botton> </view>
|
2)事件传参
在事件中,事件绑定者指的是绑定tap属性的组件,而事件触发者指的是触发tap的组件。使用currentTarget获得的是当前事件绑定者身上的数据,而使用target获得的是事件触发者身上的数据。
例如:
若此时按下按钮,view成为事件绑定者,button成为事件触发者。
1 2 3 4 5 6 7 8 9 10 11
| <view bind:tap = "handler" data-id = "222" data-name = "peter"> <button type = "primary" data-id = "111" data-name = "Tom" >按钮</button> </view>
<view bind:tap = "handler" mark:id = "222" mark:name = "peter"> <button type = "primary" mark:id = "111" mark:name = "Tom" >按钮</button> </view>
|
js事件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| ... handler(event){ console.log(event.target.dataset.id); console.log(event.target.dataset.name); console.log(event.currentTarget.dataset.id); console.log(event.currentTarget.dataset.name); }, ...
|
另一种事件传参的方法是通过mark,获取事件触发者的数据
例如:
1 2 3 4 5
| <view bind:tap = "handler" mark:id = "222" mark:name = "peter"> <button type = "primary" mark:id = "111" mark:name = "Tom" >按钮</button> </view>
|
js:
1 2 3 4 5 6 7 8 9
| ... handler(event){ console.log(event.mark.id); console.log(event.mark.name); }, ...
|
3)数据声明和绑定
在js文件的中可以声明一些变量,比如:
1 2 3 4 5 6 7 8 9 10
| ... data: { id : "1", obj: { name:"jim", age: "18" }, ischecked:false, }, ...
|
在wxml中使用特殊符号进行访问,比如:
1 2 3 4
| <view>{{id}}</view> <view>{{obj.name}}</view> <view>{{id*3 + 2}}</view> <view>{{ischecked === true ? "yes" : "no"}}</view>
|
4)数据更新
直接在js中使用this.data.xxx的方式赋值,虽然可以修改数据,但是无法改变刷新页面上呈现的数据。若要实现后者,则需要使用this.setData()的方法。
1 2 3
| <view>{{id}}</view> <view>{{obj.name}}</view> <botton type = "primary" bind:tap = "handler">更新名字为jackson</botton>
|
js:
1 2 3 4 5 6 7
| handler(event){ this.data.obj.name = "Wang"; this.data.id += 1 this.setData({ obj: {name: "jackson"}, id : this.data.id + 1 })
|
每次按下按钮,页面上的id每次增加2,而name变为jackson。