Skip to content

WX语法

WXSS

https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html

页面样式的三种写法:

  • 行内样式、页面样式、全局样式
  • 三种样式都可以作用于页面的组件

优先级依次是:行内样式 > 页面样式 > 全局样式

image-20231007094310232

选择器

image-20231007094452141

尺寸单位

  • rpx(responsive pixel): 可以根据屏幕宽度进行自适应,规定屏幕宽为 750rpx
  • 如在 iPhone6 上,屏幕宽度为 375px,共有 750 个物理像素,则 750rpx = 375px = 750 物理像素,1rpx = 0.5px = 1 物理像素

image-20231007094810757

移动端适配方案

  1. rem,需要设置 html 的 font-size ,再计算出对应宽度
  2. vw,相对屏幕的宽度
html
<view class="item">rpx使用</view>
<style>
.item {
  font-size: 32rpx;
  width: 200rpx;
  height: 200rpx;
  background-color: #f00;
}
</style>

WXML

https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/

Mustache

WXML 基本格式:

  • 类似于 HTML 代码:比如可以写成单标签,也可以写成双标签
  • 必须有严格的闭合:没有闭合会导致编译错误
  • 大小写敏感:class 和 Class 是不同的属性

开发中, 界面上展示的数据并不是写死的, 而是会根据服务器返回的数据,或者用户的操作来进行改变.

  • 如果使用原生 JS 或者 jQuery 的话, 我们需要通过操作 DOM 来进行界面的更新
  • 小程序和 Vue 一样, 提供了插值语法: Mustache 语法(双大括号)

image-20231007103543079

逻辑判断

wx:if – wx:elif – wx:else

image-20231007104058707

hidden属性

  • hidden 是所有的组件都默认拥有的属性
  • 当 hidden 属性为 true 时, 组件会被隐藏
  • 当 hidden 属性为 false 时, 组件会显示出来

image-20231007104331319

hidden 和 wx:if 的区别

  • hidden 控制隐藏和显示是控制是否添加 hidden 属性
  • wx:if 是控制组件是否渲染的

image-20231007105238356

列表渲染

在组件中,我们可以使用 wx:for 来遍历一个数组 (字符串 - 数字)

  • 默认情况下,遍历后在 wxml 中可以使用一个变量 index,保存的是当前遍历数据的下标值
  • 数组中对应某项的数据,使用变量名 item 获取
html
<!-- wx:for基本使用 -->
<view wx:for="{{books}}" wx:key="id">
  <!-- item: 每项内容, index: 每项索引 -->
  {{item.name}}-{{item.price}}
</view>
<!-- 遍历数字 -->
<view wx:for="{{10}}" wx:key="*this">{{ item }}</view>

<!-- 遍历字符串 -->
<view wx:for="coderwhy" wx:key="*this">{{ item }}</view>

默认情况下,item 和 index 的名字是固定的

  • 但是某些情况下,我们可能想使用其他名称
  • 或者当出现多层遍历时,名字会重复

这个时候,我们可以指定 item 和 index 的名称:

html
<block wx:for="{{books}}" wx:key="id" wx:for-item="book" wx:for-index="i">
  <view>{{ book.name }}-{{ book.price }}-{{ i }}</view>
</block>

我们看到,使用 wx:for 时,会报一个警告:

  • 这个提示告诉我们,可以添加一个key来提供性能

为什么需要这个 key 属性呢?

  • 这个其实和小程序内部也使用了虚拟DOM有关系(和 Vue、React 很相似)
  • 当某一层有很多相同的节点时,也就是列表节点时,我们希望插入、删除一个新的节点,可以更好的复用节点

wx:key 的值以两种形式提供

  • 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变
  • 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字

block标签

某些情况下,我们需要使用 wx:if 或 wx:for时,可能需要包裹一组组件标签

  • 我们希望对这一组组件标签进行整体的操作,这个时候怎么办呢?

<block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性

使用 block 有两个好处:

  1. 将需要进行遍历或者判断的内容进行包裹
  2. 将遍历和判断的属性放在 block 便签中,不影响普通属性的阅读,提高代码的可读性

WXS

https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/

WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构

  • 官方:WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致(不过基本一致)

为什么要设计 WXS 语言呢?

  • 在 WXML 中是不能直接调用 Page/Component 中定义的函数的
  • 但是某些情况, 我们可以希望使用函数来处理 WXML 中的数据(类似于 Vue 中的过滤器),这个时候就使用 WXS 了

如下写法在小程序中是不行的,但在 Vue 里是可以的

html
<view>{{ sayHello(price) }}</view>
<script>
Page({
  data: {
    price: 2232
  },
  formatPrice(price) {
    return "¥" + price
  },
})
</script>

WXS使用的限制和特点:

  • WXS 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行
  • WXS 的运行环境和其他 JavaScript 代码是隔离的,WXS 中不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序提供的 API
  • 由于运行环境的差异,在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。在 android 设备 上二者运行效率无差异

WXS有两种写法:

  • 写在 <wxs> 标签中
  • 写在以 .wxs 结尾的文件中

<wxs>标签

html
<wxs module="format">
  function formatPrice(price) {
    return '¥' + price
  }
  module.exports = {
    formatPrice: formatPrice
  }
</wxs>
<view class="books">
  <block wx:for="{{books}}" wx:key="id">
    <view>name:{{item.name}}-price:{{format.formatPrice(item.price)}}</view>
  </block>
</view>

.wxs 文件

注意:WXS 里不能使用 ES6 语法,比如:箭头函数、ES6对象增强写法

html
<wxs src="/utils/format.wxs" module="format"></wxs>

<!-- format.wxs -->
<script>
function formatPrice(price) {
  return '¥' + price
}
module.exports = {
  formatPrice: formatPrice
}
</script>

时间处理

html
<view class="time">
  {{format.formatTime(currentTime)}}/{{format.formatTime(duration)}}
</view>

<!-- format.wxs -->
<script>
function padLeft(time) {
  time = time + ''
  return ('00' + time).slice(time.length)
}
function formatTime(time) {
  var minute = Math.floor(time / 60)
  var second = Math.floor(time % 60)
  return padLeft(minute) + ': ' + padLeft(second)
}
module.exports = {
  formatTime: formatTime
}
</script>

常备不懈,才能有备无患