微信小程序学习笔记
一、微信小程序简介
微信⼩程序,简称⼩程序,英⽂名 Mini Program ,是⼀种不需要下载安装即可使⽤的应⽤,它实现
了应⽤“触⼿可及”的梦想,⽤⼾扫⼀扫或搜⼀下即可打开应⽤
1.1 为什么是微信⼩程序 ?
- 微信有海量⽤⼾,⽽且粘性很⾼,在微信⾥开发产品更容易触达⽤⼾;
- 推⼴app 或公众号的成本太⾼。
- 开发适配成本低。
- 容易⼩规模试错,然后快速迭代。
- 跨平台。
1.2 微信⼩程序历史
2016年1⽉11⽇,微信之⽗张⼩⻰时隔多年的公开亮相,解读了微信的四⼤价值观。张⼩⻰指出,
越来越多产品通过公众号来做,因为这⾥开发、获取⽤⼾和传播成本更低。拆分出来的服务号并没
有提供更好的服务,所以微信内部正在研究新的形态,叫「微信⼩程序」 需要注意的是,之前是叫
做 应⽤号
2016年9⽉21⽇,微信⼩程序正式开启内测。在微信⽣态下,触⼿可及、⽤完即⾛的微信⼩程序引
起⼴泛关注。腾讯云正式上线微信⼩程序解决⽅案,提供⼩程序在云端服务器的技术⽅案。
2017年1⽉9⽇,微信推出的“⼩程序”正式上线。“⼩程序”是⼀种⽆需安装,即可使⽤的⼿
机“应⽤”。不需要像往常⼀样下载App,⽤⼾在微信中“⽤完即⾛”。
1.3 疯狂的微信⼩程序
- 微信⽉活已经达到10.82亿。其中55岁以上的⽤⼾也达到6300万
- 信息传达数达到450亿,较去年增⻓18%;视频通话4.1亿次,增⻓100%
- ⼩程序覆盖超过200+⾏业,交易额增⻓超过6倍,服务1000亿+⼈次,创造出了5000亿+的商业价值
传智播客-黑马程序员
1.4 还有其他的⼩程序 不容忽视
- ⽀付宝⼩程序
- 百度⼩程序
- QQ⼩程序
- 今⽇头条 + 抖⾳⼩程序
1.5 微信开发者⼯具介绍
1.6 ⼩程序结构⽬录
⼩程序框架的⽬标是通过尽可能简单、⾼效的⽅式让开发者可以在微信中开发具有原⽣APP体验的服务。
⼩程序框架提供了⾃⼰的视图层描述语⾔ WXML 和 WXSS ,以及 JavaScript ,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。
1.6.1 ⼩程序⽂件结构和传统web对⽐
通过以上对⽐得出,传统web 是三层结构。⽽微信⼩程序 是四层结构,多了⼀层 配置.json
1.6.2 基本的项⽬⽬录
注意:配置文件中不能出现注释
1.7 全局配置app.json
app.json 是当前⼩程序的全局配置,包括了⼩程序的所有⻚⾯路径、界⾯表现、⽹络超时时间、底部 tab 等。普通快速启动项⽬⾥边的 app.json 配置
{
"pages":[
"pages/index/index",
"pages/img/img",
"pages/mine/mine",
"pages/search/search",
"pages/logs/logs",
"pages/demo01/demo01"
],
"window":{
"backgroundTextStyle":"dark",
"navigationBarBackgroundColor": "#66ccff",
"navigationBarTitleText": "我的应用",
"navigationBarTextStyle":"white",
"enablePullDownRefresh":true,
"backgroundColor":"#66ffcc"
},
"tabBar": {
"list": [
{"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "icon/_home.png",
"selectedIconPath": "icon/home.png"
},
{"pagePath": "pages/img/img",
"text": "图片",
"iconPath": "icon/_img.png",
"selectedIconPath": "icon/img.png"
},
{"pagePath": "pages/search/search",
"text": "搜索",
"iconPath": "icon/_search.png",
"selectedIconPath": "icon/search.png"
},
{"pagePath": "pages/mine/mine",
"text": "我的",
"iconPath": "icon/_my.png",
"selectedIconPath": "icon/my.png"
}
],
"color":"#66ccff",
"selectedColor": "#ffcc66",
"backgroundColor": "#666666"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}
-
pages 字段⸺⽤于描述当前⼩程序所有⻚⾯路径,这是为了让微信客⼾端知道当前你的⼩程序
⻚⾯定义在哪个⽬录。 -
window 字段⸺定义⼩程序所有⻚⾯的顶部背景颜⾊,⽂字颜⾊定义等。
-
tabBar 字段 ——底部 tab 栏的表现
-
完整的配置信息请参考[官网app.json配置]: https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html
1.8 ⻚⾯配置page.js
这⾥的 page.json 其实⽤来表⽰⻚⾯⽬录下的 page.json 这类和⼩程序⻚⾯相关的配置。
开发者可以独⽴定义每个⻚⾯的⼀些属性,如顶部颜⾊、是否允许下拉刷新等等。
⻚⾯的配置只能设置 app.json 中部分 window 配置项的内容,⻚⾯中配置项会覆盖 app.json的 window 中相同的配置项。
1.9 sitemap 配置
⼩程序根⽬录下的 sitemap.json ⽂件⽤于配置⼩程序及其⻚⾯是否允许被微信索引。
二、模板语法
WXML(WeiXin Markup Language)是框架设计的⼀套标签语⾔,结合基础组件、事件系统,可以构建出⻚⾯的结构。
2.1 数据绑定
WXML
<!-- 1.text 相当于以前web中的 span标签 行内元素 不会换行-->
<!-- 2.view 相当于以前web中的 div标签 块级元素 不会换行 -->
<!-- 3.view 相当于以前web中的复选框标签 -->
<!-- <text>1</text>
<text>1</text>
<view>1</view>
<view>1</view> -->
<!-- 1.字符串 -->
<view>
{{msg}}
</view>
<!-- 2.数字标签 -->
<view>
{{num}}
</view>
<!-- 3.bool类型 -->
<view>
是否为伪娘:{{isGirl}}
</view>
<!-- 4.object类型 -->
<view>{{person.age}}</view>
<view>{{person.height}}</view>
<view>{{person.weigh}}</view>
<view>{{person.name}}</view>
<!-- 5.在标签的属性中使用 -->
<view data-num="{{num}}">
自定义属性
</view>
<!-- 6.bool类型充当属性
1 字符串和花括号之间一定不要存在空格否则会导致识别失败
以下写法就是错误的示范
<checkbox checked=" {{isChecked}}"></checkbox>
-->
<view>
<checkbox checked="{{isChecked}}">
</checkbox>
</view>
demo.js
// pages/demo02/demo02.js
Page({
/**
* 页面的初始数据
*/
data: {
msg:"hello mine",
num:100000,
isGirl:false,
person:{
age:40,
height: 145,
weigh:200,
name:"富婆"
},
isChecked:false
}
})
2.2 列表渲染
运算=>表达式
- 可以在花括号中加入表达式 -- “语句”
- 表达式
指的是一些简单运算数字运算字符串拼接逻辑运算。。。
1. 数字的加减
2. 符串拼接
3. 三元表达式 - 语句
复杂的代码段- if else
- switch
- do while
- for
<!-- 7 运算=>表达式
1可以在花括号中加入表达式 -- “语句”
2表达式
指的是一些简单运算数字运算字符串拼接逻辑运算。 。
1数字的加减。
2字符串拼接
3三元表达式
3语句
1复杂的代码段
1 if else
2 switch
3 do while 。
4 for
-->
<view>
{{1+1}}
</view>
<view>
{{"1"+"1"}}
</view>
<view>
{{ 11%2===0 ? "偶数":"奇数" }}
</view>
2.3 循环
列表循环
-
wx:for="{{数组或者对象}}" wx:for-item="item" wx:for-index="index"
-
wx:key="唯一的值"用来提高列表渲染的性能 key必须唯一且稳定,提高性能的
- wx:key 绑定一个普通的字符串的时候那么这个字符串名称肯定是循环数组中的对象的唯一属性
- wx:key ="this"就表示你的数组是一个普通的数组this 表示是循环项
-
当出现数组的嵌套循环的时候尤其要注意 以下绑定的名称不要重名
wx:for-item="item" wx:for-index="index"
- 默认情况下我们不写
wx:for-item="item" wx:for-index="index"
小程序也会把循环项的名称和索引的名称item和index
只有一层循环的话(wx:for-item="item" wx:for-index="index") 可以省略
对象循环
- wx:for="{{对象}}" wx:for- item="对象的值” WX : for- index= "对象的属性"
- 循环对象的时候最好把item和index的名称都修改一下
wx:for-index="value" wx:for-item="key"
<view>
<view wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="id">
索引:{{index}}
--
值:{{item.name}}
</view>
</view>
<view>
<view wx:for="{{person}}" wx:for-index="value" wx:for-item="key" wx:key="age">
属性:{{key}}
--
值:{{value}}
</view>
</view>
2.4 Block标签
block 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
- 占位符的标签
- 写代码的时候可以看到这标签存在
- 页面渲染小程序会把它移除掉
<!--
10 block 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
1占位符的标签
2写代码的时候可以看到这标签存在
3页面渲染小程序会把它移除掉
-->
<view>
<block wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="id">
索引:{{index}}
--
值:{{item.name}}
</block>
</view>
2.5 条件渲染
-
wx:if={{ture/false}}
wx:if
wx:elif
wx:else
-
hidden
- 在标签上直接加入属性hidden
- hidden=" {{true}}"
-
什么场景下用哪个
- 当标签不是频繁的切换显示优先使用wx:if 直接把标签从页面结构给移除掉
- 当标签频繁的切换显示的时候优先使用hidden 通过添加样式的方式来切换显示 hidden属性不要和样式display一起使用
<!-- 11 条件渲染
1 wx:if={{ture/false}}
1 if,else,if else
wx:if
wx:elif
wx:else
2 hidden
1 在标签上直接加入属性hidden
2 hidden=" {{true}}"
3 什么场景下用哪个
1 当标签不是频繁的切换显示优先使用wx:if
直接把标签从页面结构给移除掉
2 当标签频繁的切换显示的时候优先使用hidden
通过添加样式的方式来切换显示
hidden属性不要和样式display 一起使用
-->
<view>
<view>条件渲染</view>
<view wx:if="{{true}}">显示</view>
<view wx:if="{{false}}">隐藏</view>
<view wx:if="{{false}}">1</view>
<view wx:elif="{{false}}">2</view>
<view wx:elif="{{true}}">3</view>
<view>----------------</view>
<view hidden="false">hidden</view>
</view>
2.6 事件绑定
-
需要给input标签绑定input事件
绑定关键字bindinput
-
如何获取输入框的值
通过事件源对象来获取
e.detail.value
-
不能直接把输入框的值赋值到data当中
1 this.data. num=e.detail.value
2 this . num=e.detail.value
-
正确的写法
this.setData({
num:e.detail.value
})
-
加入点击事件
- bindtap
- 无法在小程序当中的 事件中 直接传参
- 通过自定义属性的方式来传递参数
- 事件源中获取 自定义参数
Page({
data: {
num:0
},
// 输入框input事件的执行逻辑
handleInput(e){
// console.log(e.detail.value);
this.setData({
num:e.detail.value
})
},
// 加减 按钮事件
handleTap(e){
// console.log(e);
// 1.获取自定义属性 operation
const operation = e.currentTarget.dataset.operation;
this.setData({
num:this.data.num + operation
})
}
})
<!--
1 需要给input标签绑定input事件
绑定关键字bindinput
2 如何获取输入框的值
通过事件源对象来获取
e.detail.value
3 不能直接把输入框的值赋值到data当中
1 this.data. num=e.detail.value
2 this . num=e.detail.value
正确的写法
this.setData({
num:e.detail.value
4 加入点击事件
1 bindtap
2 无法在小程序当中的 事件中 直接传参
3 通过自定义属性的方式来传递参数
4 事件源中获取 自定义参数
})
-->
<input type="text" bindinput="handleInput">
<button bindtap="handleTap" data-operation="{{1}}">+</button>
<button bindtap="handleTap" data-operation="{{-1}}">-</button>
<view->
{{num}}
</view->
2.7 常见组件
view 标签
代替 原来的 div 标签
text ⽂本标签
- ⽂本标签
- 只能嵌套text
- ⻓按⽂字可以复制(只有该标签有这个功能)
- 可以对空格 回⻋ 进⾏编码
<!-- 1. 长按文字复制 selectable="{{true}}" 2. 对文本内容进行解码 decode="{{true}}"--><text selectable="{{true}}" decode="{{true}}"> page 123 < </text>
Image 图片标签
-
src
指定要加载的图片的路径
图片存在默认的宽度和高度320 * 240
-
mode决定图片内容如何和图片标签宽高做适配
1 scaleTqFi1l 默认值不保持纵横比缩放图片,使图片的宽高完全拉伸至填满image 元素
2 aspectFit 保持宽高比确保图片的长边显示出来页面轮播图 常用
3 aspectFill 保持纵横比缩放图片,只保证图片的短边能完全显示出来 少用
4 widthFix 以前web的图片的宽度指定了之后高度会自己按比例来调整 常用
5 bottom。 。类似以前的backgroud-position
-
小程序中的图片直接支持懒加载 lazy-load
lazy-load会自己判断当图片出现在视口上 下三屏的高度之内的时候自 己开始加载图片
<!-- image 图片标签 1. src 指定要加载的图片的路径 图片存在默认的宽度和高度320 * 240 2. mode决定图片内容如何和图片标签宽高做适配 1 scaleTqFi1l 默认值不保持纵横比缩放图片,使图片的宽高完全拉伸至填满image 元素 2 aspectFit 保持宽高比确保图片的长边显示出来页面轮播图 常用 3 aspectFill 保持纵横比缩放图片,只保证图片的短边能完全显示出来 少用 4 widthFix 以前web的图片的宽度指定了之后高度会自己按比例来调整 常用 5 bottom。 。类似以前的backgroud-position 3. 小程序中的图片直接支持懒加载 lazy-load lazy-load会自己判断当图片出现在视口上 下三屏的高度之内的时候自 己开始加载图片--><img mode="aspectFit" lazy-load="{{true}}" src="http://blogimg-dust.oss-cn-beijing.aliyuncs.com/img/222.jpg">
Swiper 轮播图
-
轮播图外层容器swiper
-
每一个轮播项swiper- item
-
swiper标签 存在默认样式
1 width 100%
2 height 150pximage存在默认宽度和高度320 * 240
3 swiper高度无法实现由内容撑开 -
先找出来原图的宽度和高度等比例给swiper 定宽度和高度
原图的宽度和高度
swiper宽度/ swiper高度 = 原图的宽度/原图的高度
swiper高度 = swiper宽度*原图的高度/原图的宽度 -
autoplay 自动轮播
-
interval 修改轮播时间
-
circular 衔接轮播
-
indicator-dots 显示指示器分页器 索引器
-
indicator-color指示器的未选择的颜色
-
indicator-active-color 选中的时候的指示器的颜色
<!-- 1. 轮播图外层容器swiper 2. 每一个轮播项swiper- item 3. swiper标签 存在默认样式 1 width 100% 2 height 150pximage存在默认宽度和高度320 * 240 3 swiper高度无法实现由内容撑开 4. 先找出来原图的宽度和高度等比例给swiper 定宽度和高度 原图的宽度和高度 swiper宽度/ swiper高度 = 原图的宽度/原图的高度 swiper高度 = swiper宽度*原图的高度/原图的宽度 5. autoplay 自动轮播 6. interval 修改轮播时间 7. circular 衔接轮播 8. indicator-dots 显示指示器分页器 索引器 9. indicator-color指示器的未选择的颜色 10. indicator-active-color 选中的时候的指示器的颜色--><swiper autoplay="{{true}}" interval="1000" circular="{{true}}" indicator-dots="{{true}}" indicator-active-color="#00ff94" indicator-color="#94ff00"> <swiper-item class="" item-id=""> <img mode="widthFix" src="https://img.alicdn.com/imgextra/i3/6000000003731/O1CN016VwHel1dQqPXjgJIt_!!6000000003731-0-octopus.jpg"> </swiper-item> <swiper-item class="" item-id=""> <img mode="widthFix" src="https://img.alicdn.com/imgextra/i1/6000000003348/O1CN01sdQRAo1abQiWtZpKz_!!6000000003348-0-octopus.jpg"> </swiper-item> <swiper-item class="" item-id=""> <img mode="widthFix" src="https://gtms01.alicdn.com/tps/i1/TB1r4h8JXXXXXXoXXXXvKyzTVXX-520-280.jpg"> </swiper-item></swiper>
navigator 导航标签
-
块级元素默认会换行可以直接加宽度和高度
-
url要跳转的页面路径绝对路径 相对路径
self默认值自己小程序的页面
miniProgram其他的小程序的页面 -
open-type 跳转的方式
1 navigate 默认值 保留当前页面,跳转到应用内的某个页面,但是不能跳到tabbar页面
2 redirect 关闭当前页面,跳转到应用内的某个页面,但是不允许跳转到tabbar页面。
3 switchTab 跳转到tabBar 页面,并关闭其他所有非tabBar页面
4 reLaunch关闭所有页面, 打开到应用内的某个页面
<!-- 导航标签 navigator 0. 块级元素默认会换行可以直接加宽度和高度 1. url要跳转的页面路径绝对路径 相对路径 self默认值自己小程序的页面 miniProgram其他的小程序的页面 3. open-type 跳转的方式 1 navigate 默认值 保留当前页面,跳转到应用内的某个页面,但是不能跳到tabbar页面 2 redirect 关闭当前页面,跳转到应用内的某个页面,但是不允许跳转到tabbar页面。 3 switchTab 跳转到tabBar 页面,并关闭其他所有非tabBar页面 4 reLaunch关闭所有页面, 打开到应用内的某个页面--><navigator url="/pages/demo07/demo07">轮播图页面</navigator><navigator url="/pages/index/index">直接跳到tabbar页面</navigator><navigator open-type="redirect" url="/pages/demo07/demo07">轮播图页面 redirect</navigator><navigator open-type="switchTab" url="/pages/index/index">直接跳到tabbar页面 switchTab</navigator><navigator open-type="reLaunch" url="/pages/index/index">直接跳到tabbar页面 reLaunch</navigator>
rich-text 富文本标签
rich-text 富文本标签
nodes属性来实现
1 接收标签字符串
2 接收对象数组
<!-- rich-text 富文本标签 nodes属性来实现 1 接收标签字符串 2 接收对象数组--><rich-text class="" nodes="{{html}}"></rich-text>
Page({ data: { // 1.标签字符串 最常用的 // html:'<div class="sc-bZQynM famEdQ"><a class="sc-gzVnrw bhThaH" href="https://www.tmall.com/wow/z/heybox/heyboxrax/heybox?utparam=%7B%22ranger_buckets_native%22%3A%22tsp2584_31920%22%7D&spm=a2141.1.iconsv5.1&scm=1007.home_icon.tmallxp.d&wh_biz=tm&disableNav=YES"><img class="sc-htoDjs gRQzSI" src="https://gw.alicdn.com/tfs/TB1OIxTcLc3T1VjSZLeXXbZsVXa-183-144.png?getAvatar=1"><p class="sc-dnqmqq blJSr">天猫新品</p></a><a class="sc-gzVnrw krOjeo" href="https://huodong.m.taobao.com/act/snipcode.html?utparam=%7B%22ranger_buckets_native%22%3A%22tsp2584_31920%22%7D&spm=a2141.1.iconsv5.6&scm=1007.home_icon.chongzzx.d&_wml_code=Vfw8V4IdfflvFcsPv2fKDCLgFlhCoOQ406ZO9WKS70zNVh2FhuClrYZQHV%2BUj8rweMrPJgOrvqON3zeUHJMIALqc03AQZnf3hmtKmJM2g5PuR9UuzwivVDM%2Bil4nBDGBPXlfSqZZA3CdATGQpVOeZMO8SbyJvaZdoC89%2B2Gg8FZsD4wqDUKs7VcgTjZxbgdE&subSource=stcz_1"><img class="sc-htoDjs gRQzSI" src="https://gw.alicdn.com/tfs/TB1llI3f4n1gK0jSZKPXXXvUXXa-183-144.png?getAvatar=1"><p class="sc-dnqmqq blJSr">充值中心</p></a></div>' // 2.对象数组 html:[ { // 1 div标签 name属性来命名 name:"div", // 2 标签上有哪一些属性 attrs:{ // 标签上的属性 class style class:"my-div", style:"color:red;" }, // 3 子节点 children要接收的数据类型和nodes第二种渲染方式的数据类型致 children:[ { name:"p", attrs:{}, children:[ { // 放文本 type:"text", text:"hello world" } ] } ] } ] }})
button 按钮标签
-
外观的属性
size控制按钮的大小
1 default 默认大小
2 mini 小尺寸 -
type用来控制按钮的颜色
1 default 灰色2 primary 绿色
3 warn红色
-
plain
按钮是否镂空,背景色透明 -
loading
前面加一个loading图标
<!-- button标签 1. 外观的属性 size控制按钮的大小 1 default 默认大小 2 mini 小尺寸 2. type用来控制按钮的颜色 1 default 灰色 2 primary 绿色 3 warn红色 3. plain 按钮是否镂空,背景色透明 4.loading 前面加一个loading图标--><button>默认按钮</button><button size="mini">mini默认按钮</button><button type="primary">primary默认按钮</button><button type="warn">warn 默认按钮</button><button type="primary" plain="{{true}}">plain默认按钮</button><button type="primary" loading="{{true}}">loading默认按钮</button>
button 开发能力
open-type:
-
contact 直接打开客服对话功能需要在微信小程序的后台配置
-
share 转发当前的小程序到微信朋友中 不能把小程序分享到朋友圈
-
getPhoneNumber 获取当前用户的手机号码信息结合一个事件来使用不是 企业的小程序账号没有权限来获取用户的手机号码
1 绑定一个事件bindgetphonenumber
2 在事件的回调函数中 通过参数来获取信息
3 获取到的信息已经加密过了需要用户自己待见小程序的后台服务器,在后台服务器中进行解析手机号码,返回到小程序中就可以看到信息了 -
getUserInfo 获取当前用户的个人信息
1 使用方法类似获取用户的手机号码
2 可以直接获取不存在加密的字段 -
launchApp 在小程序当中直接打开app
1 需要现在app中通过app的某个链接打开小程序
2 在小程序中再通过这个功能重新打开app
3 找到京东的app和京东的小程序 -
openSetting 打开小程序内置的授权页面
授权页面中只会出现用户曾经点击过的权限
-
feedback 打开小程序内置的意见反馈页面
<!--
button开发能力
open-type:
1. contact直接打开客服对话功能需要在微信小程序的后台配置
2. share转发当前的小程序到微信朋友中 不能把小程序分享到朋友圈
3. getPhoneNumber 获取当前用户的手机号码信息结合一个事件来使用不是 企业的小程序账号没有权限来获取用户的手机号码
1 绑定一个事件bindgetphonenumber
2 在事件的回调函数中 通过参数来获取信息
3 获取到的信息已经加密过了需要用户自己待见小程序的后台服务器,在后台服务器中进行解析手机号码,返回到小程序中就可以看到信息了
4. getUserInfo 获取当前用户的个人信息
1使用方法类似获取用户的手机号码
2可以直接获取不存在加密的字段
5. launchApp 在小程序当中直接打开app
1需要现在app中通过app的某个链接打开小程序
2在小程序中再通过这个功能重新打开app
3找到京东的app和京东的小程序
6. openSetting 打开小程序内置的授权页面
授权页面中只会出现用户曾经点击过的权限
7. feedback打开小程序内置的意见反馈页面
-->
<button open-type="contact">contact</button>
<button open-type="share">share</button>
<button open-type="getPhoneNumber" bindgetphonenumber="getphonenumber">getPhoneNumber</button>
<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">getUserInfo</button>
<button open-type="launchApp">launchApp</button>
<button open-type="openSetting">openSetting</button>
<button open-type="feedback">feedback</button>
Icon 字体图标
1 type 图标的类型
success |success_ no_ circle |info |warn | waiting | cancel | download | search| clear
2 size大小
3 color图标的颜色
<!-- 小程序中的字体图标 1 type 图标的类型 success |success_ no_ circle |info |warn | waiting | cancel | download | search| clear 2 size大小 3 color图标的颜色--><icon class="" type="cancel" size="50" color="#66ccff"></icon>
radio 单选框
-
radio标签必须要和父元素radio- group来使用
-
value选中的单选框的值
<!-- radio单选框 1 radio标签必须要和父元素radio- group来使用 2 value选中的单选框的值 --><radio-group bindchange="handleChange"> <radio color="red" value="male">男</radio> <radio color="red" value="famale">女</radio></radio-group><view>你选中的是{{gender}}</view>
Page({ data: { gender:"" }, handleChange(e){ // console.log(e); // 1. 获取单选框的值 let gender = e.detail.value; // 2. 把值赋给data中的数据 this.setData({ // gender:gender gender }) }})
checkbox 复选框
<view> <checkbox-group bindchange="handleItemChange"> <checkbox value="{{item.value}}" wx:for="{{list}}" wx:key="id">{{item.name}}</checkbox> </checkbox-group> <view>选中的水果:{{checkedList}}</view></view>
Page({ data: { list: [{ id: 0, name: "苹果", value: "apple" }, { id: 1, name: "葡萄", value: "grape" }, { id: 2, name: "香蕉", value: "bananer" }, ] }, // 复选框的选中事件 handleItemChange(e) { // console.log(e); // 1. 获取被复选框的值 const checkedList = e.detail.value; // 2. 进行赋值 this.setData({ checkedList }) }
自定义组件
类似vue或者react中的自定义组件
创建⾃定义组件
声明引⼊⾃定义组件
{ "usingComponents": { "Tabs":"../../components/Tabs/Tabs" }}
使用组件
<tabs></tabs>
父子组件传值
父组件 wxml
<!-- 1父组件(页面)向子组件传递数据通过标签属性的 1在子组件上进行接收 2把这个数据当成是data中的数据直接用即可 2子向父传递数据通过事件的方式传递 1在子组件的标签上加入一个自定义事件--><tabs tabs="{{tabs}}" binditemchange="handleItemChange"></tabs>
父组件 js
Page({ data: { tabs: [{ id: 0, name: "首页", isActive: true }, { id: 1, name: "原创", isActive: false }, { id: 2, name: "分类", isActive: false }, { id: 3, name: "关于", isActive: false }, ] }, handleItemChange(e) { // console.log(e); // 接收传递过来的参数 const {index} = e.detail; let {tabs} = this.data; tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false); this.setData({ tabs }) }})
子组件 wxml
<view class="tabs"> <view class="tabs_title"> <!-- <view class="title_item active" >首页</view> <view class="title_item">原创</view> <view class="title_item">分类</view> <view class="title_item">关于</view> --> <view wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive?'active':''}}" bindtap="handleItemTap" data-index="{{index}}"> {{item.name}} </view> </view> <view class="tabs_content">内容</view></view>
子组件 js
Component({ /** * 里面存放的是要从父组件中接收的数据 */ properties: { // 要接受数据的名称 // aaa:{ // type 要接收数据的类型 // type:String, // value 默认值 // value:"" // } tabs:{ type:Array, value:[] } }, /** * 组件的初始数据 */ data: { }, /* 1页面.js文件中存放事件回调函数的时候存放在data同层级下!!! 2组件.js文件中存放事件回调函数的时候必须要存在在methods中! ! ! */ methods: { handleItemTap(e) { /* 1绑定点击事件 需要在methods中绑定 2获取被点击的索引 3获取原数组 4对数组循环 1给每一个循环性选中属性改为false 2给当前的索引的项添加激活选中效果就可以了! ! ! 5点击事件触发的时候 触发父组件中的自定义事件同时传递数据给父组件 this.triggerEvent("父组件自定义事件的名称",要传递的参数) */ // 2.获取索引 const {index} = e.currentTarget.dataset; // 5.点击事件触发的时候 触发父组件中的自定义事件同时传递数据给父组件 this.triggerEvent("itemChange",{index}) //解构对复杂类型进行结构的时候复制了一份变量的引用而已 // 最严谨的做法重新拷贝一份数组,再对这个数组的备份进行处理, // let tabs = JSON.parse(JSON.stringify(this.data.tabs)) // 不要直接修改this.data.数据 // let {tabs} = this.data; // [].forEach遍历数组遍历数组的时候修改了v,也会导致源数组被修改 // tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false); // this.setData({ // tabs // }) } }})
- 微信小程序父组件往子组件传值通过标签属性的
tabs="{{tabs}}"
- 微信小程序子组件往父组件传值通过触发父组件中的自定义事件
this.triggerEvent("itemChange",{index})
slot 插槽
slot标签其实就是一个占位符插槽
等到父组件调用子组件的时候再传递标签过来最终这些被传递的标签就会替换slot插槽的位置
父组件 wxml
<tabs tabs="{{tabs}}" binditemchange="handleItemChange"><block wx:if="{{tabs[0].isActive}}">0</block><block wx:elif="{{tabs[1].isActive}}">1</block><block wx:elif="{{tabs[2].isActive}}">2</block><block wx:else="">3</block></tabs>
子组件 wxml
<view class="tabs_content"> <!-- slot标签其实就是一个占位符插槽 等到父组件调用子组件的时候再传递标签过来最终这些被传递的标签 就会替换slot插槽的位置 --> <slot></slot> </view>
三、样式
3.1 rpx
-
小程序中不需要主动来引入样式文件
-
需要把页面中某些元素的单位由px改成rpx
1设计稿750x
750 px = 750 rpx
1px=1rpx
2把屏幕宽度改成375px
375 px = 750 rpx
1px=2rpx
1rpx = 0.5px
-
存在一个设计禍宽度414或者禾知page
1设计稿page 存在一个元素 宽度100px
2拿以上的需求去实现不同宽度的页面适配
page px = 750 rpx
1px=750rpx/page
100 px = 750 rpx * 100 / page
假设page = 375px
-
利用一个属性calc属性 css和wxss都支持一个属性
1 750和rpx中间不要留空格
2 运算符的两边也不要留空格
/* 1. 小程序中不需要主动来引入样式文件
2. 需要把页面中某些元素的单位由px改成rpx
1设计稿750x
750 px = 750 rpx
1px=1rpx
2把屏幕宽度改成375px
375 px = 750 rpx
1px=2rpx
1rpx = 0.5px
3. 存在一个设计禍宽度414或者禾知page
1设计稿page 存在一个元素 宽度100px
2拿以上的需求去实现不同宽度的页面适配
page px = 750 rpx
1px=750rpx/page
100 px = 750 rpx * 100 / page
假设page = 375px
4. 利用一个属性calc属性 css和wxss都支持一个属性
1 750和rpx中间不要留空格
2 运算符的两边也不要留空格
*/
view{
/* width: 200rpx; */
height: 200rpx;
background: aqua;
/* px与rpx转换 */
width:calc(750rpx*100/375);
}
3.2 样式导入
-
引入的代码是通过@import来引入
-
路径只能写相对路径
/*
1. 引入的代码是通过@import来引入
2. 路径只能写相对路径
*/
@import"../../style/common.wxss";
3.3 选择器
特别需要注意的是 ⼩程序 不⽀持通配符 * 因此以下代码⽆效!
3.4 Less
原⽣⼩程序不⽀持 less ,其他基于⼩程序的框架⼤体都⽀持,如 wepy , mpvue , taro 等。
但是仅仅因为⼀个less功能,⽽去引⼊⼀个框架,肯定是不可取的。因此可以⽤vscode装easy less插件 来实现
// 1.定义less变量@color:yellow;view{ color: @color;}// 嵌套view{ .vie{ text{ font-size: 10px; } }}// 导入less@import "../../style/reset.less";text{ color: @theme;}
四、小程序生命周期
应⽤⽣命周期
onLaunch | 监听⼩程序初始化。 |
---|---|
onShow function | 监听⼩程序启动或切前台 |
onHide function | 监听⼩程序切后台 |
onError function | 错误监听函数 |
onPageNotFound function | ⻚⾯不存在监听函数 |
// app.jsApp({ // 生命周期 // 1 应用第一次启动就会触发的事件 onLaunch() { // 在应用第一次启动的时候获取用户的个人信息 console.log("onLaunch"); // js的方式来跳转不能触发onPageNotFound // wx.navigateTo({ // url: '11/22/33', // }); }, // 2 应用被用户看到 onShow() { // 对应用的数据或者页面效果重置 console.log("onShow"); }, // 3 应用被隐藏 onHide() { // 对应用的数据或者页面效果重置 console.log("Hide"); }, // 4 应用的代码发生了报错的时候就会触发 onError() { // 在应用发生代码报错的时候,收集用户的错误信息,通过异步请求将错误的信息发送后台去 console.log("error"); }, // 5 页面找不到就会触发 onPageNotFound() { // 如果页面不存在了通过js的方 式来重新跳转页面重新跳到第二个首页 // 不能跳到tabbar页面 导航组件类似 wx.navigateTo({ url: "pages/demo09/demo09" }); console.log("PageNotFound"); }})
⻚⾯⽣命周期
data Object ⻚⾯的初始数据 | |
---|---|
onLoad | ⽣命周期回调—监听⻚⾯加载 |
onShow | ⽣命周期回调—监听⻚⾯显⽰ |
onReady | ⽣命周期回调—监听⻚⾯初次渲染完成 |
onHide | ⽣命周期回调—监听⻚⾯隐藏 |
onUnload | ⽣命周期回调—监听⻚⾯卸载 |
onPullDownRefresh | 监听⽤⼾下拉动作 |
onReachBottom | ⻚⾯上拉触底事件的处理函数 |
onShareAppMessage | ⽤⼾点击右上⻆转发 |
onPageScroll | ⻚⾯滚动触发事件的处理函数 |
onResize | ⻚⾯尺⼨改变时触发,详⻅ 响应显⽰区域变化 |
onTabItemTap | 当前是 tab ⻚时,点击 tab 时触发 |
// pages/demo14/demo14.jsPage({ /** * 页面的初始数据 */ data: { }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { // onLoad发送异步请求来初始化页面数据 console.log("onLoad"); }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { console.log("onReady"); }, /** * 生命周期函数--监听页面显示 */ onShow: function () { console.log("onShow"); }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { console.log("onHide"); }, /** * 生命周期函数--监听页面卸载 也是可以通过点击超链接来演示 */ onUnload: function () { console.log("onUnload"); }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { // 页面的数据或者效果重新刷新 console.log("onPullDownRefresh"); }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { // 上拉加载下一页数据 console.log("onReachBottom"); }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { console.log("onShareAppMessage"); }, /* *页面滚动 就可以触发 */ onPageScroll(){ console.log("onPageScroll"); }, /** * 页面的尺寸发生改变的时候触发 * 小程序发生了横屏竖屏切换的时候触发 */ onResize(){ console.log("onResize"); }, /** * 1必须要求当前页面也是tabbar页面 * 2点击的自己的tab item的时候才触发 */ onTabItemTap(){ console.log("onTabItemTap"); }})
项目
https://www.cnblogs.com/roy-dust/p/15173877.html
文章来源: 博客园
- 还没有人评论,欢迎说说您的想法!