关于组件
小程序中的页面都是由组件构成,所谓组件,就类似于HTML中的标签,所以我们学习组件时,可以和HTML标签对比着来学习。
常用组件
text == span
view == div
image
icon
导航标签(跳转)
navigator
navigator组件类似于HTML中的a标签,用于微信各个页面间的跳转。
例如从index页面跳点击跳转链接跳转到logs页面。
xml
<!--index.wxml-->
<navigator url="/pages/logs/logs">跳转到logs页面</navigator>
通过微信api进行跳转
除了通过navigator组件进行跳转之外,还可以通过微信提供的api进行跳转。
javascript
<!--index.wxml-->
<navigator url="/pages/logs/logs">跳转到logs页面</navigator>
<view bindtap="clickMe">通过api进行跳转</view>
// index.js
Page({
clickMe(event) {
// 使用微信跳转的api进行跳转操作
wx.navigateTo({
// url: '/pages/logs/logs.wxml', // 注意路径不需要带最后的扩展名,也就是.wxml,否则不跳转
url: '/pages/logs/logs', // 正确的
})
}
})
样式选择器
列表渲染:for
https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/list.html
小程序的循环跟vue差不多,来看有几种套路。
首先在js的data中定义要循环的数组:
javascript
// index.js
Page({
data:{
userList: ["张开0", "张开1", "张开2"]
}
})
页面中这么用:
html
<!--index.wxml-->
<view>
<view>
简写形式的for循环
for循环中,如果按照如下简写形式,默认返回两个固定参数,索引index和元素item,只能叫做index和item,别的不支持
</view>
<view wx:for="{{userList}}">{{index}}--{{item}},叫别的名不行{{index1}}--{{item1}}</view>
</view>
<view>
<view>
当然了,也可以使用 wx:for-item 可以指定数组当前元素的变量名,使用 wx:for-index 可以指定数组当前下标的变量名:
</view>
<view wx:for="{{userList}}" wx:for-index="idx" wx:for-item="ele">{{idx}}--{{ele}}</view>
</view>
<view>
<view>
也可以加wx:key,当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
</view>
<view wx:for="{{userList}}" wx:key="index">{{index}}--{{item}}</view>
</view>
条件渲染:if
https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/conditional.html
wx:if
block wx:if
wx:if vs hidden
数据绑定
WXML 中的动态数据均来自对应 js文件中的Page 中的data。
来看看怎么玩的吧。
简单绑定
数据绑定使用 Mustache 语法(双大括号)将变量包起来,来看用法:
javascript
// index.js
Page({
data:{
userList: ["张开0", "张开1", "张开2"],
id: 1,
name: "张开",
x: 1,
y: 2,
z: 3,
obj: {k1:"v1"}
}
})
<!--index.wxml-->
<view>
<view>
<view>内容</view>
<text>{{name}}</text>
</view>
<view>
<view>组件属性(需要在双引号之内)</view>
<text id="{{id}}">{{id}}</text>
</view>
<view>
<view>控制属性(需要在双引号之内)</view>
<text wx:if="{{condition}}">{{id}}</text>
<text wx:if="{{id}}">{{id}}</text>
<text wx:if="{{id==1}}">{{id}}</text>
<text wx:if="{{id==0}}">{{id}}</text>
</view>
<view>
<view>关键字(需要在双引号之内)</view>
<checkbox value="1" checked="{{true}}" />
<checkbox value="1" checked="{{false}}" />
<!-- 特别注意:不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后代表真值 -->
<checkbox value="1" checked="false" />
</view>
<view>
<view>运算,可以在 {{}} 内进行简单的运算,支持的有如下几种方式</view>
<!-- 三元运算< -->
<view hidden="{{flag ? true : false}}"> Hidden </view>
<!-- 算数运算,view中的内容为 3 + 3 + d-->
<view>{{x + y}} + {{z}} + d</view>
<!-- 逻辑判断-->
<view wx:if="{{x >= 1}}">{{x}}</view>
<!-- 字符串运算-->
<view>{{name+name+"666"}}</view>
<!-- 数据路径运算-->
<view>{{obj.k1}}</view>
<view>{{userList[0]}}</view>
</view>
</view>
数据双向绑定
而且截止到目前为止(2023.4.1),我总觉得小程序的数据双向绑定不如vue的数据双向绑定用着顺手。
来看微信这边是如何设计的。
javascript
<!--index.wxml-->
<view>
<!-- 想要实现数据的双向绑定,要结合js来一起实现 -->
<view>{{name}}</view>
<!-- 绑定一个事件bindinput,当键盘输入时就触发该bindinput事件,将input框的值传给绑定的函数 -->
<input type="text" value="{{name}}" bindinput="clickMe"/>
</view>
// index.js
Page({
data:{
userList: ["张开0", "张开1", "张开2"],
name: "张开"
},
clickMe(event){
// 每次键盘输入,input框的值都被封装到了event参数中,当然,这个event你可以叫别的名字
// console.log(event);
// 拿到input框的value值
// console.log( event.detail.value);
// 接下来就要通过如下的形式完成赋值动作,实现类似于vue中的数据双向绑定的效果
// this代表当前组件对象,setData更新data中的某个值
this.setData({
name: event.detail.value
})
}
})
上面是页面和js相结合的形式实现类似于vue的数据双向绑定。
有没有更进一步的实现,有!虽然不那么完美吧:
javascript
<!--index.wxml-->
<view>
<!-- 想要实现数据的双向绑定,要结合js来一起实现 -->
<view>{{name}}</view>
<!-- 绑定一个事件bindinput,当键盘输入时就触发该bindinput事件,将input框的值传给绑定的函数 -->
<input type="text" value="{{name}}" bindinput="clickMe" />
<!-- 上面那种写法不通过js配合的话,无法直接实现双向绑定的机制 -->
<!-- 当然,为了能直接实现双向绑定效果,可以通过model声明来实现 -->
<!-- 不过如果不绑定一个事件的话,控制台会有warning提示 -->
<!-- WASubContext.js?t=wechat&s=1680422130844&v=2.19.4:2 Do not have clickMe2 handler in component: pages/index/index. Please make sure that clickMe2 handler has been defined in pages/index/index. -->
<!-- 加上一个事件之后,这个提示就没了,哪怕这个对应的事件啥都不写 -->
<input type="text" model:value="{{name}}" bindinput="clickMe2" />
</view>
// index.js
Page({
data:{
userList: ["张开0", "张开1", "张开2"],
name: "张开"
},
clickMe(event){
// 每次键盘输入,input框的值都被封装到了event参数中,当然,这个event你可以叫别的名字
// console.log(event);
// 拿到input框的value值
// console.log( event.detail.value);
// 接下来就要通过如下的形式完成赋值动作,实现类似于vue中的数据双向绑定的效果
// this代表当前组件对象,setData更新data中的某个值
this.setData({
name: event.detail.value
})
},
// 可以不实现内容,就是为了配合model:value="{{name}}"的方式,让控制台不输出warning提示
clickMe2(){}
})