Skip to content

关于组件

小程序中的页面都是由组件构成,所谓组件,就类似于HTML中的标签,所以我们学习组件时,可以和HTML标签对比着来学习。

常用组件

text == span

view == div

image

icon

导航标签(跳转)

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(){}

})

事件