目录
1.基本组成结构
账号申请 微信公众平台
ID:wxe6e6c0e49d00b73c
1.pages 存放所有小程序的页面
2.utils存放工具性质的模块(如格式化时间的自定义模块)
3.app.js项目入口文件
5.app.wxss全局样式文件
6.sitemap.json配置小程序及其页面是否允许被微信索引
1.app.json小程序项目的全局配置文件
1.pages
用来记录当前小程序所有页面的路径
2.window
全局定义小程序所有页面的背景色,文字颜色等
"window":{
"backgroundTextStyle":"light",//下拉loading样式 仅支持dark/light
"navigationBarBackgroundColor": "#2b4b6b",//导航栏背景色
"navigationBarTitleText": "二泡",//导航栏标题
"navigationBarTextStyle":"black",//导航栏标题颜色,仅支持black/white
"backgroundColor": "#ffffff",//窗口背景色
"enablePullDownRefresh":false,//是否全局开启下拉刷新
},
3.style
全局定义小程序组件所使用的的样式版本
4.sitemapLocation
用来指明sitemap.json的位置
5.tabBar
用于实现多页面的快速切换,最多5个,最少2个,顶部tabBar 不显示icon 只显示文本
"tabBar": {
"backgroundColor": "tabBar的背景色",
"selectedconPath": "选中时的图片路径",
"borderStyle": "tabBar上边框的颜色",
"iconPath":"未选中时的图片路径",
"selectedColor": "tab上的文字选中时的颜色",
"color": "tab上文字的默认颜色",
"position":"tabBar位置,仅支持bottom/top"
"list": [
{
"pagePath":"pages/logs/logs",
"text": "首页",
"iconPath": "/tabs/home.png",
"selectedIconPath": "/tabs/home-active.png"
},
{
"pagePath":"pages/index/index",
"text": "此页",
"iconPath":"未选中时的图片路径",
"selectedIconPath":"选中时的图标途径"
}
]
},
2.project.config.json项目配置文件
1.setting:保存了编译相关的配置
2.projectname:项目名称
3.appid:小程序账号ID
2.组件
1.view
相当于div
<view class="container">
<view>A</view>
<view>B</view>
<view>C</view>
</view>
2.scroll-view
scroll-y允许纵向滚动
<scroll-view class="container" scroll-y>
<view>A</view>
<view>B</view>
<view>C</view>
</scroll-view>
3.swiper轮播
indicator-dots显示面板指示点
<swiper class="swiper-container" indicator-dots>
<swiper-item>
<view class="item">A</view>
</swiper-item>
<swiper-item>
<view class="item">B</view>
</swiper-item>
<swiper-item>
<view class="item">C</view>
</swiper-item>
</swiper>
.swiper-container{
height: 150px;
}
.item{
height: 100%;
line-height: 150px;
text-align: center;
}
swiper-item:nth-child(1) .item{
background-color: lightgreen;
}
swiper-item:nth-child(2) .item{
background-color: lightskyblue;
}
swiper-item:nth-child(3) .item{
background-colr: lightpink;
}
3.WXML模板语法
1.数据绑定
//页面初始数据
data: {
info:'Hello',
ImageData:'https://www.itheima.com/images/logo.png',
random:Math.random()*10//10以内随机数
},
<view>{{info}}</view>
<image src="{{ImageData}}" mode="widthFix"></image>
<view>{{random>=5?'随机数大于等于5':'随机数小于5'}}</view>
2.事件绑定
1.bindtap 触摸事件
<!-- 点击内部按钮,点击事件以冒泡的方式向外扩散,也会触发外层view的tap事件
e.target指向的是触发事件的源头组件 是内部的按钮组件
e.currentTarget指向的是当前正在触发事件的组件 是当前view组件 -->
<view class="outer-view" bindtap="outerHandler">
<button type="primary">按钮</button>
</view>
<!-- 不能直接传参 data-*自定义属性传参 info 为参数名字 2 参数值 -->
<button type="primary" bindtap="changeCount" data-info="{{2}}">按钮</button>
// 事件处理函数
changeCount(e){
//dataset是一个对象 包含了所有通过data-*传递过来的参数项
console.log(e.target.dataset);
console.log(e.target.dataset.info);
//this.setData(dataObject)方法可以给页面data中的数据重新赋值
this.setData({
count:this.data.count+1
})
}
2.bindinput 文本框输入事件
<input value="{{msg}}" bindinput="inputHandle"></input>
inputHandle(e){
console.log(e.detail.value);//变化后的最新值
this.setData({
msg:e.detail.value
})
}
3.bindchange 状态改变
3.条件渲染
<!-- wx:if="{{}}"判断是否需要渲染该代码块 -->
<view wx:if="{{type===1}}">男</view>
<view wx:elif="{{type===2}}">女</view>
<view wx:else>保密</view>
<!-- 一次性控制多个组件的展示与隐藏,使用<block></block>标签将多个组件包装起来,在<block>标签上使用wx:if控制属性-->
<block wx:if="{{true}}">
<view>11</view>
<view>22</view>
</block>
<view hidden="{{flag}}">TRUE 隐藏</view>
4.列表渲染
<!-- wx:for根据指定的数组,循环渲染重复的组件结构,默认情况下索引index 当前循环项item -->
<view wx:for="{{arry}}">
索引{{index}},项目{{item}}
</view>
4.WXSS模板样式
5.数据请求
//发起get数据请求
getInfo(){
wx.request({
url: 'https://www.escook.cn/api/get',
method:'GET',
data:{
name:'zs',
age:20
},
success:(res)=>{
console.log(res);
}
})
},
//页面加载时调用 相当于created
onLoad(options) {
this.getInfo()
},
6.页面导航
页面之间相互跳转
1.声明式导航
在页面声明一个<navigator>导航组件,通过点击跳转
<!-- 跳转到tabBar页面 url必须/开头 必须有open-type="switchTab"-->
<navigator url="/pages/index/index" open-type="switchTab">跳转到消息页面</navigator>
<!-- 跳转到非tabBar页面 open-type="navigate"可以省略 -->
<navigator url="/pages/info/info?name=zs&age=20" open-type="navigate">跳转到info页面</navigator>
<!-- 后退导航 delta="1"是数字表示后退的层级 ,后退上一页可省略默认为1 -->
<navigator delta="1" open-type="navigateBack">返回上一页</navigator>
2.编程式导航
调用小程序的导航API
<button bindtap="getMessage">跳转到消息页面</button>
<button bindtap="get">跳转到info页面</button>
// 跳转到tabBar页面
getMessage(){
wx.switchTab({
url: '/pages/index/index',
})
},
// 跳转到非tabBar页面
get(){
wx.navigateTo({
url: '/pages/info/info?name=zs&age=20',
})
},
<button bindtap="getBack">返回上一页</button>
getBack(){
wx.navigateBack({
delta: 1,
})
},
3.导航传参
onLoad(options) {
//options就是导航传来的参数
console.log(options);
this.setData({
query:options
})
},
7.页面事件
1.下拉刷新
手指在屏幕下拉滑动,重新加载页面数据 enablePullDownRefresh:true
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
this.setData({
count:0
})
//当数据重置后,调用函数关闭下拉刷新
wx.stopPullDownRefresh()
},
2.上拉触底
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
console.log("触发上拉触底事件");
},
3.对上拉触底进行节流处理
如果连续触底多次会请求多页数据,所以如果当前正在请求下一页数据时,应该把后续的请求屏蔽,当前没有任何请求 时,才发起下一页请求
在data中定义isloading节流阀
false表示当前没有进行任何数据请求
true表示正在进行数据请求
getColor(){
//当前正在发起网络数据请求
this.setData({
isloading:true
})
//需要展示Loading效果
wx.showLoading({
title: '数据展示中',
})
wx.request({
url: 'https://www.escook.cn/api/color',
method:'GET',
success:({data:res})=>{
// console.log(res);
this.setData({
colorList:[...this.data.colorList,...res.data]
})
},
complete:()=>{
wx.hideLoading()//隐藏load效果
this.setData({
isloading:false
})
}
})
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
if (this.data.isloading) return //当为true则阻止当前请求
this.getColor()
},
8.生命周期
1.应用
//当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
onLaunch: function () {},
//当小程序启动,或从后台进入前台显示,会触发 onShow
onShow: function (options) {},
// 当小程序从前台进入后台,会触发 onHide
onHide: function () {},
2.页面
Page({
onLoad(options) {},//生命周期函数--监听页面加载
onReady() {},//生命周期函数--监听页面初次渲染完成,一个页面只调用一次
onShow() {},//生命周期函数--监听页面显示
onHide() {},//生命周期函数--监听页面隐藏
onUnload() {},//生命周期函数--监听页面卸载,一个页面只调用一次
})
9.自定义组件
1.局部引用
//在页面的.json文件中,引入组件
"usingComponents": {
"my-test1":"/components/test/test"
}
//在页面的.wxml文件中,使用组件
<my-test1></my-test1>
2.全局引用
每个小程序页面都可以使用
//在页面的app.json文件中,引入组件
"usingComponents": {
"my-test1":"/components/test/test"
}
//在页面的.wxml文件中,使用组件
<my-test1></my-test1>
3.样式
app.wxss中的全局样式对组件无效
只有class选择器会有样式隔离效果,id选择器,属性选择器,标签选择器不受样式隔离的影响
通过stylelsolation修改组件的样式隔离选项 ”stylelsolation“:”isolated
4.属性
properties用来接收外界传递到组件中的数据,倾向于存储外界传递到组件中的数据
data倾向于存储组件的私有数据
5.数据监听器
用于监听和响应任何属性和数据字段的变化,从而执行特定的操作,类似watch
methods: {
add1(){
this.setData({
n1:this.data.n1+1
})
},
add2(){
this.setData({
n2:this.data.n2+1
})
}
},
//数据监听
observers:{
//监听n1,n2
'n1,n2':function(n1,n2){
this.setData({
sum:n1+n2
})
}
}
6.生命周期
1.组件的生命周期
1.created 组件实例刚被创建时执行,不能调用setData函数
2.attached 组件实例进入页面节点树时执行 this.data已经初始化完成,可以进行大多数初始化的工作
3.ready 组件在视图层布局完成后执行
4.moved 组件实例被移动到节点树另一个位置时执行
5.detached 组件实例被从页面节点树移除时执行
6.error组件方法抛出错误时执行
2.组件所在页面的生命周期
1.show 组件所在页面被展示时执行
2.hide 组件所在页面被隐藏时执行
3.resize 组件所在页面尺寸变化时执行
7.插槽
<slot>用于承载组件使用者提供的wxml结构
test1.wxml
<view>
<slot name="be"></slot>
<view>这里是组件内部结构</view>
<slot name="he"></slot>
</view>
home.wxml
<my-test1 max="100">
<!-- 这个view被填充到slot位置 -->
<view slot="be">be</view>
<view slot="he">he</view>
</my-test1>
options:{
multipleSlots:true//启用多个插槽
},
8.组件通信
1.属性绑定父传子
home.wxml
<!-- 子组件 -->
<my-test1 count="{{count}}">
</my-test1>
<!-- 父组件 -->
<view>{{count}}</view>
test.js
properties: {
count:Number
},
2.事件绑定子传父
1.在父组件的js中定义一个函数,这个函数即将通过自定义事件传递给子组件
2.在父组件的wxml中通过自定义事件将1中定义的函数引用,传递给父组件
3.在子组件的js通过this.triggerEvent('自定义事件',{参数对象}),将数据发送给父组件
4.在父组件js中,通过e.detail获取子组件传递的数据
home
<my-test1 count="{{count}}" bind:sync="syncCount">
syncCount(e){
// console.log(e.detail);
this.setData({
count:e.detail.value
})
},
test
addcount(){
this.setData({
count:this.properties.count+1
})
this.triggerEvent('sync',{value:this.properties.count})
}
3.获取组件实例
<my-test1 count="{{count}}" bind:sync="syncCount" class="count">
</my-test1>
<button bindtap="getcount">获取子组件实例</button>
getcount(){
const child=this.selectComponent('.count')
child.setData({count:child.properties.count+1})
child.addcount()
},
9.子组件behaviors
用于实现组件间代码共享 相当于mixins
使用require()方法导入
挂载:behaviors:[mybehavior]
10.Npm
1.vant组件库
初始化包 npm init -y
/**app.wxss**/ /* 定制全局主题样式 */ page{ --button-danger-background-color:#c00000; }
2.实现API promise化
npm i --save miniprogram-api-promise
import{proisifyAll} from 'miniprogram-api-promise'
const wxp=wx.p={}
proisifyAll(wx,wxp)
wx.request基于回调函数的异步API
调用promise化API
async getpro(){
const res= await wx.p.request({
method:'GET',
url:'https://www.escook.cn/api/get',
data:{
name:'zs',
age:20
}
})
console.log(res);
},
3.全局数据共享
npm install --save mobx-miniprogram mobx-miniprogram-bindings
mobx-miniprogram创建store实例对象
mobx-miniprogram-bindings把store中的共享数据或方法,绑定到组件或页面中使用
//创建store实例对象
import {action, observable} from 'mobx-miniprogram'
export const store =observable({
//数据字段
numA:1,
numB:2,
//计算属性
get sum(){
return this.numA+this.sumB
},
//actions方法,用来修改store中的数据
updateNum1:action(function(step){
this.sumA+=step
}),
updateNum2:action(function(step){
this.sumB+=step
}),
})
在页面使用
<text>联系</text>
<view>{{numA}}+{{numB}}={{sum}}</view>
<vant-button type="primary" bindtap="btn1" data-step="{{1}}">
numA+1
</vant-button>
<vant-button type="danger" bindtap="btn1" data-step="{{-1}}">
numA-1
</vant-button>
import {createStoreBindings} from 'mobx-miniprogram-bindings'
import {store} from '../../store/store'
onLoad(options) {
this.storeBindings=createStoreBindings(this,{
store,
fields:['numA','numB','sum'],
actions:['updateNum1']
})
},
btn1(e){
this.updateNum1(e.target.dataset.step)
// console.log(e);
},
onUnload() {
this.storeBindings.destroyStoreBindings()
},
4.分包
"subPackages": [ { "root":"A", "pages":[ "pages/cat/cat" ] }
11.自定义tabbar
12.黑马优购项目
uni-app
在线文档1. 起步 | uniapp - 黑马优购 (escook.cn)
1.微信小程序后台一直报403的错误,关闭了一个设置
2.保存subPackages 新建页面才会有分包的选项
3.css3中有一个很有趣的属性position:sticky,粘性属性,效果是一个吸顶效果,可以说是相对定位relative和固定定位fixed的结合;它主要用在对scroll事件的监听上;简单来说,在滑动过程中,某个元素距离其父元素的距离达到sticky粘性定位的要求时 (比如top:100px);position:sticky这时的效果相当于fixed定位,固定到适当位置。
4.搜索框防抖处理:定义一个定时器在500毫秒内没有触发新的输入事件,则为搜索关键词赋值
clearTimeout(this.timer)
this.timer=setTimeout(()=>{
this.kw=e
console.log(this.kw);
},500)
5.通过watch侦听器,监听计算属性total值得变化,从而动态为购物车按钮赋值,但是使用普通函数形式定义的watch侦听器,在页面首次加载后不会被调用。因此导致了商品详情页在首次加载完毕之后,不会将商品的总数量显示到商品导航区域。
为了防止这个上述问题,可以使用对象的形式来定义 watch 侦听器
6.mixins:除了要在 cart.vue 页面中设置购物车的数字徽标,还需要在其它 3 个 tabBar 页面中,为购物车设置数字徽标。将设置 tabBar 徽标的代码抽离为 mixins
7.改变购物车的数量后,重新编译数量又被重置,且tab栏中的数字随着数量改变也不变(把绑定的事件@写成了: 找了一下午的bug。。。。。)