1.组件案例
(1)跳转到商品列表
跳转要用navigation组件,常用的属性有2个:

注意事项:
a.路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔
例如:/list?id=10&name=hua,在onLoad(options)生命周期函数中获取传递的参数
b.open-type="switchTab"时不支持传参
html
<!-- 在进行 页面跳转时,需要在路径的前面加 / 斜线,否则跳转不成功 -->
<navigator url="/pages/list/list?id=10&num=hua">到商品列表页面</navigator>
<navigator url="/pages/cate/cate?id=10&num=hua" open-type="switchTab">到商品分类页面</navigator>
<!-- navigate:只能跳转到非 TabBar 页面,不能跳转到 TabBar 页面,保留上一级页面-->
<navigator url="/pages/list/list" open-type="navigate">到商品列表页面</navigator>
<navigator url="/pages/cate/cate" open-type="navigate">到商品分类页面</navigator>
<!-- redirect:只能跳转到非 TabBar 页面,不能跳转到 TabBar 页面,关闭上一级页面-->
<navigator url="/pages/list/list" open-type="redirect">到商品列表页面</navigator>
<navigator url="/pages/cate/cate" open-type="redirect">到商品分类页面</navigator>
<!-- switchTab:只能跳转到 TabBar 页面,不能跳转到非 TabBar 页面,关闭其他所有的非 TabBar 页面-->
<navigator url="/pages/list/list" open-type="switchTab">到商品列表页面</navigator>
<navigator url="/pages/cate/cate" open-type="switchTab">到商品分类页面</navigator>
<!-- reLaunch:关闭所有页面,打开小程序中某一个页面 -->
<navigator url="/pages/list/list" open-type="reLaunch">到商品列表页面</navigator>
<navigator url="/pages/cate/cate" open-type="reLaunch">到商品分类页面</navigator>
<!-- navigateBack:返回上一页或者返回前几页,默认只能返回上一页 -->
<!-- delta:返回的层级,默认是 1,如果想返回几级,就写几 -->
<navigator open-type="navigateBack" delta="1">返回上一页</navigator>
(2)推荐商品区域
在微信想小程序中如果想实现内容滚动,需要使用scroll-view组件
scroll-view:可滚动视图区域,适用于需要滚动展示内容的场景,用于在小程序中实现类似于
网页中的滚动条效果,用户可以通过手指滑动或者点击滚动条来滚动内容。
来学习两个属性:
scroll-x:允许横向滚动
scroll-y:允许纵向滚动
html
<scroll-view class="scroll-x" scroll-x>
<view>1</view>
<view>2</view>
<view>3</view>
</scroll-view>
<scroll-view class="scroll-y" scroll-y>
<view>1</view>
<view>2</view>
<view>3</view>
</scroll-view>
(3)实现结构样式
html
<view class="goods-hot">
<scroll-view scroll-x class="scroll-x">
<view>
<view class="good-item">
<image src="../../assets/floor/1.png" mode=""/>
<text>灰太狼</text>
<text>66</text>
</view>
</view>
<view>
<view class="good-item">
<image src="../../assets/floor/2.png" mode=""/>
<text>蕉太狼</text>
<text>99</text>
</view>
</view>
<view>
<view class="good-item">
<image src="../../assets/floor/3.png" mode=""/>
<text>红太狼</text>
<text>88</text>
</view>
</view>
<view>
<view class="good-item">
<image src="../../assets/floor/1.png" mode=""/>
<text>黑太狼</text>
<text>77</text>
</view>
</view>
<view>
<view class="good-item">
<image src="../../assets/floor/2.png" mode=""/>
<text>银太狼</text>
<text>55</text>
</view>
</view>
</scroll-view>
</view>
(4)字体图标的使用
在项目中使用到的小图标,一般由公司设计师进行设计,设计好以后上传到阿里巴巴矢量图 标库,然后方便程序员来进行使用
小程序中的字体图标使用方式与Web开发中的使用方式是一样的
注意事项:
使用字体图标可能会报错:[渲染层网络层错误] Failed to load font.. 该错误可忽略
但在控制台出现错误,会影响开发调试,解决方案是:将字体图标转换成base64的格式
2.事件系统
(1)事件绑定和事件对象

html
<!-- 第一种绑定事件的方式:bind:事件名 -->
<button type="primary" bind:tap="handler">绑定事件</button>
<!-- 第二种绑定事件的方式:bind事件名 -->
<button type="warn" bindtap="handler">绑定事件</button>
javascript
Page({
// 事件处理函数需要写到 Page() 方法中才可以
handler (event) {
// console.log('事件触发了~~~')
console.log(event)
}
})
(2)事件分为冒泡事件和非冒泡事件
事件分为冒泡事件和非冒泡事件:
冒泡事件:当一个组件的事件被触发后,该事件会向父节点传递
非冒泡事件:当一个组件的事件被触发后,该事件不会向父节点传
使用bind绑定的事件,会触发事件冒泡,如果想阻止事件冒泡,可以使用catch来绑定事件
javascript
<view class="catch" bind:tap="parentHandler">
<button catch:tap="btnHandler">按钮</button>
</view>
javascript
Page({
parentHandler () {
console.log('父组件绑定的事件')
},
btnHandler () {
console.log('子组件触发的事件')
},
})
(3)事件传参-data-*自定义数据

html
<view bind:tap="parentHandler" data-parent-id="1" data-parentName="tom">
<!-- 如果需要进行事件传参,需要在组件上通过 data- 的方式传递数据 -->
<!-- <button bind:tap="btnHandler" data-id="1" data-name="tom">按钮</button> -->
<button data-id="1" data-name="tom">按钮</button>
</view>
javascript
// pages/cate/cate.js
Page({
// 按钮触发的事件处理函数
btnHandler (event) {
// currentTarget 事件绑定者,也就是指:哪个组件绑定了当前事件处理函数
// target 事件触发者,也就是指:哪个组件触发了当前事件处理函数
// currentTarget 和 target 都是指按钮,因为是按钮绑定的事件处理函数,同时点击按钮触发事件处理函数
// 这时候通过谁来获取数据都可以
console.log(event.currentTarget.dataset.id)
console.log(event.target.dataset.name)
},
// view 绑定的事件处理函数
parentHandler (event) {
// 点击蓝色区域(不点击按钮)
// currentTarget 事件绑定者:view
// target 事件触发者:view
// currentTarget 和 target 都是指 view,如果想获取 view 身上的数据,使用谁都可以
// 点击按钮(不点击蓝色区域)
// currentTarget 事件绑定者:view
// target 事件触发者:按钮
// 如果想获取 view 身上的数据,就必须使用 currentTarget 才可以
// 如果想获取的是时间触发者本身的数据,就需要使用 target
console.log(event)
// 在传递参数的时候,如果自定义属性是多个单词,单词与单词直接使用中划线 - 进行连接
// 在事件对象中会被转化为小驼峰写法
console.log(event.currentTarget.dataset.parentId)
// 在传递参数的时候,如果自定义属性是多个单词,单词如果使用的是小驼峰写法
// 在事件对象中会被转化为全部小写的
console.log(event.currentTarget.dataset.parentName)
}
})
(4)事件传参-mark自定义数据

html
<view bind:tap="parentHandler" mark:parentid="1" mark:parentname="tom">
<!-- 如果需要使用 mark 进行事件传参,需要使用 mark: 自定义属性的方式进行参数传递 -->
<!-- <button bind:tap="btnHandler" mark:id="1" mark:name="tom">按钮</button> -->
<button mark:id="1" mark:name="tom">按钮</button>
</view>
javascript
// pages/cart/cart.js
Page({
// 按钮绑定的事件处理函数
btnHandler (event) {
console.log(event.mark.id)
console.log(event.mark.name)
},
// view 绑定的事件处理函数
parentHandler (event) {
// 先点击蓝色区域(不点击按钮)
// 通过事件对象获取的是 view 身上绑定的数据
// 先点击按钮(不点击蓝色区域)
// 通过事件对象获取到的是 触发事件的节点 以及 父节点身上所有的 mark 数据
console.log(event)
}
})
(5)声明和绑定数据

html
<!-- 如果需要展示数据,在 wxml 中需要使用双大括号写法将变量进行包裹 -->
<!-- 展示内容 -->
<view>{{ school }}</view>
<view>{{ obj.name }}</view>
<!-- 绑定属性值 如果需要动态绑定一个变量,属性值也需要使用双大括号进行包裹 -->
<view id="{{ id }}">绑定属性值</view>
<!-- 如果属性值是布尔值,也需要使用双大括号进行包裹 -->
<checkbox checked="{{ isChacked }}"/>
<!-- 算术运算 -->
<view>{{ id + 1 }}</view>
<view>{{ id - 1 }}</view>
<!-- 三元运算 -->
<view>{{ id === 1 ? '等于' : '不等于' }}</view>
<!-- 逻辑判断 -->
<view>{{ id === 1 }}</view>
<!-- 在双大括号写法内部只能写表达式,不能写语句,也不能调用 js 的方法 -->
<!-- <view>{{ if (id === 1) {} }}</view> -->
javascript
// index.js
Page({
// 在小程序页面中所需要使用的数据均来自于 data 对象
data: {
school: '青青草原',
obj: {
name: 'tom'
},
id: 1,
isChecked: false,
}
})
(6)setData()修改数据

(7)setData()一修改对象类型数据
增单个/多个属性
修改单个/多个属性
删除单个/多个属性
(8)setData()-修改数组类型数据
新增数组元素
修改数组元素
删除数组元素
html
<view>{{ num }}</view>
<button bind:tap="updateNum">更新 num</button>
<view class="line"></view>
<view>{{ userInfo.name }}</view>
<view>{{ userInfo.age }}</view>
<button type="warn" bind:tap="updateUserInfo">修改对象类型数据</button>
<view class="line"></view>
<view wx:for="{{ list }}" wx:key="index">{{ item }}</view>
<!-- <view>{{ list[0].name }}</view> -->
<button type="primary" bind:tap="updateList">修改数组类型数据</button>
javascript
// pages/cate/cate.js
Page({
data: {
num: 1,
userInfo: {
name: 'tom',
age: 18,
test: 111
},
list: [1,2,3]
// list: [ { id:1, name:'tom' } ]
},
// 更新 num
updateNum () {
// 获取数据
// console.log(this.data.num)
// 通过赋值的方式直接修改数据
// 能够修改数据,但是不能改变页面上的数据
// this.data.num += 1
// console.log(this.data.num)
// this.setData 两个作用
// 1.更新数据
// 2.驱动视图更新
this.setData ({
// key: 是需要可更新的数据
// value: 是最新的值
num: this.data.num + 1
})
},
// 更新userInfo
updateUserInfo () {
// // 新增单个 / 多个属性
// this.setData({
// // 如果给对象新增属性,可以将 key 写成数据路径的方式 a.b.c
// 'userInfo.name': 'tom',
// 'userInfo.age': 18
// })
// // 修改单个 / 多个属性
// this.setData({
// // 如果需要修改对象属性,可以将 key 写成数据路径的方式 a.b.c
// 'userInfo.name': 'jerry',
// 'userInfo.age': 20
// })
// 目前进行新增和修改都是使用数据路径,如果新增和修改数据量比较小,还可以
// 如果修改数据很多,每次都写数据路径,就太麻烦了
// 可以使用 ES6 提供是展开运算符 和 Object.assign()
// // ES6 提供是展开运算符
// // 通过展开运算符能够将对象中的属性复制给另一个对象
// // 后面的属性会覆盖前面的属性
// const userInfo = {
// ...this.data.userInfo,
// name: 'jerry',
// age: 20
// }
// this.setData({
// userInfo
// })
// // Object.assign() 将多个对象合并为一个对象
// const userInfo = Object.assign(this.data.userInfo,{ name: 'jerry' },{ age: 20 })
// this.setData ({
// userInfo
// })
// // 删除单个属性
// delete this.data.userInfo.age
// console.log(this.data.userInfo)
// this.setData({
// userInfo: this.data.userInfo
// })
// 删除多个属性 rest 剩余参数
const { age, test, ...rest } = this.data.userInfo
this.setData({
userInfo: rest
})
},
// 更新 list
updateList () {
// 新增数组元素
// 如果直接使用 push 方法,可以直接更新 data,但是不能更新 页面中的数据
// this.data.list.push(4)
// this.data.list.push(4)
// this,this.setData({
// list: this.data.list
// })
// const newList = this.data.list.concat(4)
// this.setData({
// list: newList
// })
// const newList = [ ...this.data.list, 4 ]
// this.setData({
// list:newList
// })
// 修改数组元素
// this.setData({
// // 'list[1]':6
// 'list[0].name': 'jerry'
// })
// 删除数组元素
// this.data.list.splice(1, 1)
// this.setData({
// list:this.data.list
// })
const newList = this.data.list.filter(item => item !== 2)
this.setData({
list: newList
})
}
})
(9)列表渲染-基本使用

(10)列表渲染-进阶用法

(11)条件渲染

html
<!-- wx:if 属性组 -->
<!-- wx:if wx:elif wx:else -->
<!-- 只有对应的条件成立,属性所在的组件才会进行展示 -->
<!-- <view wx:if="{{ num === 1 }}">num 等于 {{ num }}</view>
<view wx:elif="{{ num === 2 }}">num 等于 {{ num }}</view>
<view wx:else>num 大于 2, 目前 num 等于 {{ num }}</view> -->
<!-- wx:elif wx:else 不能单独使用,在使用的时候,必须结合 wx:if 来使用 -->
<!-- <view wx:if="{{ num === 1 }}">num 等于 {{ num }}</view>
<view wx:elif="{{ num === 2 }}">num 等于 {{ num }}</view>
<view wx:else>num 大于 2, 目前 num 等于 {{ num }}</view> -->
<!-- 使用了wx:if 属性组不能被打断,组件必须连贯才可以 -->
<view wx:if="{{ num === 1 }}">num 等于 {{ num }}</view>
<view wx:elif="{{ num === 2 }}">num 等于 {{ num }}</view>
<view wx:else>num 大于 2, 目前 num 等于 {{ num }}</view>
<!-- hidden 属性 -->
<!-- hidden 属性 属性值 如果是 true,就会隐藏结构,如果是 false,才会展示 -->
<view hidden="{{ !isFlag }}">如果 isFlag 是true,展示结构,否则隐藏结构</view>
<!-- wx:if 控制结构的展示和隐藏,是通过新增和移除结构来实现的 -->
<!-- hidden 属性控制结构的展示和隐藏,是通过 css 的 display 属性来实现 -->
<button type="warn" bind:tap="updateNum">更新 num</button>
javascript
Page({
data: {
num: 1,
isFlag: true
},
// 更新 num
updateNum () {
this.setData({
num: this.data.num + 1
})
}
})
(12)简易双向数据绑定

html
<!-- 单向绑定:数据能够影响页面,但是页面更新不会影响到数据 -->
<!-- <input type="text" value="{{ value }}"/> -->
<!-- 双向绑定:数据能够影响页面,页面更新也能够影响数据 -->
<!-- 如果实现简易双向绑定,需要在对应的属性前面添加 model: -->
<!-- <input type="text" model:value="{{ value }}"/> -->
<!-- 如果需要获取复选框的选中效果,需要给 checked 添加 model: -->
<!-- <checkbox model:checked="{{ isChecked }}"/>是否同意该协议 -->
<!-- 注意事项1:属性值只能是一个单一字段的绑定 -->
<!-- <input type="text" model:value="值为{{ value }}"/> -->
<!-- 注意事项2:属性值不能写数据路径,也就是不支持对象和数组 -->
<input type="text" model:value="{{ obj.value }}"/>
javascript
// pages/cart/cart.js
Page({
data: {
value: 123,
isChecked: false,
obj: {
value: 123
}
}
})
(13)小程序运行机制


(14)小程序生命周期介绍

(15)小程序更新机制

(16)应用生命周期

页面生命周期

(17)生命周期两个细节

(18)小程序API介绍

(19)网络请求

