1. WXML 要求标签必须是严格闭合的,没有闭合将会导致编译错误。
2. 属性值也可以动态的去改变,有所不同的是,属性值必须被包裹在双引号中
hello world
hello world
3. WXML 中,使用wx:if="{{condition}}" 来判断是否需要渲染该代码块
1
2
3
4. 关于 .json文件
5.样式
title:{
overflow:hidden; /*自动隐藏文字*/
text-overflow:ellipsis; /*文字隐藏后添加省略号*/
white-space: nowrap; /**强制不换行*/
}
6.页面跳转动态修改导航栏标题和页面传参问题
动态修改导航栏标题,假如从A页面跳转到B页面,B页面的导航栏标题需要从A页面带过去。
页面A:
在设置bindtap的时候设置一个data-passparam;其中data-前缀是固定的,后面passparam是你要传递的参数,名字随便,但是不能出现大写字母,不然值传不过去。
在点击跳转方法中
bindMessageDetail:function(e){
vartitle = e.currentTarget.dataset.passparam;
wx.navigateTo({
url: "chat/chat?name="+title,
});
},
通过e.currentTarget.dataset.passparam获取刚才需要传递的参数,然后拼接到url后值就传递过去了。
在B页面,如果需要获取传递过来的值,需要在生命周期方法onLoad方法中获取
onLoad: function(options) {
let name= options.name;
},
,但是如果是需要给导航栏设置title,官方建议在
onReady: function() { },
方法中进行设置。所以如果是动态设置导航栏标题则在onLoad方法先获取传递过来的参数保存起来,然后在onReady方法里进行设置。
Page({
/**
* 页面的初始数据
*/
data: {
navTitle:''
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.data.navTitle = options.name;
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function() {
wx.setNavigationBarTitle({
title: this.data.navTitle // 其他页面传过来的标题名
})
},
7.列表渲染
1.在组件上使用wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。默认数组的当前项的下标变量名默认为index,数组当前项的变量名默认为item
{{index}}: {{item.message}}
2.使用wx:for-item 指定数组当前元素的变量名,使用wx:for-index 指定数组当前下标的变量名:
{{idx}}: {{itemName.message}}
3.类似 block wx:if ,也可以将 wx:for 用在
{{index}}: {{item}}
8.Toast使用和Modal的使用
- Toast使用方式一:(不推荐)
在.wxml文件中定义组件
请稍后重试
在js文件data中定义一个变量isShowToast用于控制是否显示Toast,在js文件需要显示Toast的地方
bindTapSearch:function(){
this.setData({isShowToast:true})
}
同时需要实现toastChange方法,不然Toast不会消失
toastChange:function(){
this.setData({ isShowToast: false })
},
2.Toast使用方式二:(推荐)
直接调用API控制Toast的显示和隐藏
- 显示Toast(显示完Toast后过了duration时间会自动隐藏)
wx.showToast({
title: '已发送',
icon: 'none', //此处(有success、loading、none三种样式可选)
duration: 1500
});
- 隐藏Toast
wx.hideToast();
3.Modal的使用方式一
//官方Modal(使用方式和Toast的方式一一样)
wx.showModal({
title: '标题',
content: '告知当前状态,信息和解决方法',
confirmText: '主操作',
cancelText: '次要操作',
success: function(res) {
if(res.confirm) {
console.log('用户点击主操作')
} elseif(res.cancel) {
console.log('用户点击次要操作')
}
}
})
4.Modal的使用方式二
内容
//no-cancel:是否隐藏cancel按钮
- 自定义Modal
参见:https://blog.csdn.net/solocoder/article/details/80696752
注意:官方已有组件
9.小程序中的slot(插槽)
有时候在自定义组件时,有一部分在某处是不需要显示的,而其他地方需要显示,这时候,可以用slot来控制隐藏的部分;
slot 标签可用在自定义组件中,根据外部传进来的标签,来显示和隐藏 如果需要显示就传递标签进来,如果不需要显示,就不传,这样,可以动态的设置自定义组件的样式,提高了组件的复用性
自定义组件,添加插槽,插槽的name一定要设置,使用时name要相同
{{text}}
使用组件,组件名为 ,name 要和添加时候一直(after) {{item.nums}} 里面的标签就是传递给插槽的,
注意:最重要的是激活插槽,在自定义组件的JS中,添加一下代码/** * 启用插槽 */ options:{ multipleSlots: true }
在组件的wxml中可以包含 slot 节点,用于承载组件使用者提供的wxml结构。
默认情况下,一个组件的wxml中只能有一个slot。需要使用多slot时,可以在组件js中声明启用。
A.js
Component({
options: {
multipleSlots: true // 在组件定义时的选项中启用多slot支持
},
properties: { /* ... */ }, methods: { /* ... */ } })
10.事件分类
事件分为冒泡事件和非冒泡事件:
- 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
- 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。事件绑定的写法同组件的属性,以key、value的形式。
· key以bind或catch开头,然后跟上事件的类型,如bindtap、catchtouchstart。自基础库版本 1.5.0 起,在非原生组件中,bind和catch后可以紧跟一个冒号,其含义不变,如bind:tap、catch:touchstart。
· value 是一个字符串,需要在对应的Page 中定义同名的函数。不然当触发事件的时候会报错。
bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。
如在下边这个例子中,点击inner view 会先后调用handleTap3和handleTap2(因为tap事件会冒泡到middle view,而middle view 阻止了tap 事件冒泡,不再向父节点传递),点击middle view 会触发handleTap2,点击outer view 会触发handleTap1。
outer view
middle view
inner view
组件间通信与事件(https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.html)
自定义组件触发事件时,需要使用 triggerEvent 方法,指定事件名、detail对象和事件选项
Component({
properties: {},
methods: {
onTap: function(){
varmyEventDetail ={} // detail对象,提供给事件监听函数
varmyEventOption ={} // 触发事件的选项
this.triggerEvent('myevent', myEventDetail, myEventOption) } } })
具体使用参见自定义modal文章对cancel和comfirm事件的处理(https://blog.csdn.net/solocoder/article/details/80696752)
11.如果当前处于登录界面(看不到tab),当用户登录成功后才能进入有tabBar的主页面,使用方法
wx.switchTab({
url:'/pages/home/index/index'
});
此处url需要使用绝对路径
相对路径:../../此类
绝对路径:类似’/page/’形式,绝对路径以“/”开头,表示根目录
12;微信小程序App()方法与getApp()方法
App()注册一个小程序,小程序的入口方法
App({
onLaunch: function(options) {
console.log("onLaunch");
},
onShow: function(options) {
console.log("onShow");
// Do something when show.
},
onHide: function() {
console.log("onHide");
// Do something when hide.
},
onError: function(msg) {
console.log(msg)
},
test:function() {
console.log("I am func from App.js");
},
globalData: {
userInfo:null,
helloFromApp:'Hello,I am From App.js'
}
})
在其他子页面如何使用test方法呢?
通过getApp获取全局对象,然后进行全局变量和全局方法的使用。
var app = getApp();
console.log(app.globalData.helloFromApp); // 调用全局变量
app.test(); // 调用全局方法
注意:
· App() 必须在 app.js 中注册,且不能注册多个。
· 不要在定义于 App() 内的函数中调用 getApp() ,使用 this 就可以拿到app 实例。
· 不要在onLaunch 的时候调用 getCurrentPages(),此时page 还没有生成
13: 关于:before ::before 和:after ::after的使用
::before用法:view::before,表示在该view组件的前面加入内容 ::after用法:view::after,表示在该view组件的后面加入内容 这里是双冒号,不是单冒号。单冒号是CSS2的内容,双冒号是CSS3的内容。当然微信小程序也是兼容CSS2的写法的
用法
wxml
{{price}}
wxss
.container {
width: auto;
margin: 30rpx;
background-color: #fff;
text-align: center;
}
.price {
position: relative;
display: inline-block;
font-size: 78rpx;
color: red;
}
.price::before {
content: "金额:¥";
position: absolute;
font-size: 40rpx;
top: 30rpx;
left: -160rpx;
color: black;
}
.price::after {
content: ".00 元";
font-size: 30rpx;
top: 40rpx;
position: absolute;
right: -90rpx;
color: black;
}
js
Page({
onLoad: function() {
this.setData({
price: 100
})
})
})
14.tips:
如果在app.wxss文件里有样式.styleA{…},那么这个样式A就是一个全局的样式,在其他页面B的wxss样式里,如果有同名的样式styleA,那么在B的样式里会拥有app.wxss文件样式styleA的全部设置。需要注意。
15.修改一个页面默认背景颜色
直接在该页面的page.wxss文件里设置page{background-color:red;},
.banner_container{
width:10vw;
height:230vw;
background-color:#13b5f5
}
page{background-color:red}
16.padding ****就是内边距
padding: 5px; 带一个参数,表示上下左右都是5px距离
padding: 5px 0; 带两个参数,表示什么呢?表示上下都是5px,左右都是0px,就是这里容易出错,切记切记!
padding: 5px 4px 3px 2px; 带四个参数,表示上5px,右4px,下3px,左2px
17.text文本中使用空格符
必须设置属性decode="{{true}}",然后在需要使用的地方加
{{'申请时间 '+item.applyTime}}
18:设置一个椭圆形按钮
自带的button设置高度一般的圆角显示会有问题,设置view可以解决想要一个椭圆形按钮的问题
.rejectBtn{
display: flex;
border: 0.2rpx solid #e4e4e4;
width: 150rpx;
height: 64rpx;
line-height: 32px;
border-radius: 32px;
text-align: center;
justify-content: center;
align-items: center;
font-size: 29rpx;
margin-right: 21rpx;
color: #666666;
}
19.需求:当用户名和密码都输入的情况下登录按钮才显示可点击,不然是灰色的
登录
20.关于js中的扩展运算符… 的使用
作用:将一个数组转为用逗号分隔的参数序列
- 函数调用
l function add(x, y) {
return x + y;
}
var numbers = [4, 38];
add(...numbers) // 42
2.通过push函数,将一个数组添加到另一个数组的尾部
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);
3.合并数组
var moreArr = [‘3’];
ES5写法:[‘1’,‘2’].concat(moreArr)
ES6写法:[‘1’,‘2’,...moreArr];
4.扩展运算符将字符串转为真正的数组
[...'hello'] => [“h”,”e”,”l”,”l”,”o”]
21.路由
1.wx.switchTab(Object object): 跳转到tabBar 页面,并关闭其他所有非tabBar 页面
url:需要跳转的tabBar 页面的路径(需在app.json 的 tabBar 字段定义的页面),路径后不能带参数。
success : function 接口调用成功的回调函数
fail : function 接口调用失败的回调函数
complete : function 接口调用结束的回调函数(调用成功、失败都会执行)
2wx.reLaunch(Object object) : 关闭所有页面,打开到应用内的某个页面
url:需要跳转的应用内页面路径,路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如'path?key=value&key2=value2
success : function 接口调用成功的回调函数
fail : function 接口调用失败的回调函数
complete : function 接口调用结束的回调函数(调用成功、失败都会执行)
3.wx.redirectTo(Object object):关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到tabbar 页面
url:同2
success : function 接口调用成功的回调函数
fail : function 接口调用失败的回调函数
complete : function 接口调用结束的回调函数(调用成功、失败都会执行)
4.wx.navigateTo(Object object) :保留当前页面,跳转到应用内的某个页面。但是不能跳到tabbar 页面。使用 wx.navigateBack 可以返回到原页面。小程序中页面栈最多十层。
url:同2
success : function 接口调用成功的回调函数
fail : function 接口调用失败的回调函数
complete : function 接口调用结束的回调函数(调用成功、失败都会执行)
5.wx.navigateBack(Object object) :关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages 获取当前的页面栈,决定需要返回几层。
参数
delta :number ,返回的页面数,如果delta 大于现有页面数,则返回到首页。
success : function 接口调用成功的回调函数
fail : function 接口调用失败的回调函数
complete : function 接口调用结束的回调函数(调用成功、失败都会执行)
eg:
wx.navigateBack({ delta: 2})
Note:getCurrentPages()
获取当前页面栈。数组中第一个元素为首页,最后一个元素为当前页面。
· 不要尝试修改页面栈,会导致路由以及页面状态错误。
不要在 App.onLaunch 的时候调用 getCurrentPages(),此时 page 还没有生成。
let pages = getCurrentPages(); //当前页面栈集合
使用场景:
- 获取当前页面相关信息
l 获取方式一
let pages = getCurrentPages();
let cutentPage = pages[pages.length - 1];
l 获取方式二
注:pop()方法用于删除并返回数组的最后一个元素
let pages = getCurrentPages();
let cutentPage = pages.pop();
2.跨页面赋值
let pages = getCurrentPages();
let prevPage = pages[pages.length - 2]; //上个页面
prevPage.setData({
//直接给上个页面赋值
})
3.页面跳转后自动刷新
wx.switchTab({
url: '../index/index',
success: function (e) {
var page = getCurrentPages().pop(); //当前页面
if (page == undefined || page == null) return;
page.onLoad(); //或者其它操作
}
})
22.注意点:
1.
2.wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
- 有时,组件希望接受外部传入的样式类。此时可以在 Component 中用 externalClasses 定义段定义若干个外部样式类。
/* 组件custom-component.js */
Component({
externalClasses: ['my-class']
})
- flex布局
flex-shrink属性
当项目在主轴方向上溢出时,通过设置项目收缩因子来压缩项目适应容器。属性值为项目的收缩因子,属性值取非负数,默认1
flex-grow属性
当项目在主轴方向上还有剩余空间时,通过设置项目扩张因子进行剩余空间的分配。属性值为项目的扩张因子,属性值取非负数。默认0
align-self属性
设置项目在行中交叉轴方向上的对齐方式,用于覆盖容器的align-items,这么做可以对项目的对齐方式做特殊处理。默认属性值为auto,继承容器的align-items值,当容器没有设置align-items时,属性值为stretch。
23:模板(template)
WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。
a. 定义模板
{{index}}: {{msg}}
Time: {{time}}
b. 使用模板
使用is 属性,声明需要的使用的模板,然后将模板所需要的data 传入,
Page({ data: {
item: {
index: 0,
msg: 'this is a template',
time: '2016-09-15'
} } })
note: is 属性可以使用Mustache 语法,来动态决定具体需要渲染哪个模板:
odd
even
24.引用
WXML提供两种文件引用方式import和include
- import
import可以在该文件中使用目标文件定义的template,如:
在item.wxml 中定义了一个叫item的template:
{{text}}
在index.wxml 中引用了item.wxml,就可以使用item模板:
注:import 的作用域
import 有作用域的概念,即只会import 目标文件中定义的template,而不会import 目标文件import 的template。
如:C import B,B import A,在C中可以使用B定义的template,在B中可以使用A定义的template,但是C不能使用A定义的template。
- include
include 可以将目标文件除了外的整个代码引入,相当于是拷贝到 include 位置,
25.关于WXS文件
wxs是专门用于wxml页面的,主要在视图层调用函数
wxs和js不能互相直接调用,有的事情,用wxs和js都能实现,但是你会发现用wxs****更方便、直接。
(链接:https://www.jianshu.com/p/bb0892e07d6f)
26.获取用户信息
使用wx.getUserInfo 接口直接弹出授权框的开发方式将逐步不再支持。从2018年4月30日开始,小程序与小游戏的体验版、开发版调用wx.getUserInfo 接口,将无法弹出授权询问框,默认调用失败。正式版暂不受影响。开发者可使用以下方式获取或展示用户信息:
1、使用button 组件,并将open-type 指定为getUserInfo 类型,获取用户基本信息
onGotUserInfo: function(e) {
console.log(e.detail.errMsg)
console.log(e.detail.userInfo)
console.log(e.detail.rawData)
},
2.使用open-data 展示用户基本信息
.userinfo{
position:relative;
width:750rpx;
height:320rpx;
color:white;
display:flex;
flex-direction:column;
align-items:center;
background-color:gray
}
.userinfo-avatar{
overflow:hidden;
display:block;
width:160rpx;
height:160rpx;
margin:20rpx;
margin-top:50rpx;
border-radius:50%;
border:2pxsolid#fff;
}
27.微信小程序自定义组件Component的使用
参见(https://blog.csdn.net/qq_17470165/article/details/81211923)必看
28.小程序中that和this用法
微信小程序中,在wx.request({});方法调用成功或者失败之后,有时候会需要获取页面初始化数据data的情况,这个时候,如果使用,this.data来获取,会出现获取不到的情况,调试页面也会报undefiend。原因是,在javascript中,this代表着当前对象,会随着程序的执行过程中的上下文改变,在wx.request({});方法的回调函数中,对象已经发生改变,所以已经不是wx.request({});方法对象了,data属性也不存在了。
官方的解决办法是,复制一份当前的对象,如下:
- 方式一:
var that=this;//把this对象复制到临时变量that
在success回调函数中使用that.data就能获取到数据了。
loadData: function() {
wx.request({
var that=this;
url: 'test.php',
data: {a: 'a', b: 'b'},
header: { 'content-type': 'application/json'},
success(res) {
that.setData({ toastHidden: false}) },
}) }
- 方式二
还有另外一种方式,也很特别,是将success回调函数换一种声明方式,(使用箭头函数) 如下:
loadData: function() {
wx.request({
url: 'test.php',
data: {a: 'a', b: 'b'},
header: { 'content-type': 'application/json'},
success:(res) => {
this.setData({ toastHidden: false}) },
}) }
29.关于占位符${}的用法
1.占位符就如同一个普通字符串一样,可以插入到字符串中的任意位置。
通常将两个字符串拼接我们会使用+
例如
1.
letaddress="青岛市南区";
letstr="蚂蚁部落位于"+address+",网址是www.softwhy.com"
如果使用${}可以的到相同的效果
letstr=`蚂蚁部落位于${address},网址是www.softwhy.com`;
2.letfunc=(url)=>{
returnurl;
}
letstr = `本站的url地址是${func("www.softwhy.com")}`;
console.log(str);
结果:本站的url地址是[www.softwhy.com](http://www.softwhy.com/)
3.letarr = ["蚂", "蚁", "部", "落"];
letstr = `${arr}`;
console.log(str);
结果:蚂,蚁,部,落
注:占位符中是数组,但是这个数组所处的上下文环境是字符串。
那么就隐身调用toString方法将其转换为字符串。
30.async-await 的使用
Async - 定义异步函数(async function someName(){...})
- 自动把函数转换为Promise
- 当调用异步函数时,函数返回值会被resolve 处理
- 异步函数内部可以使用await
Await - 暂停异步函数的执行(var result = await someAsyncCall();) - 当使用在Promise 前面时,await 等待Promise 完成,并返回Promise 的结果
- await 只能和Promise 一起使用,不能和callback 一起使用
- await 只能用在async 函数中
更多参加链接:https://www.jianshu.com/p/e622dee9de99
eg:
asyncgetPhoneNumber({ detail }) {
if(detail.iv && detail.encryptedData) {
this.setData({ loading: false, loginLoading: true});
try{
const{ result } = awaitwx.cloud.callFunction({
name: 'index',
data: {
code: this.noPageData.code,
iv: detail.iv,
encryptedData: detail.encryptedData,
secret: app.globalData.secret
}
});
if(result.purePhoneNumber) {
}
} catch(error) {
}
} else{
}
},
31做一个左右可切换的功能
test.js
Page({
data: {
swiperTitles:['待分配','已分配'],
swiperCurrent: 0,
animationData: null
},
switchSwiper ({ detail }) {
this.animationData(this, detail.current);
},
changeSwiper (e) {
this.animationData(this, e.currentTarget.dataset.current);
},
animationData (that, index) {
constanimation = wx.createAnimation({
duration: 400,
timingFunction: 'linear'
});
animation.translateX(`${index * 100}%`).step();
that.setData({
animationData: animation.export(),
swiperCurrent: index
});
},})
test.wxml
{{swiperTitles[0]}}
{{swiperTitles[1]}}
text.wxss
.orders{
height:100%;
overflow-y:hidden;
background-color:yellow
}
.nav-tab-box{
height:88.88rpx;
background-color:#ffffff;
}
.nav-tab{
display:flex;
flex-direction:row;
align-items:center;
height:85rpx;
font-size:27.75rpx;
color:#8badc8;
}
.nav-tab-text{
text-align:center;
flex-grow:1;
}
.nav-tab-underline{
width:750rpx;
height:4rpx;
}
.nav-tab-underline> .border-line{
height:inherit;
width:375rpx;
background-color:#03a9f4;
}
.nav-tab-active{
color:#03a9f4;
}
.swiper-box{
height:100vh;
}