邂逅微信小程序
微信小程序简介
- 微信⼩程序,简称⼩程序,英⽂名
Mini Program
,是⼀种不需要下载安装即可使⽤的应⽤,它实现了应⽤“触⼿可及”的梦想,⽤⼾扫⼀扫或搜⼀下即可打开应⽤ - 微信小程序特点:
- 微信有海量⽤⼾,⽽且粘性很⾼,在微信⾥开发产品更容易触达⽤⼾;
- 推⼴
app
或公众号的成本太⾼。 - 开发适配成本低。
- 容易⼩规模试错,然后快速迭代。
- 跨平台
微信小程序的历史
- 2016年1⽉11⽇,微信之⽗张⼩⻰时隔多年的公开亮相,解读了微信的四⼤价值观。张⼩⻰指出,越来越多产品通过公众号来做,因为这⾥开发、获取⽤⼾和传播成本更低。拆分出来的服务号并没有提供更好的服务,所以微信内部正在研究新的形态,叫「微信⼩程序」 需要注意的是,之前是叫做 应⽤号
- 2016年9⽉21⽇,微信⼩程序正式开启内测。在微信⽣态下,触⼿可及、⽤完即⾛的微信⼩程序引起⼴泛关注。腾讯云正式上线微信⼩程序解决⽅案,提供⼩程序在云端服务器的技术⽅案
- 2017年1⽉9⽇,微信推出的“⼩程序”正式上线。“⼩程序”是⼀种⽆需安装,即可使⽤的⼿机“应⽤”。不需要像往常⼀样下载
App
,⽤⼾在微信中“⽤完即⾛”。
疯狂的小程序
- 微信⽉活已经达到 10.82 亿。其中 55 岁以上的⽤⼾也达到 6300 万
- 信息传达数达到 450 亿,较去年增⻓ 18% ;视频通话 4.1 亿次,增⻓100%
- ⼩程序覆盖超过 200 + ⾏业,交易额增⻓超过 6 倍,服务 1000 亿 + ⼈次,创造出了 5000 亿 + 的商业价值
- 除了微信小程序,还有其他小程序也不容忽视:
- ⽀付宝⼩程序
- 百度⼩程序
- QQ ⼩程序
- 今⽇头条 + 抖⾳⼩程序
环境准备
-
开发微信⼩程序之前,必须要准备好相应的环境
-
注册账号:建议使用全新的邮箱,没有注册过其他小程序或者公众号的
-
注册地址:
https://mp.weixin.qq.com/wxopen/waregister?action=step1
-
获取
AppID
-
注册完毕后,登录账号。
-
在开发一栏中点击开发管理,在开发管理中点击开发设置。
-
复制保存开发者
ID
里面的AppID(小程序ID)
里面的id号(后面我们要使用) -
由于后期调⽤微信⼩程序的接⼝等功能,需要索取开发者的⼩程序中的
APPID
,所以在注册成功后, 可登录,然后获取APPID
。 -
登录成功后,可在开发中查看到
AppID
,悄悄保存起来,不要被别人看到
-
-
下载开发工具
-
下载地址:
https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
-
这里下载完成后直接双击,然后傻瓜式安装一直点下一步。
-
-
项目搭建
-
第一次使用微信开发者工具需要使用微信扫描二维码登录
-
登录成功后就可以点击加号进行项目创建了,将我们我
AppID
填入即可
微信小程序初体验
小程序文件结构与传统web对比
-
小程序框架的⽬标是通过尽可能简单、⾼效的⽅式让开发者可以在微信中开发具有原⽣
APP
体验的服务。 -
⼩程序框架提供了⾃⼰的视图层描述语⾔
WXML
和WXSS
,以及JavaScript
,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。结构 传统web 微信小程序 结构 HTML WXML 样式 CSS WXSS 逻辑 Javascript Javascript 配置 无 JSON -
通过以上对⽐得出,传统
web
是三层结构。⽽微信⼩程序是四层结构,多了⼀层 配置.json
基本项目目录
小程序配置文件
-
⼀个⼩程序应⽤程序会包括最基本的两种配置⽂件。⼀种是全局的
app.json
和⻚⾯⾃⼰的page.json
-
注意:配置文件中不能出现注释
-
app.json
是当前⼩程序的全局配置,包括了⼩程序的所有⻚⾯路径、界⾯表现、⽹络超时时间、底部tab
等。普通快速启动项⽬⾥边的app.json
配置-
字段的含义
-
pages 字段⸺⽤于描述当前⼩程序所有⻚⾯路径,这是为了让微信客⼾端知道当前你的⼩程序⻚⾯定义在哪个⽬录。
-
window
(窗口) 字段⸺定义⼩程序所有⻚⾯的顶部背景颜⾊,⽂字颜⾊定义等。backgroundTextStyle
当你对着网页进行下拉刷新的时候的样式,值只能是dark
或者light
navigationBarBackgroundColor
导航栏的背景颜色navigationBarTitleText
导航栏的文字navigationBarTextStyle
导航栏的标题颜色
-
style
微信小程序基础组件样式升级(v2
版本) -
sitemapLocation
-
完整的配置信息请参考
app.json
配置
-
-
-
⻚⾯⾃⼰的
page.json
-
比如当你给页面
index
文件里面的index.json
添加navigationBarBackgroundColor
这样就只会对这个页面生效,不是全局的了。
-
模板语法
-
WXML
(WeiXin Markup Language
)是框架设计的⼀套标签语⾔,结合基础组件、事件系统,可以构建出⻚⾯的结构。 -
基本语法
-
在
pages
页面文件里面的home
文件为例-
在
index.js
/** * 页面的初始数据 */ data: { msg:'hello world', },
-
在
index.wxml
渲染<!-- 在小程序中 标签(组件) --> <text>{{msg}}</text>
-
页面效果展示
-
-
-
组件属性
-
在
pages
页面文件里面的home
文件为例-
在
index.js
/** * 页面的初始数据 */ data: { msg:'hello world', id:'title', class:'item' },
-
在
index.wxml
渲染<!-- 组件是属性 --> <!-- view 类似于 div --> <view id="{{id}}">{{msg}}</view> <view class="{{class}}">{{msg}}</view>
-
在
index.wxss
添加样式#title{ color: red; } .item { color: aquamarine; }
-
页面效果展示
-
-
-
boolean类型
-
不要直接写
checked="false"
,会被计算为一个字符串 -
在
pages
页面文件里面的home
文件为例-
在
index.wxml
<!-- boolean --> <!-- 复选框 checkbox false默认不选中 true默认选中 --> <!-- 这里不要直接写 checked="false",会被计算为一个字符串 --> <checkbox checked="{{false}}">吃饭</checkbox>
-
页面效果展示
-
-
-
运算
-
三元运算
-
在
pages
页面文件里面的home
文件为例 -
在
index.js
/** * 页面的初始数据 */ data: { flag: false },
-
在
index.wxml
<!-- 三元表达式 --> <view>{{flag?'显示':'隐藏'}}</view>
-
页面效果展示
-
-
算术运算
-
在
pages
页面文件里面的home
文件为例 -
在
index.wxml
<!-- 算术运行 --> <view>{{10+20+30}}</view>
-
页面效果展示
-
-
-
逻辑判断
-
在
pages
页面文件里面的home
文件为例 -
在
index.js
/** * 页面的初始数据 */ data: { a:10 },
-
在
index.wxml
<!-- 逻辑判断 --> <view vx:if="{{a>=10}}">a>=10</view>
-
页面效果展示
-
-
字符串运行
-
在
pages
页面文件里面的home
文件为例 -
在
index.js
/** * 页面的初始数据 */ data: { msg: "hello world" },
-
在
index.wxml
<!-- 字符串运算拼接 --> <view>{{msg+'张三'}}</view>
-
页面效果展示
-
注意:花括号和引号之间如果有空格,将最终被解析成为字符串
-
列表渲染
-
wx:for
-
项的变量名默认为
item wx:for--item
可以指定数组当前元素的变量名 -
下标变量名默认为
index wx:for--index
可以指定数组当前下标的变量名 -
wx:key
⽤来提⾼数组渲染的性能wx:key
绑定的值-
在
pages
页面文件里面的home
文件为例 -
在
index.wxml
<!-- wx:for 去遍历 --> <!-- item 是默认的项 --> <!-- index 是默认的索引(下标) --> <!-- wx:key="index" 为每一个元素 添加键值 提高更新的效率 --> <view wx:for="{{books}}" wx:key="index">{{index+1}}-{{item}}</view> <text>\n</text> <label for="book1">输入框1(失焦触发)</label> <input type="text" class="book" id="book1" bindblur="addBook" /> <text>\n</text> <label for="book2">输入框2(点击按钮触发)</label> <input type="text" class="book" id="book2" model:value="{{boo}}" /> <button bindtap="savaBook">添加</button>
-
在
index.wxss
.book{ border: 1px solid; }
-
在
index.js
Page({ /** * 页面的初始数据 */ data: { books: ['Vuejs', 'Angular', 'Reeact', '微信小程序'], boo: '' }, /** * 失焦触发 */ addBook(e) { // 通过事件对象获取输入的内容 // console.log(e); // detail: {value: "", cursor: 1} // console.log(e.detail.value ); // 获取到输入的内容 let book = e.detail.value // 判断 book,当输入的 book 为空不添加内容 if (book == '') return // 获取data中的books // 对象的解构 const {books} = this.data // 添加输入的book books.push(book) // 更新视图 this.setData({books}) e.detail.value = '' }, /** * 点击按钮触发 */ savaBook() { // 解构 let {books,boo} = this.data // 当输入框为空 不做任何操作 if (boo == '') return // 数组的添加 添加输入的内容 boo books.push(boo) // 情况输入框内容 让 boo 为空 boo = '' // 更新视图 this.setData({books,boo}) } })
-
页面效果展示
-
列表渲染
-
block
-
渲染一个包含多节点的结构块
block
最终不会变成真正的dom
元素-
在
pages
页面文件里面的home
文件为例 -
在
index.wxml
<view wx:for="{{books}}"> <view>{{item}}</view> <view>{{index}}</view> </view> <text>\n</text> <block wx:for="{{books}}"> <view>{{item}}</view> <view>{{index}}</view> </block>
-
在
index.js
Page({ data: { books: ['Vuejs', 'Angular', 'Reeact', '微信小程序'], } })
-
调试器
Wxml
元素渲染结构显示 -
页面效果展示
-
条件渲染
-
wx:if
-
在框架中,使⽤
wx:if="{{isShow}}"
来判断是否需要渲染该代码块: -
在
pages
页面文件里面的home
文件为例 -
在
index.wxml
<!-- 条件渲染语句 --> <view wx:if="{{isShow}}">Hello World</view> <view wx:if="{{show}}" class="show">Hello World</view> <view wx:if="{{score>=90}}">优秀</view> <view wx:elif="{{score>=80}}">及格</view> <view wx:else>不及格</view>
-
在
index.wxss
.show { color: red; }
-
在
index.js
Page({ /** * 页面的初始数据 */ data: { isShow:false, show:true, score:88 }, })
-
页面效果展示
-
-
hidden
-
类似
wx:if
频繁切换⽤hidden
,不频繁切换使用wx:if
-
在
pages
页面文件里面的home
文件为例 -
在
index.wxml
<view wx:if="{{score>=90}}">优秀</view> <view wx:elif="{{score>=80}}">及格</view> <view wx:else>不及格</view> <view hidden="{{false}}">false显示</view> <view hidden="{{true}}">true隐藏</view> <!-- 如何选择到底使用 wx:if 还是 hidden --> <!-- 当频繁切换 使用 hidden 设置样式--> <!-- 当不频繁切换的时候 使用 wx:if 创建和销毁组件 -->
-
在
index.js
Page({ /** * 页面的初始数据 */ data: { score:88 }, })
-
调试器
Wxml
元素渲染结构显示- 这里的
wx:if
是隐藏和显示是组件的销毁和创建的过程 - 而
hidden
是通过设置display:none
和display:block
实现组件的隐藏和显示
- 这里的
-
页面效果展示
-
小程序的事件绑定
-
⼩程序中绑定事件,通过
bind
关键字来实现。如bindtap``bindinput``bindchange
等不同的组件⽀持不同的事件,具体看组件的说明即可。-
在
pages
页面文件里面的home
文件为例 -
在
index.wxml
<!-- 事件绑定 --> <!-- 点击事件 --> <button bindtap="handlelClick" data-index="10" data-msg="消息">点击事件</button> <text>\n</text> <!--input事件 bindinput方法可以监听到当前输入框的值 --> <input type="text" bindinput="handleInput" /> <text>\n</text> input事件 聚焦事件 <input type="text" bindfocus="handleFocus" /> <text>\n</text> input事件 失焦事件 <input type="text" bindblur="handleBlur" /> <text>\n</text> change 事件 <radio-group bindchange="handleChange"> <radio value="吃饭">吃饭</radio> <radio value="睡觉">睡觉</radio> <radio value="写代码">写代码</radio> </radio-group>
-
在
index.wxss
input[type='text'] { border: 1px solid; }
-
在
index.js
Page({ /** * 页面的初始数据 */ data: { }, /** * 点击事件 */ handlelClick(e) { console.log('点击了'); // 事件对象 // console.log(e); // 获取参数 data-xxx = 'xxx' 参数 // const {index,msg} = e.currentTarget.dataset const {index,msg} = e.target.dataset console.log('参数列表:',index,msg); // 参数列表: 10 消息 }, /** * 处理 input 事件 */ handleInput(e) { // 输入框输入值触发 console.log('input事件'); // console.log(e); // 获取input事件的参数 const {value} = e.detail console.log(value); }, handleFocus(e) { console.log('聚焦事件'); // console.log(e); // 获取focus事件的参数 const {value} = e.detail console.log(value); }, handleBlur(e) { console.log('失焦事件'); // 获取blur事件的参数 const {value} = e.detail console.log(value); }, handleChange(e) { // console.log(e); const {value} = e.detail // 这里获取到的值 radio组件里面value属性的值 并不是radio组件之间的值 console.log(value); } })
-
页面效果展示
-
-
特别注意:
- 绑定事件时不能带参数 不能带括号
- 事件传值 通过标签⾃定义属性的⽅式和
value
,自定义属性比如上面所示的data-index="10"
或者data-msg="消息"
- 事件触发时获取数据
小程序的样式(rpx)
-
WXSS
(WeiXin Style Sheets
)是⼀套样式语⾔,⽤于描述WXML
的组件样式。 -
与
CSS
相⽐,WXSS
扩展的特性有:- 响应式⻓度单位
rpx
- 样式导⼊
- 响应式⻓度单位
-
rpx
(responsive pixel
): 可以根据屏幕宽度进⾏⾃适应。规定屏幕宽为750rpx
。如在iPhone6
上,屏幕宽度为375px
,共有750
个物理像素,则750rpx = 375px = 750
物理像 素 ,1rpx = 0.5px = 1
物理像素 。设备 rpx 换算 px(屏幕宽度/750) px 换算 rpx(750/屏幕宽度) iPhone5 1rpx = 0.24px 1px = 2.34rpx iPhone6 1rpx = 0.5px 1px = 2rpx iPhone6 Plus 1rpx = 0.552px 1px = 1.81rpx -
建议: 开发微信⼩程序时设计师可以⽤
iPhone6
作为视觉稿的标准。 -
使⽤步骤:
- 确定设计稿宽度
pageWidth
- 计算⽐例
750rpx = pageWidth px
,因此1px=750rpx/pageWidth
。 - 在
less
⽂件中,只要把设计稿中的px => 750/pageWidth rpx
即可
- 确定设计稿宽度
小程序的样式(导入样式)
-
wxss
中直接就⽀持,样式导⼊功能。 -
也可以和
less
中的导⼊混⽤。 -
使⽤
@import
语句可以导⼊外联样式表,只⽀持相对路径。-
目录结构视图
-
在
index.wxml
<view class="navbar"> <view class="left"></view> <view class="center title">首页</view> <view class="right"></view> </view>
-
在
index.wxss
/* 使⽤ @import 语句可以导⼊外联样式表,只⽀持相对路径 */ @import './title.wxss'; /* 直接导入 */ .navbar { display: flex; height: 88rpx; } .left,.right { width: 120rpx; background: red; } .center { flex: 1; background: blue; }
-
在
title.wxss
.title { text-align: center; line-height: 88rpx; color: white; }
-
页面效果展示
-
小程序的样式(选择器 )
-
特别需要注意的是⼩程序 不⽀持通配符
*
因此以下代码⽆效! -
⽬前⽀持的选择器有
选择器 样式 样例描述 .class .intro 选择所有拥有 class=“intro” 的组件 #id #firstname 选择拥有 id=“firstname” 的组件 element(组件选择器) view 选择所有 view 组件 element,element(兄弟选择器) view,checkbox 选择所有文档的 view 组件和所有的 checkbox 组件 nth-child(n) view:nth-child(n) 选择某个索引的标签 ::after view::after 在 view 组件后边插入内容 ::before view::before 在 view 组件前边插入内容
案例
-
视图展示
-
代码展示
-
在
index.wxml
<view> <view class="tabs"> <view class="tabs-item {{currentIndex==0?'active':''}}" bindtap="tabClick" data-index="0"> <text>新款</text> </view> <view class="tabs-item {{currentIndex==1?'active':''}}" bindtap="tabClick" data-index="1"> <text>流行</text> </view> <view class="tabs-item {{currentIndex==2?'active':''}}" bindtap="tabClick" data-index="2"> <text>精选</text> </view> </view> <view class="tab-panel"> <view wx:if="{{currentIndex == 0}}" class="tab-panel-item">新款内容</view> <view wx:elif="{{currentIndex == 1}}" class="tab-panel-item">流行内容</view> <view wx:else class="tab-panel-item">精选内容</view> </view> </view>
-
在
index.wxss
.tabs { display: flex; text-align: center; align-items: center; height: 60rpx; } .tabs-item { flex: 1; } .active { color: red; } .active text { padding: 0 10rpx; border-bottom: 5rpx solid red; } .tab-panel-item { text-align: center; padding-top: 200rpx; }
-
在
index.js
Page({ /** * 页面的初始数据 */ data: { currentIndex:0 }, tabClick(e) { // console.log(e); const {index} = e.currentTarget.dataset this.setData({ currentIndex:index }) } })