微信小程序入门笔记(一)
day 01
1.微信公众平台
https://mp.weixin.qq.com/
品牌,营销
1.1微信公众平台概念
- 微信公众平台,简称公众号。曾命名为“官号平台”、“媒体平台”、微信公众号,最终定位为“公众平台”,无疑让我们看到一个微信对后续更大的期望。
- 利用公众账号平台进行自媒体活动,简单来说就是进行一对多的媒体性行为活动,如商家通过申请公众微信服务号通过二次开发展示商家微官网、微会员、微推送、微支付、微活动、微报名、微分享、微名片等,已经形成了一种主流的线上线下微信互动营销方式。
1.2微信公众平台的账号分类
1.2.1服务号
- 服务号:为企业和组织提供更强大的业务服务与用户管理能力,主要偏向服务类交互(功能类似12315,114,银行,提供绑定信息,服务交互的);
- 适用人群:媒体、企业、政府或其他组织。
- 群发次数:服务号1个月(按自然月)内可发送4条群发消息。
- 所在的位置:在微信里像一个联系人会话一样存在。
1.2.2 订阅号
- 订阅号:为媒体和个人提供一种新的信息传播方式,主要功能是在微信侧给用户传达资讯;(功能类似报纸杂志,提供新闻信息或娱乐趣事)
- 适用人群:个人、媒体、企业、政府或其他组织。
- 群发次数:订阅号(认证用户、非认证用户)1天内可群发1条消息。
- 所在位置:在微信里像一个文件夹一样,所有的订阅号都在订阅号的文件夹中
1.2.3企业微信(企业号)
- 打卡,考勤,工资,日报,周报-----钉钉
- 为企业与组织提供专业的协作、管理和客户运营工具。企业员工可以用认证的身份添加客户微信,提供服务,实现交易。实现对内工作协同高效,对外连接12亿微信用户。
1.2.4小程序
- 小程序是一种新的开放能力,开发者可以快速地开发一个小程序。小程序可以在微信内被便捷地获取和传播,同时具有出色的使用体验。
2.小程序
2.1小程序的概念
- 微信小程序,小程序的一种,英文名Wechat Mini Program,是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用。
- 全面开放申请后,主体类型为企业、政府、媒体、其他组织或个人的开发者,均可申请注册小程序。微信小程序、微信订阅号、微信服务号、微信企业号是并行的体系。
- 微信小程序是一种不用下载就能使用的应用,也是一项创新,经过将近两年的发展,已经构造了新的微信小程序开发环境和开发者生态。微信小程序也是这么多年来中国IT行业里一个真正能够影响到普通程序员的创新成果,已经有超过150万的开发者加入到了微信小程序的开发,与我们一起共同发力推动微信小程序的发展,微信小程序应用数量超过了一百万,覆盖200多个细分的行业,日活用户达到两个亿,微信小程序还在许多城市实现了支持地铁、公交服务。微信小程序发展带来更多的就业机会,2017年小程序带动就业104万人,社会效应不断提升。
2.2小程序的优缺点(重点)
- 功能,速度,用户体验,开发成本 H5 app
优点
- 功能比H5多,和原生app差不多,
- 速度和H5一样,比原生app慢一些。
- 用户体验较好,即用即走,无需下载
- 开发成本不高
- 基于微信的,用户群体比较大
- 不需要下载(最大的特点)
- 比较简单,容易上手(html+Css+js)
- 开发成本低,节省时间和人力(小程序无论是安卓还是ios都可以用)
缺点
- 微信小程序的代码量最大是2M,使用分包技术可以将代码量提升到20M,(伪app)
- 上线时需要审核。
- 不能分享到朋友圈(现在可以分享到朋友圈)。
- 源码 只有2M(利用分包 将源码变成16M)
- 上线比较麻烦(需要微信团队人工审核,审核日期1-7工作日)
- 入口比较深(先登录温馨)
2.3小程序的应用场景
- 各行各业都在使用,电商,微活动,抽奖,团购,打车。
- 家政 餐饮 电商等等,如果碰见一些不确定的分类,找个相似的分类就可以
2.4小程序的发展前景
- 依靠腾讯公司,(人多,钱多)
- 运行环境微信 : 用户多,流量大
2.5微信小程序的接入流程
2.5.1开放注册范围
- 百度小程序个人注册不了,支付宝小程序可以注册。
2.5.2提供的开发支持
2.5.3小程序的接入流程
2.5.3.1注册
- 一个账号(邮箱)只能注册一个类型的公众平台的账号,一个微信号可以绑定多个账号
2.5.3.2填写邮箱
2.5.3.3激活链接
2.5.3.4选择主体信息
- 小程序是属于谁的
2.5.3.5填写主体信息
2.5.3.6绑定微信账号
- 扫码绑定微信账号,下一次直接使用微信扫码登录就行。
2.6微信小程序管理后台介绍
2.6.1首页
2.6.2小程序的信息的设置
2.6.3小程序的开发设置
2.6.3.1appid
- appid是小程序的唯一的标示,上线时要使用,开发时可以不用。
2.6.3.2服务器的域名
- 小程序没有跨域,小程序上线后要在小程序的管理后台开发设置中填写请求的域名,否则不能请求成功
2.6.3.3统计
- 一般小程序的运营人员会看。
2.6.3.4版本管理
- 开发版本:开发者在微信开发者工具中开发完成了代码点击上传形成了开发版本。
- 体验版本:是开发版本设置过来的(有体验权限的人才能体验)
- 审核版本:开发版本提交审核得到审核版本。(审核挺严格,1-7个工作日)
- 线上版本:微信后台管理员审核审核版本通过后获得线上版
2.6.3.5成员管理(最多有31个人)
- 管理员:小程序的拥有者
- 项目成员
- 参与项目开发和体验运营的人员项目的成员是管理员添加的,可以根据工作职责的不同,分配不同的权限,最多能添加15人。
- 参与项目开发和体验运营的人员项目的成员是管理员添加的,可以根据工作职责的不同,分配不同的权限,最多能添加15人。
- 体验成员,是管理员添加的,点击添加按钮,搜索微信号,点击添加,最多能添加15人。
3.微信开发者工具
- 一个微信提供的编辑器,集成了开发,调试和上线于一体。
https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
3.1下载
3.2安装
- 安装时不要安装在C盘,尽量不要放置在中文路径下。傻瓜式安装
3.3使用
3.4新建一个项目
- 选择一个空目录。
3.5开发者工具的讲解
- 1菜单栏
- 2工具栏
- 3 模拟器(类似微信app)
- 4目录结构
- 5编辑代码的部分
- 6调试器所在的区域
3.6关于编译
- 就是将小程序的代码通过基础库编译成各个平台(andriod,ios)认识的代码,编译的过程不用我们操作,开发者工具自动帮我们编译好了
3.7关于appId
- 只有真实appid才能上线小程序,使用云开发
4.小程序的目录结构
- 目录和文件组成
- 小程序包含一个描述整体程序的
app
和多个描述各自页面的page
组成 - 目录
pages
:小程序的页面放在该目录,一般一个目录就是一个页面- **.js :放置的该页面的逻辑
- **.json:放置该文件的配置
- **.wxss 对标css,该文件中放置的是页面的样式
- **.wxml 对标html,该文件中放置的是该页面结构
utils
:放置的是项目模块化的公共代码(模块文件,可以做一些功能模块封装)common
:公共的样式,components
:公共的组件static
:公共的资源,图片,视屏,音频文件
- 文件
app.js
:放置的整个小程序的逻辑。(项目的入口js文件)app.json
: 放置的是整个小程序的配置(项目的配置文件)app.wxss
:放置的是小程序整体的样式结构(全局的css样式文件)project.config.json
:项目配置文件,不要手动修改里面的配置,记录用户配置的喜好,即使换了小程序的运行环境,不用重新配置了。sitemap.json
:配置微信能不能搜索到该小程序(栈点索引)
小程序目录描述
- 小程序包含一个描述整体程序的
app
和多个描述各自页面的page
。 - 一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下:
文件 | 必需 | 作用 |
---|---|---|
app.js | 是 | 小程序逻辑 |
app.json | 是 | 小程序公共配置 |
app.wxss | 否 | 小程序公共样式表 |
- 一个小程序页面由四个文件组成,分别是:
文件类型 | 必需 | 作用 |
---|---|---|
js | 是 | 页面逻辑 |
wxml | 是 | 页面结构 |
json | 否 | 页面配置 |
wxss | 否 | 页面样式表 |
允许上传的文件类型
- 在项目目录中,以下文件会经过编译,因此上传之后无法直接访问到:
*.js、app.json、*.wxml、*.wxss
(其中 wxml 和 wxss 文件仅针对在 app.json 中配置了的页面)。除此之外,只有后缀名在白名单内的文件可以被上传,不在白名单列表内文件在开发工具能被访问到,但无法被上传。具体白名单列表如下:- wxs
- png
- jpg
- jpeg
- gif
- svg
- json
- cer
- mp3
- aac
- m4a
- mp4
- wav
- ogg
- silk
5.小程序的配置
5.1全局配置
- 小程序根目录下的
app.json
文件用来对微信小程序进行全局配置,决定页面文件的路径(配置路由及)、窗口表现、设置网络超时时间、设置多 tab 等。- 1 是一个json格式的数据
- 2 语法格式很严格
- 3 不允许写注释
5.1.1pages
- 页面路径列表
- 页面路径不能以/ ./ …/ 开头
- 数组中的每一项都要用逗号隔开,最后不加逗号
- 不能使用单引号
- 配置小程序的路由,必填,里面放置的小程序的页面
"pages": [ "pages/index/index", "pages/cart/cart", "pages/my/my", "pages/cate/cate"],
5.1.2entryPagePath
- 设置小程序的默认启动的页面。
- 如果有entryPagePath属性,默认启动的首页就是该选项配置的
- 如果没有entryPagePath属性,默认启动的页面使用pages属性中的第一个页面
- 一般开发者习惯将index页面作为首页
"entryPagePath": "pages/index/index",
5.1.3window
- 用于设置小程序的状态栏、导航条、标题、窗口背景色。
{"pages": ["pages/index/index","pages/a/a","pages/logs/logs","pages/b/b"],"window": {"navigationBarBackgroundColor": "#f00","navigationBarTitleText": "我的","navigationBarTextStyle": "black",// 下拉刷新界面的背景颜色,需要开启enablePullDownRefresh,才能看见效果"backgroundColor": "#ccc","enablePullDownRefresh": true,"backgroundTextStyle": "light",// 设置导航栏 如果设置custom 设置自定义导航栏 之前做的导航栏样式都不会再有效果"navigationStyle": "custom"},"style": "v2","sitemapLocation": "sitemap.json"
}
5.1.4tabbar配置
"tabBar": {"color":"#ccc","selectedColor": "#f00","backgroundColor": "#fff","borderStyle": "white","position": "top","custom": false,"list": [{"pagePath": "pages/index/index","text":"首页","iconPath": "./images/index.png","selectedIconPath": "./images/indexFull.png"},{"pagePath": "pages/car/car","text":"购物车","iconPath": "./images/cart.png","selectedIconPath": "./images/cartFull.png"},{"pagePath": "pages/mine/mine","text":"个人中心","iconPath": "./images/my.png","selectedIconPath": "./images/myFull.png"}]},
注意
- 至少设置2个,最多5个tab
- position设置为top的时候 iconpath和selectedIconpath没有效果
- iconpath和selectedIconpath图片40kb 不能使用网络图片
- pagePath的页面文件路径不能以/ …/ ./ 开头
5.2页面配置
- 页面配置文件高于全局配置文件,只能配置window项
- 每一个小程序页面也可以使用同名
.json
文件来对本页面的窗口表现进行配置,页面中配置项会覆盖app.json
的window
中相同的配置项。页面配置的作用范围只作用于该页面。
"navigationBarBackgroundColor": "#ff0000","navigationBarTextStyle": "white","navigationBarTitleText": "小u商城","backgroundColor": "#00ff00","backgroundTextStyle": "dark","enablePullDownRefresh": true
5.3sitemap配置(了解)
- 栈点索引
- 微信现已开放小程序内搜索,开发者可以通过
sitemap.json
配置,或者管理后台页面收录开关来配置其小程序页面是否允许微信索引。当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索词条触发该索引时,小程序的页面将可能展示在搜索结果中
5.3.1在小程序管理的后台配置是否允许被搜索到
- 打开小程序的管理后台----页面内容收录
5.3.2配置sitemap.json
- 虽然在小程序的管理后台配置了希望被微信搜索到,要配置搜索规则。
- 默认规则:如果sitemap中的规则没有一个命中的画则使用默认规则,所有的页面都将被搜索得到
- 小程序根目录下的
sitemap.json
文件用于配置小程序及其页面是否允许被微信索引,文件内容为一个 JSON 对象,如果没有sitemap.json
,则默认为所有页面都允许被索引;sitemap.json
有以下属性:
配置项
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
rules | Object[] | 是 | 索引规则列表 |
- 一个对象就是一个访问规则
{"rules": [{"action": "disallow","page":"/pages/cart/cart"},{"action": "disallow","page":"/pages/my/my"},{"action": "allow","page":"/pages/detail/detail","params": ["price","info"],"matching": "partial"}]}
rules
- rules 配置项指定了索引规则,每项规则为一个JSON对象,属性如下所示:
属性 | 类型 | 必填 | 默认值 | 取值 | 取值说明 |
---|---|---|---|---|---|
action | string | 否 | “allow” | “allow”、“disallow” | 命中该规则的页面是否能被索引 |
page | string | 是 | “*”、页面的路径 |
* 表示所有页面,不能作为通配符使用
|
|
params | string[] | 否 | [] | 当 page 字段指定的页面在被本规则匹配时可能使用的页面参数名称的列表(不含参数值) | |
matching | string | 否 | “inclusive” | 参考 matching 取值说明 | 当 page 字段指定的页面在被本规则匹配时,此参数说明 params 匹配方式 |
priority | Number | 否 | 优先级,值越大则规则越早被匹配,否则默认从上到下匹配 |
- matching 取值说明
值 | 说明 |
---|---|
exact | 当小程序页面的参数列表等于 params 时,规则命中 |
inclusive | 当小程序页面的参数列表包含 params 时,规则命中 |
exclusive | 当小程序页面的参数列表与 params 交集为空时,规则命中 |
partial | 当小程序页面的参数列表与 params 交集不为空时,规则命中 |
- 对于没有参数的页面使用action和page就能完成配置,对于有参数的页面,需要params和matching配合使用,根据页面的需求.
- 一般项目完成后在进行配置。
6小程序场景值
6.1概念
- 场景值用来描述用户进入小程序的路径。完整场景值的含义请查看,用户怎么进入小程序。
6.2应用
- 不同场景值做不同的业务。
- kfc:通过扫码进入的小程序,跳转到点餐页面,通过公众号菜单,进入到发放优惠券的界面。
onLaunch: function (option) {if(option.scene==1035){console.log("发放优惠券")}if(option.scene==1011){console.log("点餐")} },
6.3获取场景值的方式
场景值
- 对于小程序,可以在
App
的onLaunch
和onShow
,或wx.getLaunchOptionsSync 中获取上述场景值。
App({// 小程序初始化完成走的生命周期onLaunch(a){// console.log("onlaunch",a)// 同步 let b = wx.getLaunchOptionsSync();console.log(b)if(b.scene==1011){console.log("活动详情")}},onShow(e){console.log("onshow",e)}})
- 对于小游戏,可以在 wx.getLaunchOptionsSync 和 wx.onShow 中获取上述场景值
day 02
- 小程序的配置
- 全局配置—app.json–所有页面----路由–全局窗口–tabBar–分包–注册全局组件
- 局部配置–页面对应的json文件–当前页面生效—页面窗口–局部注册组件
- 局部配置–覆盖全局
1小程序的逻辑层
- 小程序开发框架的逻辑层使用
JavaScript
引擎为小程序提供开发者JavaScript
代码的运行环境以及微信小程序的特有功能。
1.1逻辑层的概念
- 逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。
- 开发者写的所有代码最终将会打包成一份
JavaScript
文件,并在小程序启动的时候运行,直到小程序销毁。这一行为类似 ServiceWorker,所以逻辑层也称之为 App Service。 - 在
JavaScript
的基础上,我们增加了一些功能,以方便小程序的开发:- 增加
App
和Page
方法,进行程序注册和页面注册。 - 增加
getApp
和getCurrentPages
方法,分别用来获取App
实例和当前页面栈。 - 提供丰富的 API,如微信用户数据,扫一扫,支付等微信特有能力。
- 提供模块化能力,每个页面有独立的作用域。
- 注意:小程序框架的逻辑层并非运行在浏览器中,因此
JavaScript
在 web 中一些能力都无法使用,如window
,document
等。
- 增加
1.2注册小程序
- 每个小程序都需要在
app.js
中调用App
方法注册小程序实例,绑定生命周期回调函数、错误监听和页面不存在监听函数等。 - 注册小程序。接受一个
Object
参数,其指定小程序的生命周期回调等。 - App() 必须在
app.js
中调用,必须调用且只能调用一次。不然会出现无法预期的后果。
1.2.1小程序的生命周期监听方法
App({/** \* 当小程序初始化完成时,会触发 onLaunch(全局只触发一次) */ onLaunch: function () {console.log("app launch") }, /** \* 当小程序启动,或从后台进入前台显示,会触发 onShow */ onShow: function (options) { console.log("app show") }, /** \* 当小程序从前台进入后台,会触发 onHide */ onHide: function () { console.log("app hide") }, /** \* 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息(当小程序有报错信息,无论是页面文件还是全局文件,只要有报错信息,就会触发onerror函数) */ onError: function (msg) { //调用记录日志接口 }, onPageNotFound:function(){ wx.navigateTo({ url: './pages/notfound/notfound', }) }
})
1.2.2其他
- 用户可以在App中自定义一些属性和方法,然后通过this.属性/方法去调用,
App({globalData:{ token:"", userinfo:"" }, /** \* 当小程序初始化完成时,会触发 onLaunch(全局只触发一次) */ onLaunch: function () { this._login() }, _login:function(){ //判断用户有没有登录过 //如果登录过 //调用登录的接口,返回对应的token //将token存储到缓存中,再将token放到globalData中,这里globalData就是全局变量 console.log("login ok") this.globalData.token="abcdefgh124343242"this.globalData.userInfo={name:"zhangsan"} console.log(this.globalData) }, /** \* 当小程序启动,或从后台进入前台显示,会触发 onShow */ onShow: function (options) { console.log("app show") },/** \* 当小程序从前台进入后台,会触发 onHide */ onHide: function () { console.log("app hide") }, /** \* 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息 */ onError: function (msg) { //调用记录日志接口 }, onPageNotFound:function(){ wx.navigateTo({ url: './pages/notfound/notfound', }) }
})
- 在App.js获取全局变量和函数
//app.js
App({// 小程序启动或者切前台onShow(){console.log("onshow")},// 小程序初始化完成 全局只触发一次onLaunch(){console.log("onlaunch")console.log(this.userInfo.name)console.log(this.userInfo.age)console.log(this.say())},// 小程序切后台的时候触发onHide(){console.log("onhide")},// 当小程序有报错信息,无论是页面文件还是全局文件,只要有报错信息,就会触发onerror函数onError(err){console.log("错误信息",err)},onPageNotFound(){console.log("页面不存在")wx.navigateTo({url: '/pages/logs/logs',})},// 全局的变量userInfo:{name:"张三",age:20},// say(){// return "正在吃东西" // }// 全局的函数say:function(){// console.log(this.userInfo,"函数")// 在函数内部访问全局变量return this.userInfo.name + "正在吃东西"}
})
- 在其他页面的js获取全局变量和函数
// 获取app实例唯一的方法
let app = getApp();
console.log(app.userInfo.name)// 注意事项:不要在页面中调用app的生命周期
Page({})
1.2.3getApp的使用
- 整个小程序只有一个 App 实例,是全部页面共享的。开发者可以通过
getApp
方法获取到全局唯一的 App 实例,获取App上的数据或调用自定义函数开发者注册在App
上的函数。
// xxx.js
const appInstance = getApp()
console.log(appInstance.globalData) // I am global data
1.2.4使用getapp的注意事项
- 不要在定义于
App()
内的函数中,或调用App
前调用getApp()
,使用this
就可以拿到 app 实例。 - 通过
getApp()
获取实例之后,不要私自调用生命周期函数。
1.3注册页面
- 对于小程序中的每个页面,都需要在页面对应的
js
文件中使用Page构造方法进行注册,指定页面的初始数据、生命周期回调、事件处理函数等。
1.3.1页面的生命周期监听函数
Page({/**\* 页面的初始数据*/data: { },/**\* 生命周期函数--监听页面加载*/onLoad: function (options) {console.log("index load")},/**\* 生命周期函数--监听页面初次渲染完成*/onReady: function () {console.log("index ready")},/**\* 生命周期函数--监听页面显示*/onShow: function () {console.log("index show")},/**\* 生命周期函数--监听页面隐藏*/onHide: function () {console.log("index hide")},/**\* 生命周期函数--监听页面卸载*/onUnload: function () {console.log("index unload")},/**\* 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh: function () {console.log("下拉刷新")},/**\* 页面上拉触底事件的处理函数*/onReachBottom: function () {console.log("加载更多")},/**\* 用户点击右上角分享*/onShareAppMessage: function () {}
})
- 生命周期顺序(不含异步):
- 进入的时候:app.js的onLaunch—onshow 页面的onLoad—页面的onShow
- 离开的时候:页面的onHide—app.js的onHide
1.3.2关于data
- data 是页面第一次渲染使用的初始数据。
- 页面加载时,data 将会以JSON字符串的形式由逻辑层传至渲染层,因此data中的数据必须是可以转成JSON的类型:字符串,数字,布尔值,对象,数组。
- 渲染层可以通过 WXML 对数据进行绑定。
//修改数据
this.setData({ num:2
})
- 里面放置页面初始化的数据.初始化的数据可以展示在视图层。
- this.data.键名:获取
- this.setData( {键名:new键值}):设置
data: {name:"zhangsan",age:"18"},/**\* 生命周期函数--监听页面加载*/onLoad: function (options) {this._login()},_login:function(){console.log("login ok") },_fn:function(){this.setData({ age:2})},
- 页面的处理函数
// pages/demo1/demo1.js
Page({/*** 页面的初始数据*/data: {num:1,},//页面的下拉刷新,必须先把enablePullDownRef开启才可以出发该事件函数onPullDownRefresh(){console.log("demo1的下拉刷新")this.setData({num:2})console.log(this)},//默认是距离底部有50px的时候,触发该函数,如果想改变距离,设置onReachBottomDistance就可以onReachBottom(){console.log("demo1的上拉刷新")},// 页面滑动事件 onPageScroll(e){console.log("页面的滚动事件",e)}})
注意:请只在需要的时候才在 page 中定义此方法,不要定义空方法。以减少不必要的事件派发对渲染层-逻辑层通信的影响。 注意:请避免在 onPageScroll 中过于频繁的执行 setData
等引起逻辑层-渲染层通信的操作。尤其是每次传输大量数据,会影响通信耗时。
1.3.3getCurrentPages
- 获取当前的页面栈,页面栈是一个数组,用户访问过的页面都记录在这个数组里,方便用户返回
- 数组中第一个元素为首页,最后一个元素为当前页面。
- 不要尝试修改页面栈,会导致路由以及页面状态错误。
- 不要在
App.onLaunch
的时候调用getCurrentPages()
,此时page
还没有生成。
1.4小程序的页面生命周期
2小程序的视图层
- 结构 + 样式
https://developers.weixin.qq.com/miniprogram/dev/framework/view/
2.1视图层的概念
- 框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。
- 将逻辑层的数据反映成视图,同时将视图层的事件发送给逻辑层。
- WXML(WeiXin Markup language) 用于描述页面的结构。
- WXSS(WeiXin Style Sheet) 用于描述页面的样式。
- 组件(Component)是视图的基本组成单元。
2.2wxml(小程序的结构)
- 放置组件+要渲染的数据
- 数据绑定
<!-- 1.普通的数据绑定 -->
<view> {{msg}} </view>
<!-- 2.属性绑定 -->
<!-- <view id="box"></view> -->
<view id="{{ID}}"></view>
<!-- 3.关键字绑定 true/false hidden 隐藏 true隐藏 false显示"132"-----true注意:非空字符串转成布尔值,都是转换为true因此需要改写为 "{{ true/false }}"
-->
<view hidden="{{ false }}">主人下马客在船</view><!-- 4.运算 -->
<!-- 4.1算术运算 -->
<view>{{1+2+num}}</view>
<!-- 4.2字符串运算 --><!-- 123 33 -->
<view>{{1+2+"3"}}</view>
<!-- -->
<view>{{1+"2"+3}}</view>
<!-- 4.3三元运算/三目运算 表达式 ? true的执行代码 : false的执行代码 -->
<view>{{ store>=60?"及格":"不及格" }}</view>
<!-- 4.4 路径运算 就是如何拿数组中的值和对象的值 --><view>{{arr[0]}}</view><view>{{arr[1]}}</view><view>{{arr[2]}}</view><view>{{obj.name}}------{{obj.text}}</view><!-- 注意事项 --><view></view>
- 注意:无论是普通的数据绑定,还是属性绑定,或者是其他的,只要进行数据渲染,都需要加{{}}
- 列表渲染
<!-- wx:for 列表渲染wx:for="{{ [1,2,3,4] }}"item 默认的数据列表项index 默认的下标改变默认值wx:for-index="属性值"wx:for-item="属性值"注意:如果改变了默认值,之前的item,index就不再起作用vue v-for="(item,index) in arr" {{item}}===={{index}}--><view wx:for="{{[1,2,3,4]}}" wx:key="*this"> {{index}}-------{{item}}</view><view wx:for="{{arr}}" wx:for-item="item1" wx:for-index="index1" wx:key="*this" >{{index1}}-------{{item1}}{{index}}</view><view wx:for="{{arr}}" wx:key="index">{{index}}-----{{item}}
</view><!-- key值*this当前item如果是唯一的值,就可以用*this唯一的属性如果item中的某一个属性标识唯一,就可以使用该属性最为key值不加key如果当前循环体不发生改变,可以不加加key如果当前循环体发生了改变,需要加key-->
<!--pages/demo2/demo2.wxml-->
<text>pages/demo2/demo2.wxml</text>
<view wx:for="{{obj}}" wx:key="*this">{{index}}------ {{item}}
</view><view wx:for="{{goods}}" wx:key="id">{{index}}-----{{item.id}}-----{{item.name}}------{{item.price}}
</view><!-- 注意事项 --><!-- 花括号和引号之间如果有空格,将最终被解析成为字符串 -->
<view wx:for=" {{[1,2,3]}}">{{item}}
</view><!-- 如果循环数据不加{{}},那么数组名或者对象名就当成一个字符串 -->
<view wx:for="[1,2,3]">{{item}}</view><view><block wx:for="{{arr}}">{{item}}</block>
</view>
- 条件渲染
<!--pages/demo3/demo3.wxml-->
<text>pages/demo3/demo3.wxml</text>
<!-- 条件渲染wx:ifwx:elifwx:else--><!-- 单分支 --><!-- <view wx:if="{{store>=60}}">及格</view> --><!-- 双分支 --><view wx:if="{{store>=60}}">及格</view><!-- <view wx:if="{{store<60}}">不及格</view> --><!-- <view wx:else>不及格</view> --><!-- 低于60 不及格 60-80 中等 大于80 优秀 --><!-- 多分支 --><view wx:if="{{store>=80}}">优秀</view><view wx:elif="{{store>=60}}">中等</view><view wx:else>不及格</view><!-- block --><!-- wx:if hidden --><view hidden="{{false}}">内容</view><view wx:if="{{false}}">内容一</view><!-- wx:if 如果设置false,是在Dom结构中删除结构 hidden 就是给元素添加一个display:none如果是频繁操作 使用hidden因为 wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。-->
数据绑定
<view>{{name}}</view>
<view>{{age}}</view>
绑定属性
<view data-title="{{title}}">{{age}}</view>
关键字的处理
- true和false是关键字,使用时也要使用
{{}}
<checkbox checked="{{false}}"></checkbox>
运算
- 算术运算
<view data-title="{{title}}">{{age+1}}</view>
- 逻辑运算
<checkbox checked="{{age<20}}"></checkbox>
- 字符串运算
<view>{{name+"三"}}</view>
- 路径运算
<view>{{arr[0]}}</view>
<view>{{user.height}}</view>
- 三元运算符
<view class="{{age>18?'red':'blue'}}">{{user.height}}</view>
2.2.2列表渲染
data: {name:"zhangsan",age:17,title:"我是标题",arr:[1,2,3],user:{height:180,weight:"150"},goods:[{id:1,name:"小米"},{id:2,name:"华为"}],string:"abcdefg"},
<view>--------遍历数组-----------</view>
<view wx:for="{{arr}}" wx:key="*this">{{index}}---{{item}}
</view>
<view wx:for="{{arr}}" wx:key="*this" wx:for-item="vo" wx:for-index="key">{{key}}---{{vo}}
</view>
<view>--------遍历对象-----------</view>
<view wx:for="{{user}}" wx:key="*this">{{index}}---{{item}}
</view>
<view wx:for="{{user}}" wx:key="*this" wx:for-item="vo" wx:for-index="key">{{key}}---{{vo}}
</view>
<view>--------遍历数组对象-----------</view>
<view wx:for="{{goods}}" wx:key="*this">{{index}}---{{item.id}}---{{item.name}}
</view>
<view>--------遍历字符串-----------</view>
<view wx:for="{{string}}" wx:key="*this">{{index}}---{{item}}
</view>
<view>--------遍历数字-----------</view>
<view wx:for="{{10}}" wx:key="*this">{{index}}---{{item}}
</view>
<block wx:for="{{goods}}" wx:key="*this"><view>{{item.id}}</view><view>{{item.name}}</view>
</block>
block是包裹元素
- 不会渲染到页面上,不能在上面写属性
wx:key
- 如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input 中的输入内容,switch 的选中状态),需要使用
wx:key
来指定列表中项目的唯一的标识符。 wx:key
的值以两种形式提供- 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 保留关键字
*this
代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。
- 当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
- 如不提供
wx:key
,会报一个warning
, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
2.2.3条件渲染
- 使用判断时也可以使用block包裹元素
<view wx:if="{{age>=18}}">成年</view><view wx:if="{{age>=18}}">成年</view>
<view wx:else>未成年</view><view wx:if="{{age>=18}}">成年</view>
<view wx:elif="{{age>=15}}">青少年</view>
<view wx:else>少年</view>
wx:if vs hidden
- 因为
wx:if
之中的模板也可能包含数据绑定,所以当wx:if
的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。 - 同时
wx:if
也是惰性的,如果在初始渲染条件为false
,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。 - 相比之下,
hidden
就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。 - 一般来说,
wx:if
有更高的切换消耗而hidden
有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用hidden
更好,如果在运行时条件不大可能改变则wx:if
较好。
2.2.4模板(了解)
- 什么是模板
- WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。
- 如何定义模板
name="名字"
- 如何使用模板
is="相对应的模板名字"
- 在其他页面使用模板
<!-- 引入 --><!-- import inclue --><import src="/pages/template/header.wxml"></import>
<!-- 使用 -->
<template is="myheader"></template>
- 模板的传参
要在模板中定义
<!--pages/demo4/demo4.wxml-->
<text>pages/demo4/demo4.wxml</text><!-- 定义模板 -->
<template name="mytem1"><view>姓名:{{name}}</view><view>年龄:{{age}}</view>
</template>
- 在页面文件中使用
<!-- 使用模板 --><!-- <template is="mytem1"></template>
<template is="mytem1"></template> -->
<!-- 使用模板 --><!-- <template is="mytem1"></template>
<template is="mytem1"></template> --><!-- 带参数使用模板 注意:不要使用{}去传参数 --><template is="mytem1" data="{{name:'张三',age:30}}"></template>
<template is="mytem1" data="{{name:'李四',age:60}}"></template>
<!-- <template is="mytem1" data="{{{name:'李四',age:60}}}"></template>
--><template is="mytem1" data="{{name:obj.name,age:obj.age}}"></template><template is="mytem1" data="{{ obj }}"></template>
- 引用
- import和inclue引入
include 可以将目标文件除了 <template/> <wxs/> 外的整个代码引入,相当于是拷贝到 include 位置
import可以在该文件中使用目标文件定义的template
import引的是模板 inclue引入的是普通的组件
- wxss
- WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。
- 尺寸单位
- 设计稿尺寸 750 640
设计稿的元素宽度2px/设计稿的宽度750px = 设计布局的宽度2rpx/设备的宽度750rpx设计稿的元素宽度2px/设计稿的宽度640px = 设计布局的宽度2rpx/设备的宽度750rpx
- 样式导入
/* pages/demo6/demo6.wxss */
@import "/common/my.wxss";.box{width: 100rpx;height: 100rpx;background-color: red;
}
- 内联样式
- 选择器
- 全局样式和局部样式
定义模板
<template name="head"><view>我是页面的头部</view>
</template><template name="foot"><view>我是页面的底部</view>
</template>
使用模板
<template is="head"></template><view>我是cate</view><template is="foot"></template>
使用模板并且向模板中传值
- js
data: { style:"style1",
temp:{ nav:[{ id:1,
name:"男装"
},{ id:2,
name:"女装"
}],
name:"aaa"
}},
- wxml
<template name="style1"><view class="nav1">
<view wx:for="{{nav}}">{{item.name}}</view>
<view>{{name}}</view></view>
</template>
<template is="{{style}}" data="{{...temp}}"></template>
2.2.5引用(了解)
- WXML 提供两种文件引用方式
import
和include
。
import
- import可以在该文件中使用目标文件定义的template,import
只引入目标文件中的template模板
,其余的一概不引入
<import src="/template/template.wxml"/>
- C import B,B import A,在C中可以使用B定义的
template
,在B中可以使用A定义的template
,但是C不能使用A定义的template
。
include
include
可以将目标文件除了<template/>
<wxs/>
外的整个代码引入,相当于是拷贝到include
位置
<include src="/template/template.wxml" />
2.3wxss(小程序的样式)
2.3.1wxss的概念
- WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。
- WXSS 用来决定 WXML 的组件应该怎么显示。
- 为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。
- 与 CSS 相比,WXSS 扩展的特性有:
- 尺寸单位
- 样式导入
2.3.2尺寸单位
- rpx(responsive pixel): 可以根据屏幕宽度进行自适应。
规定屏幕宽为750rpx
。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
设备 | rpx换算px (屏幕宽度/750) | px换算rpx (750/屏幕宽度) |
---|---|---|
iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
iPhone6 Plus | 1rpx = 0.552px | 1px = 1.81rpx |
- 建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。
- 注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。
2.3.3样式导入
- 使用
@import
语句可以导入外联样式表,@import
后跟需要导入的外联样式表的相对路径,用;
表示语句结束。
@import "../../common/cart.wxss";
2.3.4内联样式
- style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度
<view style="color:{{color}};font-weight:bold">nihao</view>
- class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上
.
,样式类名之间用空格分隔。
<view class="red {{color}}">nihao</view>
2.3.5选择器
- 目前支持的选择器有:(尽量使用class,因为组件有一个样式隔离)
选择器 | 样例 | 样例描述 |
---|---|---|
.class |
.intro
|
选择所有拥有 class=“intro” 的组件 |
#id |
#firstname
|
选择拥有 id=“firstname” 的组件 |
element |
view
|
选择所有 view 组件 |
element, element |
view, checkbox
|
选择所有文档的 view 组件和所有的 checkbox 组件 |
::after |
view::after
|
在 view 组件后边插入内容 |
::before |
view::before
|
在 view 组件前边插入内容 |
2.3.6全局样式和局部样式
- 定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。
3事件系统
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html
3.1事件的概念
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件对象可以携带额外信息,如 id, dataset, touches。
3.2事件的基本的使用
3.2.1事件的绑定
- 我们可以使用
bind+事件类型 = "函数名"
或者使用catch+事件类型 = "函数名"
来绑定事件 - wxml
<view bindtap="_fn1">事件1</view>
<view catchtap="_fn2">事件1</view>
- js
箭头函数拿不到this 建议在写事件函数的不要用箭头函数_fn1:function(){ console.log("我被触发了fn1")},_fn2(){ console.log("我被触发了fn2")},
事件函数中的this
//将this重新赋值
let money=[10,20,30]
let that=this
let new_money=money.map(function(item){ return item+that.data.add
})
console.log(new_money)
//使用箭头函数
let money=[10,20,30]
let new_money=money.map((item)=>{ return item+this.data.add
})
console.log(new_money)
3.2.2事件的类型
冒泡事件,非冒泡事件
- 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
- 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
冒泡事件
类型 触发条件 最低版本 touchstart 手指触摸动作开始 touchmove 手指触摸后移动 touchcancel 手指触摸动作被打断,如来电提醒,弹窗 touchend 手指触摸动作结束 tap 手指触摸后马上离开 longpress 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 1.5.0 longtap 手指触摸后,超过350ms再离开(推荐使用longpress事件代替) 除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的
submit
事件,input 的input
事件,scroll-view 的scroll
事件
3.2.3事件的绑定和冒泡
<view class="father" catchtap="_fn1"><view class="son" catchtap="_fn2"></view>
</view>
- 使用catch绑定事件会阻止事件冒泡,使用bind绑定的事件不会阻止冒泡,在哪里阻止事件冒泡,就绑定在哪个元素上
3.2.4事件对象
- 在触发事件时会产生一个事件对象,事件对象中包含很多信息
- 事件对象中的值
type
:什么事件触发的。touches
:事件发生的位置,detail
:子组件传递过来的数据就放在detail。currentTarget
:事件绑定的元素。target
:事件触发的元素。
3.2.4.1小程序传递参数
- 事件如何传参和接参(重要)
- 传参
id 接参 e.target.ide.currentTaget.iddata-*(自定义的参数名)接参 e.target.dataset.ide.currentTarget.dataset.id
- 小程序传递参数可以通过id,通过data-参数名称=“参数的值”这个数据进行传参,获取参数通过事件对象获取。
- 通过id传参,可以使用事件对象e.currentTarget.id 进行获取,只能传递一个参数。
- 通过==data-参数名称=“参数的值”==这个数据进行传参,使用事件对象中的e.currentTarget.dataset获取
<view class="father" data-user-sex="男" data-name="zhangsan" data-age="18" catchtap="_fn1"><view class="son" catchtap="_fn2"></view>
</view>
//推荐使用的传参方式,参数名称比如data-user-sex====>userSex//传递的参数可以是对象/数组
总结:
- 如果事件没有冒泡,触发的元素也是绑定的元素target和currentTarget的值是一样的,使用哪一个都可以。
- 如果事件有冒泡,触发的元素和绑定的元素是不一样的target和currentTarget的值是不一样的,使用时要慎重。
- 以后在哪个元素上绑定事件,就在哪个元素上传参数,获取参数统一都是用currentTarget去获取参数
- 注意事项
- bind和catch有什么区别?
- bind是冒泡
- catch是阻止冒泡
- target和currentTarget有什么区别?
- target 是触发事件的事件源
- currentTarget 是事件触发的当前组件
day 03
- 小程序逻辑层(js+小程序定义的方法)
- 注册小程序—app.js — App—生命监听的周期函数。
- 注册页面-----**.js----Page—页面的生命周期–getApp
- 小程序的视图层
- wxml–html—怎么渲染—列表渲染—条件渲染----
- wxss—css—增加了尺寸单位rpx—样式导入
- 事件系统
- 可以在视图层绑定事件
1组件基础
https://developers.weixin.qq.com/miniprogram/dev/component/swiper.html
1.1基础组件
- 框架为开发者提供了一系列基础组件,开发者可以通过组合这些基础组件进行快速开发。详细介绍请参考组件文档。
- 什么是组件:
- 组件是视图层的基本组成单元。
- 组件自带一些功能与微信风格一致的样式。
- 一个组件通常包括
开始标签
和结束标签
,属性
用来修饰这个组件,内容
在两个标签之内。
<tagname property="value">
Content goes here ...
</tagname>
- 注意:所有组件与属性都是小写,以连字符
-
连接
1.2属性的类型
类型 | 描述 | 注解 |
---|---|---|
Boolean | 布尔值 |
组件写上该属性,不管是什么值都被当作 true ;只有组件上没有该属性时,属性值才为false 。 如果属性值为变量,变量的值会被转换为Boolean类型
|
Number | 数字 |
1 , 2.5
|
String | 字符串 |
"string"
|
Array | 数组 |
[ 1, "string" ]
|
Object | 对象 |
{ key: value }
|
EventHandler | 事件处理函数名 |
"handlerName" 是 Page 中定义的事件处理函数名
|
Any | 任意属性 |
1.3公共的属性
- 任何一个组件上都可以写的属性
属性名 | 类型 | 描述 | 注解 |
---|---|---|---|
id | String | 组件的唯一标示 | 保持整个页面唯一 |
class | String | 组件的样式类 | 在对应的 WXSS 中定义的样式类 |
style | String | 组件的内联样式 | 可以动态设置的内联样式 |
hidden | Boolean | 组件是否显示 | 所有组件默认显示 |
data-* | Any | 自定义属性 | 组件上触发的事件时,会发送给事件处理函数 |
bind* / catch* | EventHandler | 组件的事件 | 详见事件 |
1.4私有属性
- 几乎所有组件都有各自定义的属性,可以对该组件的功能或样式进行修饰,一般会将这些属性写成一个文档
2基础内容
icon(图标)
<icon type="success" size="50" color="#ff0000"></icon><icon type="success_no_circle" ></icon><icon type="info" ></icon><icon type="warn" ></icon><icon type="waiting" ></icon><icon type="download" ></icon>
progress
<progress bindactiveend="_fn1" active="{{true}}" percent="40" stroke-width="10" show-info="{{true}}"></progress>
text
<!-- text user-select 文本是否能被选中decode 解码 < > & '    space 空格大小--><!-- "<p style="font-size:50px">内容<p>" --><view><text user-select="{{true}}" space="ensp">文本 内容</text></view>
<view><text user-select="{{true}}" space="nbsp">文本 内容</text></view>
<view><text user-select="{{true}}" space="nbsp" decode="{{true}}">文本>内容</text></view>
<text decode="{{true}}" space="ensp" user-select="{{true}}">{{goods_info}}</text>
rich-text(富文本)
nodes 节点列表string/arraystring形式
<rich-text nodes="<h2>二级标题</h2>"></rich-text>
array形式arr:[{// <h2 class="box1">二级标题数组</h2>// 标签名是节点node 标签内容是text//节点类型 type:"node",name:"h2", //标签名attrs:{class:"box1"}, //标签身上的属性children:[{type:"text",text:"二级标题数组"}]}]
<rich-text nodes="{{goods_info}}"></rich-text>
3容器组件
view(视图容器)
<view class="box" hover-class="active" hover-start-time="2000" hover-stay-time="5000"></view><view class="out" hover-class="out-active"><view class="inser" hover-class="inser-active" hover-stop-propagation="{{true}}"></view>
</view>
<view id="father" hover-class="blue"><view hover-stop-propagation="{{true}}" id="son" hover-class="red">我是son</view></view>
swiper
swiper的基础使用
swiper
<!--pages/demo04/demo04.wxml-->
<text>pages/demo04/demo04.wxml</text><!-- swiper 滑动视图容器 直接子组件只能是swiper-item swiper width 100% height 150image width 320 height 240
-->
<!-- <swiper><swiper-item>1</swiper-item><swiper-item>2</swiper-item><swiper-item>3</swiper-item>
</swiper> -->
<swiper indicator-dots="{{true}}"indicator-color="#ccc"indicator-active-color="#f00"autoplay="{{true}}"interval="1000"circular="{{true}}"current="2"vertical="{{false}}"previous-margin="50px"next-margin="50px"bindchange="_change"
><block wx:for="{{arrImage}}"><swiper-item><image src="{{item}}"></image></swiper-item></block>
</swiper>
<swiper indicator-dots="{{true}}"autoplay="{{true}}"current="2"interval="2000"circular="{{true}}"bindchange="_changeImg"\><swiper-item><image src="/static/banners/1.jpg" /></swiper-item><swiper-item><image src="/static/banners/2.jpg" /></swiper-item><swiper-item><image src="/static/banners/3.jpg" /></swiper-item></swiper>
封装指示点
<!--pages/demo05/demo05.wxml-->
<text>pages/demo05/demo05.wxml</text><!-- 模拟小标识 --><view class="banner"><!-- 轮播图片 --><swiperautoplayinterval="2000"circularbindchange="_change"
><swiper-item wx:for="{{arr}}"><image src="{{item}}"></image></swiper-item>
</swiper><!-- 小标识 -->
<view class="dots"><text wx:for="{{arr}}" class="{{ index==_currentIndex?'active':'' }}" ></text>
</view></view>
/* pages/demo05/demo05.wxss */
image{width: 100%;height: 100%;
}
.banner{position: relative;
}
.dots{position: absolute;left: 0;bottom: 0;width: 100%;text-align: center;
}
.dots text{width: 40rpx;height: 20rpx;display: inline-block;background: #ccc;margin-left: 10rpx;
}.dots .active{background-color: red;
}
// pages/demo05/demo05.js
Page({/*** 页面的初始数据*/data: {arr:["/logo/1.jpg","/logo/2.jpg","/logo/3.jpg",],_currentIndex:0,num:1},_change(e){// console.log(e.detail.current)// 异步 this.setData({_currentIndex:e.detail.current,},function(){// console.log(this.data.num++)})// 如果变量经过赋值改变之后,要渲染在视图层,建议写setdata进行改变值// 如果变量只在js文件中使用,可以直接进行赋值,不需要再setdata里面改变console.log( this.data.num++)}
})
自定义指示点的形状
- wxml文件
<view class="container"><swiper autoplay="{{true}}" bindchange="_changeImg"> <swiper-item wx:for="{{banner}}" wx:key="*this"> <image class="img" src="/static/banners/{{item}}" /> </swiper-item></swiper><view class="dots"> <text class="{{index==currentIndex?'active':''}}" wx:for="{{banner}}" wx:key="*this"></text></view></view>
- wxss文件
/* pages/swiper/swiper.wxss */.container{position: relative;}.container .dots{width: 100%;position: absolute;bottom: 20rpx;text-align: center;}.dots text{display: inline-block;width:20rpx;height:8rpx;margin-left:10rpx;background-color:#333;}text.active{background-color: blue;}.img{width: 100%;}
- js文件
/**\* 页面的初始数据*/data: { banner:["1.jpg","2.jpg","3.jpg"], currentIndex:0}, _changeImg:function(e){ this.setData({ currentIndex:e.detail.current })},
scroll-view
scroll-view
- 可滚动视图区域
<!--pages/demo06/demo06.wxml-->
<text>pages/demo06/demo06.wxml</text><!-- 纵向 y 子元素要超过父元素高度,父元素设置高度 scroll-y true --><!-- <scroll-view class="box" scroll-y="{{true}}"><view class="red">red</view><view class="green">green</view><view class="pink">pink</view>
</scroll-view> --><!-- 横向 x 父元素设置宽度 子元素要超出父元素的宽度 white-space nowrap scroll-x为true -->
<!--
<scroll-view class="box" scroll-x="{{true}}"><view class="red">red</view>
<view class="green">green</view>
<view class="pink">pink</view>
</scroll-view> --><view class="classify"><!-- 一级分类 --><scroll-view class="classify_l" scroll-y="{{true}}" ><view wx:for="{{arr}}" class="title" bindtap="_change" data-index="{{index}}">{{item.title}}</view></scroll-view><!-- 二级分类 --><scroll-view class="classify_r" scroll-y="{{true}}" scroll-into-view="carid{{_currentIndex}}"><view wx:for="{{arr}}" id="carid{{index}}" ><!-- carid1 carid2 --> <view class="secTitle" >{{item.title}}</view><view wx:for="{{item.goods}}" wx:for-item="item1" >{{item1.text}}</view></view></scroll-view>
</view>
_change(e){console.log(e.target.dataset.index)this.setData({_currentIndex:e.target.dataset.index})},
scroll-view基本使用
<!--横向滚动--><scroll-view class="scroll-x" scroll-x="{{true}}"><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view></scroll-view><!--纵向滚动--><scroll-view class="scroll-y" scroll-y="{{true}}"><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view><view>分类1</view></scroll-view>
- wxss
/* pages/scroll/scroll.wxss */.scroll-x{white-space: nowrap;}.scroll-x view {display: inline-block;padding:10rpx;background-color: #ccc;margin:0rpx 10rpx;}.scroll-y{height:600rpx;width:400rpx;border:1rpx solid #ccc}.scroll-y view {width: 400rpx;height:270rpx;background-color: #ccc;margin-bottom: 10rpx;}
使用scroll-view模拟京东分类页
- wxml文件
<view class="container"><scroll-view class="left" scroll-y="{{true}}"> <view bindtap="_scrollview" data-cate="cate1">分类1</view> <view bindtap="_scrollview" data-cate="cate2">分类2</view> <view bindtap="_scrollview" data-cate="cate3">分类3</view> <view bindtap="_scrollview" data-cate="cate4">分类4</view> <view bindtap="_scrollview" data-cate="cate5">分类5</view> <view bindtap="_scrollview" data-cate="cate6">分类6</view> <view bindtap="_scrollview" data-cate="cate7">分类7</view> <view bindtap="_scrollview" data-cate="cate8">分类8</view></scroll-view><scroll-view class="right" scroll-y="{{true}}" scroll-into-view="{{view}}"> <view id="cate1"> <text>分类1子分类</text> <text>分类1子分类</text> <text>分类1子分类</text> <text>分类1子分类</text> </view> <view id="cate2"> <text>分类2子分类</text> <text>分类2子分类</text> <text>分类2子分类</text> <text>分类2子分类</text> </view> <view id="cate3"> <text>分类3子分类</text> <text>分类3子分类</text> <text>分类3子分类</text> <text>分类3子分类</text> </view> <view id="cate4"> <text>分类4子分类</text> <text>分类4子分类</text> <text>分类4子分类</text> <text>分类4子分类</text> </view> <view id="cate5"> <text>分类5子分类</text> <text>分类5子分类</text> <text>分类5子分类</text> <text>分类5子分类</text> </view> <view id="cate6"> <text>分类6子分类</text> <text>分类6子分类</text> <text>分类6子分类</text> <text>分类6子分类</text> </view> <view id="cate7"> <text>分类7子分类</text> <text>分类7子分类</text> <text>分类7子分类</text> <text>分类7子分类</text> </view> <view id="cate8"> <text>分类8子分类</text> <text>分类8子分类</text> <text>分类8子分类</text> <text>分类8子分类</text> </view></scroll-view></view>
- js文件
data: { view:"cate1"},_scrollview:function(e){ let {cate}=e.currentTarget.dataset this.setData({ view:cate })},
- wxss文件
/* pages/scroll-view/scroll-view.wxss */.container{display: flex;height:800rpx;}.left{width:200rpx;height:800rpx;}.left view{height:120rpx;line-height: 120rpx;text-align: center;margin-bottom:20rpx;background-color: #ccc;}.right{width:550rpx;height:800rpx;}.right view{width: 550rpx;height:400rpx;background-color: #ccc;margin-bottom:20rpx;}.right view text{display: inline-block;padding: 20rpx;margin:10rpx;background-color: #fff;}
4媒体组件
image
- 图片,支持 JPG、PNG、SVG、WEBP、GIF 等格式(支持网络图片和在线资源图片)
<image src="/static/erha1.jpg" lazy-load="{{true}}" bindload="_load" /><!-- binderror 图片资源加载不成功bindload 图片资源加载成功lazy-load 懒加载show-menu-by-longpress 只识别小程序二维码-->
<image src="/logo/1.jpg" binderror="_error" bindload="_load" lazy-load="{{true}}"></image>
5表单组件
<form bindsubmit="_submit"><view class="box"><!-- input的type类型 指的是键盘的类型 -->
<!-- title -->
<view class="title">请填写以下信息</view><view><view>姓名</view><input type="idcard" placeholder="请输入姓名" name="name1" />
</view><view><view>联系方式</view><input type="idcard" placeholder="请输入姓名" name="tel"/>
</view><!-- 单选按钮 可以通过bindchange拿到想对应的value -->
<radio-group bindchange="_change1" name="sex"><view> <radio value="0">男</radio></view><view><radio value="1">女</radio></view><view><radio value="2">保密</radio></view></radio-group><view><view>您的爱好是</view><checkbox-group bindchange="_changeHobby" name="hobby"><view><checkbox value="吃饭">吃饭</checkbox></view><view><checkbox value="睡觉">睡觉</checkbox></view><view><checkbox value="打豆豆">打豆豆</checkbox></view></checkbox-group>
</view><view><view>是否同意</view><switch type="checkbox" name="isArr"></switch>
</view><view><button size="mini" type="primary" form-type="submit">提交</button><button size="mini" form-type="reset">重置</button>
</view><!-- 怎么区分button中的提交和重置 -->
<!-- 全部提交数据 -->
</view>
</form>
注意
- radio-group需要和radio组件一起使用
- checkbox-group需要和checkbox一起使用
- switch组件也有checkbox,值为true和false
- 怎么区分button中的提交和重置 利用button组件的form-type属性
- 如何一次获取全部表单数据 button按钮的form-type属性和form组件的bindsubmit事件一起使用,还需要在每个表单组件身上绑定name属性
<!--pages/form/form.wxml--><view class="page"><form bindsubmit="_submit" bindreset="_reset"><view class="title">请填写问卷调查</view><view> <label>姓名</label> <input class="input" type="text" placeholder="请填写姓名" name="name" bindinput="_inputName"></input></view><view> <label>联系方式</label> <input class="input" type="number" placeholder="请填写手机号码" name="tel" maxlength="11" bindinput="_inputPhone"></input></view><view> <label>性别</label> <radio-group name="sex" bindchange="_inputSex"> <view> <radio checked="{{true}}" value="男">男</radio> </view> <view> <radio color="#ff0000" value="女">女</radio> </view> <view> <radio disabled="{{true}}" value="保密">保密</radio> </view> </radio-group></view><view> <label>你的爱好</label> <checkbox-group name="hobby" bindchange="_inputHobby"> <view> <checkbox checked="{{true}}" value="抽烟">抽烟</checkbox> </view> <view> <checkbox color="#00ff00" value="喝酒">喝酒</checkbox> </view> <view> <checkbox disabled="{{true}}" value="烫头">烫头</checkbox> </view> </checkbox-group></view><view> <label>您是否同意我们联系你</label> <view> <switch name="agree" type="checkbox" bindchange="_inputAgree">同意</switch> </view></view><view> <label>请给我们的服务打分</label> <view> <slider name="score" show-value="{{true}}" value="60" min="0" max="100" bindchange="_inputScore"></slider> </view></view><view> <label>你喜欢的运动</label> <picker range="{{arr}}" name="sport" value="{{index}}" range-key="name" bindchange="_inputSport"> <view>你的选择是:{{arr[index].name}}</view> </picker></view><view> <label>你喜欢的时间</label> <picker mode="region"> <view>开始时间:</view> </picker></view> <view class="btn"> <button type="primary" form-type="submit" size="mini" >提交</button> <button type="warn" form-type="reset" size="mini">重置</button></view> </form></view>
- wxss
/* pages/form/form.wxss */.page{padding: 10rpx;}.page view{margin:15rpx;}.title{height:80rpx;line-height: 80rpx;padding-left: 10rpx;font-weight: bold;color:#fff;background-color: orangered;}view label{font-size: 36rpx;font-weight: bold;}.input{height:80rpx;border:1rpx solid #ccc;margin-top:10rpx;border-radius: 10rpx;padding-left: 10rpx;}
- js
data: { name:"",
tel:"",
sex:"男",
hobby:[],
agree:false,
score:60,
arr:[{ id:1,
name:"有氧运动"
},{ id:2,
name:"无氧运动"
}],
index:0},_submit:function(e){ console.log(e)},_inputSport:function(e){ this.setData({ index:e.detail.value
})},_inputName:function(e){ this.setData({ name:e.detail.value
})},_inputPhone:function(e){ this.setData({ tel:e.detail.value
})},_inputSex:function(e){ this.setData({ sex:e.detail.value
})},_inputHobby:function(e){ this.setData({ hobby:e.detail.value
})},_inputAgree:function(e){ this.setData({ agree:e.detail.value
})},_inputScore:function(e){ this.setData({ score:e.detail.value
})},
6导航组件
- 类似于H5中的a标签(可以进行页面跳转和页面链接)
navigator
target
值 | 说明 | 最低版本 |
---|---|---|
self | 当前小程序 | |
miniProgram | 其它小程序 |
open-type
<!--pages/demo1/demo1.wxml-->
<text>pages/demo1/demo1.wxml</text>
<!-- open-typenavigate 默认值
保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。使用 wx.navigateBack 可以返回到原页面。小程序中页面栈最多十层 redirect:
关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。
在小程序插件中使用时,只能在当前插件的页面中调用switchTab
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
在小程序插件中使用时,只能在当前插件的页面中调用navigateBack 关闭当前页面,返回上一页面或多级页面 delta 设置返回的页面数,默认值是1 如果参数值大于页面数 跳转到首页导航组件传参: 直接在页面路径上?拼接接参:是在onload里面的options接受参数
--><navigator url="/pages/homework/homework?id=121344&name='作业'" target="self"><button>组件跳转----index</button>
</navigator>
- navigate:保留当前的页面到页面栈。新的页面也会入栈。
<navigator target="self" url="../detail/detail" open-type="navigate" >跳转到商品详情</navigator>
场景:电子商城 首页—分类—商品列表–详情(还可以返回)
redirect
微信小程序入门笔记(一)相关推荐
- 微信小程序入门笔记-1
WXML WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件.事件系统,可以构建出页面的结构. 主要功能:数据绑定.列表渲染.条件渲染.模板.事件.引用 W ...
- 微信小程序入门笔记5(page.json)
page.json 一.全局配置 1.pages 页面路径 2. Windows配置 3.tabBar 底部导航 (1)list (2)networkTimeout 各类网络请求的超时时间 二.页面配 ...
- 【微信小程序】微信小程序入门与实战-个人笔记
微信小程序入门与实战 文章目录 微信小程序入门与实战 1 初识微信小程序 1-1 2020版重录说明 1-2 下载小程序开发工具 1-3 新建小程序项目 1-4 小程序appid的注册 1-5 新版小 ...
- 做一个微信小程序给TA——程序猿小白的情人节礼物(微信小程序入门——一文学会小程序开发到发布小程序的全过程)
# 情人节 可送给女朋友 的礼物,或者作为两人的纪念 # 效果展示:微信搜索 "王美美与曾小帅" 小程序即可查看效果 # 微信小程序入门--使用免费后端云(Bmod)搭建留言板 ...
- 微信小程序入门与实战(七月)
微信小程序入门与实战(七月) 第1章 初识微信小程序 第2章 小程序的基本目录结构与文件作用剖析 2-1 小程序页面的4种基本文件类型详解 第3章 rpx响应式单位与flex布局 3-3 新建页面的技 ...
- 微信小程序开发-笔记
一.开发文件结构 1.根目录下有三个文件:app.js,app.json和app.wxss.一个小程序项目必须有的三个描述App的文件.这三个文件是应用程序级别的文件.这3个文件的意义: 表1.1 ...
- 一个C#程序员学习微信小程序的笔记
一个C#程序员学习微信小程序的笔记 客户端打开小程序的时候,就将代码包下载到本地进行解析,首先找到了根目录的 app.json ,知道了小程序的所有页面. 在这个Index页面就是我们的首页,客户端在 ...
- 小程序 pagescrollto_微信小程序学习笔记(三)-- 首页及详情页开发
一.常用组件 在上一个章节中讲解了封装请求数据的模块,在此处请求轮播图的数据 1.首页轮播图数据的请求以及渲染 1.1 轮播图数据的请求 pages/home/home.js import 2 使用组 ...
- 微信小程序入门二:底部导航tabBar
小程序底部导航栏组件tabBar,可以参考下官方的API:tabBar 先看代码 //app.json {"pages":["pages/index/index" ...
最新文章
- Ansible 入门指南 - ansible-playbook 命令
- python做多元线性回归
- (二)Linux命令使用
- 测验4: 程序的控制结构 (第4周)
- netty系列之:netty架构概述
- php向下滑动,js如何判断鼠标滚轮是向下还是向上滚动
- checkbox大小缩放
- 【空号检测】批量手机号码空号检测查询软件,号码如何去除查询空号
- android控制灯编程,远程控制智能灯(android)
- 游戏BOSS关卡的设计
- 华为服务器安装系统流程图,华为a安装手册.docx
- 视频音轨音量是否为0检测过程
- 小程序审核出现的虚拟支付审核失败
- 〖TFS_CLUB社区〗-〖星荐官共赢计划〗~ 期待各位小伙伴的加入~
- 企业级 Go 项目实战,记住这 5 大核心要点
- 100725B Banal Tickets
- Git冲突:Your local changes would be overwritten by merge. Commit, stash or revert them to proceed.
- Mac系统怎么升级到macOS Catalina 10.15 beta版
- java 项目启动初始化_Spring项目启动时执行初始化方法
- HDU 1864 最大报销额 dp
热门文章
- JS写一个图片抽奖机
- 1230_SCons对于依赖的处理
- 从 RGB 到 HSV 的转换详细介绍
- 终结符号和非终结符号
- 买投影仪选当贝还是极米,哪个投影仪最好用
- P1008 [NOIP1998 普及组] 三连击
- 在OpenGL中创建一个球体动画,使球体在窗口内做自由落体运动,并在撞击地面后能够返回原来高度
- 计算机蓝屏代码0xc0000020,Win10系统运行程序提示“损坏的映像 错误0xc0000020”怎么解决...
- Jenkins系列之——第二章 Jenkins中Maven和JDK配置
- Python分布式通用爬虫(4)
- 微信小程序入门笔记-1