tabber配置
"tabBar": {
"color": "#a9b7b7",
"selectedColor": "#11cd6e",
"borderStyle": "black" ,
"list": [
{
"selectedIconPath": "icon/home-o.png",
"iconPath": "icon/home.png",
"pagePath": "pages/index/index",
"text": "首页"
},
{
"selectedIconPath": "icon/category-o.png",
"iconPath": "icon/category.png",
"pagePath": "pages/category/category",
"text": "一元投"
}
]
},
运算
运算符 => 表达式
1.可以在花括号里面加入表达式语句
2.表达式
指的是一些简单的 数组运算 字符串拼接 逻辑运算
1. 数字的加减
2. 字符串拼接
3. 三元表达式
<view>{{ 1 + 1}}</view>
<view>{{ 1 + '2'}}</view>
<view>{{ 10 % 2 === 0 ? '偶数' : '基数'}}</view>
<view>{{ false || 1 }}</view>
<view>{{ true || 1 }}</view>
<view>{{ true && 1 }}</view>
循环
<!-- wx:for循环 -->
<!--
1.wx:for='{{数组或者对象}}' wx:for-item="循环的名称" wx:for-index="循环的索引"
2.wx:key="唯一的值" 用来提高性能
1. wx:key 绑定一个普通的字符串的时候 那么这个字符串名称 肯定是数组中的对象的唯一属性
2. wx:key = "*this" 这种表示循环一个数组的时候用这个
3. 当出现循环嵌套时候 要注意绑定名称不要重复
-->
<view
wx:for="{{list}}"
wx:for-item="item"
wx:for-index="index"
wx:key="id">
{{index}} - {{item.name}}
</view>
<!--
默认情况下 我们不写
wx:for="{{list}}"
wx:for-item="item"
wx:for-index="index"
item 和 index 也是生效的
只有一层的话 wx:for-item="item" wx:for-index="index" 可以省略
-->
<view wx:for="{{list}}" wx:key='*this'>{{item.name}}</view>
<!--
对象循环
1.wx:for='{{对象}}' wx:for-item="对象的值" wx:for-index="对象的属性"
2. 循环对象的时候 最好把item 和 index 的名称改一下
wx-for-item = 'value' wx:for-index = 'key'
-->
<view wx:for="{{obj}}" wx:for-item="value" wx:for-index='key'>
{{key}} - {{value}}
</view>
blck
- 占位符
- 写代码的时候 可以看到整个标签的存在
- 页面的渲染小程序会把他移除掉
条件渲染
条件渲染
1. wx:if="{{true / false}}"
wx:if
wx:elif
wx:else
2. hidden
在标签上直接加入属性hidden
hidden="{{true}}"
3. 什么场景使用哪个
1. 当标签不是频繁切换显示 优先使用 wx:if (直接把标签从页面中移除掉)
2. 当标签频繁切换显示 优先使用 hidden (通过添加样式方法来切换显示)
事件绑定
1. 需要给input标签绑定 input事件
绑定关键字 bindinput
2. 如果获取输入框的值
通过事件源对象来获取
e.detail.value
3. 把输入框的值赋值给data当中
不能直接用vue中的方法
this.num = e.detail.value
正确写法
this.setData({
num: e.detail.value
})
在js中拿到data的值
this.data.num
4. 点击事件 bindtap
1. 无法在小程序中直接通过函数传参 bindtap='readletap(1)'
2. 通过自定义属性传递参数 data-num='{{1}}' js中通过e.currentTarget.dataset.num
wxml
<input type="text" value="{{num}}" bindinput="gbInput" />
<button size="mini" bindtap='readletap' data-num='{{1}}'>+</button>
<button size="mini" bindtap='readletap' data-num='{{-1}}'>-</button>
<view>{{num}}</view>
js
// pages/demo1/demo1.js
Page({
data: {
num: 0
},
gbInput(e) {
this.setData({
num: parseInt(e.detail.value)
})
},
readletap(e) {
this.setData({
num: e.currentTarget.dataset.num + this.data.num
})
}
})
尺寸单位
rpx 可以根据屏幕进行自适应,规定屏幕为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375rpx物理像素,1rpx = 0.5px = 1物理像素。
设备 rpx换算px (屏幕宽度/750) px换算rpx (750/屏幕宽度)
image.png
建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。
注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。
需要把页面中的某些元素的单位 由 px 改成prx
1 设计稿 750 px
750 px = 750 rpx
1 px = 1 rpx
2 把屏幕高度改成 375
375 px = 750 rpx
1 px = 2rpx
1rpx = 0.5px
3 如果存在一个设计稿 宽度 414 或者 未知 page
1 设计稿 page 存在一个元素 宽度 100px
2 拿以上的需求 去实现 不同宽度的页面适配
page px = 750rpx
1 px = 750rpx / page
100 px = 750 rpx * 100 / page
样式导入
通过@ import 来引入
路径只能写相对路径
@ import “../../styles/common.wxss”;
选择器和使用less
小程序不知此通配符 *{}
image.png
常见标签
常用 view, text, rich-text, button, image, navigator, icon, swiper, radio, checkbox。 等等
text
text的decode可以解析的有 < > & '    
image
image 图片标签
1 src 指定要加载的图片路径
图片存在默认的宽度和高度 320 * 240 不设置宽高,就会默认320 * 240
2 mode 决定 图片内容 如何 和 图片标签 宽高 适配 列举一些常用的
1. scaleToFill 默认值 不保持丛横比缩放图片,使用图片的宽高完全拉伸填满 image 元素
2 aspectFit 保持宽高比 确保图片的长边 显示出来 适合页面轮播图 (常用)
3 aspectFill 保持纵横比缩放图片, 只保证图片的 短 边能完全显示出来。 (少用)
4 widthFix 以前web图片的 宽度指定后 高度会自己安装比例来调整 (常用)
5 bottom。。 类似以前的background-position
3. 小程序中的image 直接支持 懒加载 lazy-load
1. lazy-load会自己判断 当 图片 出现在视口 上下 三屏的时候 自己开始加载图片
Swiper
swiper 标签 存在默认样式
width:100%
height: 150px image 存在默认宽度和高度 320 * 240
swiper高度无法实现由内容撑开
先找出 原图的宽度和高度 等比例 给swiper 定 宽度和高度
原图的宽度和高度 750 * 310
swiper 宽度 / swiper 宽度 = 原图的宽度 / 原图的高度
swiper 高度 = swiper 宽度 * 原图的高度 / 原图的宽度
height:
* 310 / 750
窗口固定宽度为100vw,将窗口宽度平均分为100份,每一份是1vw。
窗口固定高度为100vh,将窗口高度平均分为100份,每一份是1vh。
<swiper>
<swiper-item>
<image mode="widthFix" src="//pic50.t8tcdn.com/adcms/ad/201909/25/c8cad7f58fd875d5d3ef020f11c7886d6696.jpg" />
</swiper-item>
<swiper-item>
<image mode="widthFix" src="//pic50.t8tcdn.com/adcms/ad/202001/17/938f8f2dbb8e1c30bd47cda9ca65f5cb83269.jpg" />
</swiper-item>
</swiper>
wxss
swiper{
width: 100%;
/* height: calc(750rpx * 310 / 750); */
height: calc(100vw * 310 / 750);
/*height: 图片的高度也可以*/
}
image {
width: 100%;
}
navigator
导航组件 navigator
块级元素 默认会换行 可以直接加宽度高度
1 参数 url 要跳转的页面路径 可以绝对路径 相对路径
2 参数 target 要跳转到当前的小程序 还是其他的小程序
target = 'self' 默认值 自己小程序页面
miniprogram 其他小程序页面
3 open-type 跳转方式
1 navigator 默认值 保留当前页面,跳转到应用内的某个页面,但不能跳到tabbar页面
2 redirect 关闭当前页面,跳转到应用内的某个页面,但不允许跳转tabber
3 switchTab 跳转到 tabber 页面,并关闭所有非 tabBer 页面
4 reLaunch 关闭所有页面 打开到应用中
<!-- navigator 默认值 跳转到pages/demo/demo 顶部显示可以返回箭头 可返回当前页面 -->
<navigator url="/pages/demo/demo">跳转</navigator>
<!-- redirect 跳转到pages/demo/demo 顶部左上角显示返回首页 关闭当前页面 不能返回当前页面 -->
<navigator url="/pages/demo/demo" open-type="redirect">跳转</navigator>
<!-- 跳转到 tabber 页面,不能返回非tabber的页面 -->
<navigator open-type="switchTab" url="/pages/index/index"></navigator>
<!-- reLaunch 可以随便跳转哪个页面 左上角返回首页 关闭当前页面 -->
<navigator open-type="reLaunch" url="/pages/demo/demo">reLaunch 跳转</navigator>
rich-text 富文本标签
可以解决服务端传过来的富文本编辑的文章
wxml
<rich-text nodes="{{html}}"></rich-text>
js
// pages/demo3/demo3.js
Page({
data: {
html: '<div style="color: red">哈哈哈</div>'
},
})
button外观样式
button
外观的属性
1 size 控制按钮的大小 默认是大尺寸
sizr='mini' 小尺寸
2 type 用来控制按钮的颜色
type='default' 灰色
type='primary' 绿色
type='warn' 红色
3 plain 镂空
4 loading 在按钮前面会有一个loading
<button size='mini'>按钮</button>
<button>default按钮</button>
<button type='primary'>primary按钮</button>
<button type='warn'>warn按钮</button>
<button type='warn' plain>plain按钮</button>
<button type='primary' loading>loading</button>
button 开放能力
button
open-type:
1 contact 直接打开 客服对话功能 需要在微信小程序的后台配置
2 share 转发当前的小程序 到微信朋友中 不能把小程序 分享到朋友圈
3 getPhoneNumber 获取当前用户手机号码信息 结合一个事件来使用 不是企业的小程序账号 没有权限来获取用户手机号码
1 绑定一个事件bindgetphonenumber
2 在事件的回调函数中 通过参数来获取信息
3 获取到的信息 已经加密过了
需要搭建小程序后台,在后台服务器中进行解析,然后再传到小程序页面中 就可以看到用户的手机号码了
4 getUserInfo 获取当前用户的个人信息
使用方法 类似 获取当前用户的手机号码
可以直接获取 不存在加密的字段
通过 回调 bindgetuserinfo = 'getInfo'
getInfo(e) {}
5 launchApp 在小程序当前直接打开app 页面
需要 在app中 通过app的某个链接打开小程序
在小程序中在通过这个功能重新打开app
6 openSetting 打开小程序的内置 授权页面
授权页面中 只会出现用户曾经授权过的权限
7 feedback 打开小程序 内置的 用户意见反馈页面
只能通过真机来打开
<button open-type='contact'>contact</button>
<button open-type='share'>share</button>
<button open-type='getPhoneNumber' bindgetphonenumber="getPhone">getPhoneNumber</button>
<button open-type="getUserInfo" bindgetuserinfo="getInfo">getUserInfo</button>
<button open-type="openSetting">openSetting</button>
<button open-type="feedback">feedback</button>
<image src="{{userInfo.avatarUrl}}"></image>
icon
image.png
单选框
radio 单选框
1 radio标签 必须和父元素 radio-group 来使用
2 value 选中的单选框的值
3 需要给radio-group 绑定bindchange事件
4 需要在页面中显示选中的值
5 color 改变单元框的颜色
<radio-group bindchange='getGender'>
<radio value='男' checked="{{true}}" color='red'>男</radio>
<radio value='女'>女</radio>
</radio-group>
<view>选中的信息:{{gender}}</view>
// pages/demo5/demo5.js
Page({
data: {
gender: '男',
current: 0
},
getGender(e) {
let gender = e.detail.value
this.setData({
gender
})
},
nextFn() {
let _this = this.data;
if(_this.current === 2) {
this.setData({
current: 0
})
}else {
this.setData({
//前加加 先加在赋值
current: ++ this.data.current
//不起作用是因为 后加加 先赋值后加价
// current: this.data.current++
})
}
}
})
checkbox
<view>
<checkbox-group bindchange='getValue'>
<checkbox wx:for="{{list}}" value="{{item.value}}" wx:key="id">
{{item.name}}
</checkbox>
</checkbox-group>
</view>
// pages/demo6/demo6.js
Page({
data: {
list: [
{
id: 1,
name: '苹果',
value: 'apply'
},
{
id: 2,
name: '葡萄',
value: 'grape'
},
{
id: 3,
name: '香蕉',
value: 'banana'
}
],
checkList: []
},
getValue(e) {
this.setData({
checkList: e.detail.value
})
console.log(e);
}
})
小程序自定义组件初体验
第一步 创建components文件夹,在components文件夹中建一个组件
image.png
第二步 在想用组件的地方,打开json修改 组件路径
{
"usingComponents": {
"Tabs1": "../../components/Tabs/Tabs"
}
}
第三步 在wxml 中使用
<Tabs1></Tabs1>
自定义组件-父向子传递数据
父组件wxml
<!--pages/demo1/demo1.wxml-->
<Tabs1 abc="abc123"></Tabs1>
子组件js
Component({
/**
* 组件的属性列表
*/
properties: {
//要接受父组件的名称,子组件直接用{{abc}} 即可
abc: {
type: String, //要接受的数据类型
value: ' ' //默认值,如果父组件不传值,就以value值为准
}
},
})
子组件wxml
<view>
//页面上的值 就是 abc123
{{abc}}
</view>
父向子传递数据demo
父组件wxml
<Tabs1 tabs="{{tabs}}"></Tabs1>
父组件js
// pages/demo1/demo1.js
Page({
data: {
tabs: [
{
id: 1,
name: '首页',
active: true
},
{
id: 2,
name: '原创',
active: false
},
{
id: 3,
name: '分类',
active: false
},
{
id: 4,
name: '关于',
active: false
}
]
}
})
子组件js
// components/Tabs.js
Component({
/**
* 组件的属性列表
*/
properties: {
//要接受父组件的名称,子组件直接用{{abc}} 即可
tabs: {
type: Array, //要接受的数据类型
value: [] //默认值,如果父组件不传值,就以value值为准
}
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
eventTabs(e) {
let { index } = e.target.dataset;
let { tabs } = this.data;
//forEach 改变原数组
tabs.forEach((v, i) => i === index ? v.active = true : v.active = false);
this.setData({
tabs
})
}
}
})
子组件wxml
<view class="tabs">
<view class="tabs_title">
<!-- wx:for 循环默认 又 wx:for-item = 'item' 可以拿到循环的内容 wx:for-index = "index" 可以拿到循环的索引 -->
<view
bindtap="eventTabs"
wx:for="{{tabs}}"
wx:key="id"
data-index = '{{index}}'
class="tabs-item {{item.active ? 'active' : ''}}">
{{item.name}}
</view>
</view>
</view>
子元素向父元素传递数据
子向父传递数据 通过事件的方式传递
在子组件的标签中加入一个自定义组件
- 子组件js
methods: {
eventTabs(e) {
let { index } = e.target.dataset;
//向父组件传递值
// 触发父组件中的自定义组件 同时传递数据 给 父组件
// this.triggerEvent('父组件自定义的事件名称', { 要传递的参数 })
this.triggerEvent('changeItem', { index });
}
}
- 父组件wxml
//bindchangeItem 是子组件自定义的事件
<Tabs1 tabs="{{tabs}}" bind:changeItem="handleItemChange"></Tabs1>
父组件js
handleItemChange(e) {
let { index } = e.detail; // 1
//上面代码等价于
//let index = e.detail.index
}
slot 插槽
slot 标签 其实就是一个占位符 插槽
等到 父组件 调用 子组件的时候 再传递 标签过来 最终这些被传递的标签
就会替换slot插槽位置
子组件wxml
<view>
<!--
slot 标签 其实就是一个占位符 插槽
等到 父组件 调用 子组件的时候 再传递 标签过来 最终这些被传递的标签
就会替换slot插槽位置
-->
<slot></slot>
</view>
父组件wxml
<Tabs1>
父组件传过来的值
</Tabs1>
组件的其他属性
image.png
app.js 应用生命周期
App({
// 应用第一次启动的就会触发的事件
onLaunch() {
// 在应用第一次启动时候, 获取个人信息
console.log('onLaunch');
},
// 应用 被用户看见 触发事件
onShow() {
// 对应用的数据或者页面效果重置
console.log('onShow');
},
// 应用隐藏 触发事件
onHide() {
//暂停或者清除定时器
console.log('onHide');
},
// 应用的代码发生报错的时候 就触发
onError (err) {
// 在应用发生代码报错的时候,收集用户的错误信息。通过异步请求 将错误信息发送到后台去
console.log('onError');
},
// 页面找不到j就会触发
// 应用第一次启动的时候,如果找不到第一个入口页面 才会触发 类似404页面 找不到页面 就跳到其他页
onPageNotFound() {
console.log('onPageNotFound');
wx.navigateTo({
url: 'pages/demo1/demo1',
})
}
})
页面生命周期
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
//发送一些异步请求来初始化页面数据
console.log('onLoad');
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
console.log('onShow');
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
console.log('onReady');
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
console.log('onHide');
},
/**
* 生命周期函数--监听页面卸载 就是跳转链接 左上角没有返回箭头
*/
onUnload: function () {
console.log('onUnload');
},
/**
* 页面相关事件处理函数--监听用户下拉动作
* 要在app.json中配置
* "enablePullDownRefresh": true,
"backgroundColor": "#ccc",
更新一些数据接口
*/
onPullDownRefresh: function () {
console.log('onPullDownRefresh')
},
/**
* 页面上拉触底事件的处理函数
* 页面上拉底部触发事件
* 需要让页面 上线上下滚动才行
*/
onReachBottom: function () {
console.log('onReachBottom');
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
console.log('onShareAppMessage');
},
/**
* 只有页面一滚动就会触发
* */
onPageScroll() {
console.log('onPageScroll');
},
/**
* 当前是tab页面时候,点击tab触发
* */
onTabitemTap() {
}
request 网络请求
image.png
GET
wx.request({
url: 'con.theme_user',
method: 'GET',
data: {
act: 'getUserInfo',
wxappid: confirm.wyy_user_wxappid,
openid: resizeBy.data.openid
},
header: {
"Content-Type": "application/json"
},
success: (res) => {
console.log(res.data);
// 存放用户基本信息
this.setData({
userInfo: res.data.userInfo,
hasUserInfo: true,
canIUse: true
})
}
})
wx.request({
header: {
"content-type": "application/json"
},
method: "POST",
url: `${this.globalData.api}login/token`,
data: {
code: code
},
success: res => {
var token = res.data.data
console.log(token);
wx.setStorageSync('token', token);
// 设置完token之后获取首页数据
// resolve()
}
})