小程序
2020-11-16 15:53:52

for循环

列表循环

1 wx:for=”“ wx:for-item=”循环项的名称” wx:for-index=”循环项的索引”

2 wx:key=”唯一的值”用来提高列表渲染的性能

​ 1 wx:key 绑定一个普通的字符串的时候,那么这个字符串名称肯定是循环数组中的对象的唯一属性

​ 2 wx:key=”*this” 表示这个数组是一个普通数组,”*this” 就是循环项.比如[1,2,3,52]

对象循环

1 wx:for=”“ wx:for-item=”对象的值” wx:for-index=”对象的属性”

数据双向绑定

例如需求为文本框中的内容发生改变,下面的view 中的数据也随之发生改变

首先在data中定义num=0之后编辑wxml文件

1
2
3
4
<input type="text" bindinput="handleInput"/>
<view>
{{num}}
</view>

其中bindinput作用是监听文本框发生改变,接下来在js文件中编写handleInput方法

1
2
3
4
5
handleInput(e){
this.setData({
num: e.detail.value
})
}

小程序中修改数据的语法为this.setData({ }).其中e中包含传入的文本框中的值

自定义组件

自定义组件的基本使用

在项目中新建components文件夹,在components文件夹下新建tabs文件夹,在tabs文件夹下新建components命名为Tabs,这样自定义组件就建好了

需要使用自定义组件的时候只需在响应界面的json中添加响应的组件和路径比如下面

1
2
3
4
5
{
"usingComponents": {
"Tabs":"../../components/tabs/Tabs"
}
}

接下来在页面的wxml文件中使用命名的组件作为标签即可,如

tabbar实例

接下来展示一个tabbar 的实例,实现结果如图

image-20210422135024938

首先在Tabs.js中定义tabbar的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
data: {
tabs:[
{
id:0,
title:"首页",
isActive:true
},
{
id:1,
title:"分类",
isActive:false
},
{
id:2,
title:"购物车",
isActive:false
},
{
id:3,
title:"我的",
isActive:false
}
]
}

接下来编辑wxml界面

1
2
3
4
5
6
7
8
<view class="tabs">
<view class="tabs-item">
<view wx:for="{{tabs}}" wx:key="id" class="title-item {{item.isActive?'active':''}}" bindtap="handleTap" data-index="{{index}}">
{{item.title}}
</view>
</view>
<view class="content">内容</view>
</view>

其中bindtap是用来绑定点击事件,data-index是需要传递给绑定事件的参数,当点击时可以在e中获取,详细请看下面的handleTap方法

1
2
3
4
5
6
7
8
9
10
methods: {
handleTap(e){
const index = e.currentTarget.dataset.index;
let tabs = this.data.tabs;
tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false)
this.setData({
tabs
})
}
}

接下来修改样式文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.tabs-item{
display: flex;
padding: 10rpx 0;
}

.title-item{
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}

.active{
color: red;
}

父向子传递数据

父组件(页面)向子组件(自定义组件)传递数据,需要通过标签属性进行传递

比如上面的tabbar实例,若其他界面也需要用到这个tabbar,但是样式不变,里面的每一项的标题需要改变.这样就可以将标题的数据存在父组件中,然后在子组件中进行接收

在父组件,即任意的page的js的data中定义tabs数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
data: {
msg:"这是页面二",
tabs:[
{
id:0,
title:"首页",
isActive:true
},
{
id:1,
title:"分类",
isActive:false
},
{
id:2,
title:"购物车",
isActive:false
},
{
id:3,
title:"我的",
isActive:false
}
]
}

再在本页面的wxml使用子组件的地方传出数据,使用标签,名称自定义

1
2
3
<view>
<Tabs tabs="{{tabs}}"></Tabs>
</view>

接下来在Tabs组件的js中接收数据.父向子传递数据,在子组件中的js文件的properties中接收

1
2
3
4
5
6
properties: {
tabs:{
type:Array,
value:""
}
}

这是tabs这组数据就可以当作Tabs组件自己的数据进行使用

子向父传递数据

进行如上的更改后看起来是没有问题,但是想一想,Tabs组件对点击事件进行处理,即改变数组中被点击的isActive的属性的时候,是将父组件传递的tabs数组当作自己的数据进行更改了.也就是说相当于Tabs组件复制了一份tabs数组对其进行操作,然而父组件中的源数据(也就是父组件中的tabs数组)并没有被更改.

这时需要在Tabs组件(也就是子组件)中向父组件(也就是page页面)传递一个被点击的页面的index参数,即子向父传递数据,从而在父组件中对源数据(也就是父组件中的tabs数组)进行更改.

子组件向父组件传递数据使用this.triggerEvent(“父组件自定义事件的名称”,要传递的参数).

所以更改Tabs组件的js中handleTap方法

1
2
3
4
5
6
7
8
9
10
11
methods: {
handleTap(e){
const index = e.currentTarget.dataset.index;
this.triggerEvent("itemChange",index);
let tabs = this.data.tabs;
tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false)
this.setData({
tabs
})
}
}

接下来需要回到父组件中,在父组件的标签上加入一个自定义事件

1
2
3
<view>
<Tabs tabs="{{tabs}}" binditemChange="handleItemChange"></Tabs>
</view>

binditemChange即”bind”拼接上this.triggerEvent(“itemChange”,index)传入的自定义事件名称.这样就可以在父组件的handleItemChange方法中处理Tabs传进来的数据了

在父组件的js中定义handleItemChange方法

1
2
3
4
5
handleItemChange(e){
const index = e.detail.index;
let tabs = this.data.tabs;
tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
}

这样下来就完成了子向父传递数据,并对父组件中的数组进行操作.

Prev
2020-11-16 15:53:52
Next