Skip to content

微信小程序基础与组件(三) ​

本页对应 微信小程序基础与组件,共 7 段视频,约 1 小时 5 分。

学习目标 ​

  • 能使用 input 组件配置 type、password、placeholder、maxlength、confirm-type 等属性,并说明 type 主要用于控制真机键盘类型。
  • 能使用 type="nickname" 实现微信昵称输入,并在基础库版本不满足时完成组件库版本切换后验证昵称获取效果。
  • 能使用 radio-group、radio、checkbox-group、checkbox 与 label 完成单选和多选表单,并通过 bindchange 事件对象 e.detail.value 获取选中值。
  • 能使用 picker 的 mode="region" 与 mode="date" 实现省市区和日期选择,配置 value、start、end,并通过 bindchange 更新 data 完成界面回显。
  • 能区分全局样式 app.wxss 与页面局部样式的优先级,能将全局样式或字体图标样式抽离后通过 @import 引入并验证生效。
  • 能说明 WXSS 中不能直接引入本地静态资源的限制,并使用网络图片、Base64 或在线字体图标方式完成样式资源引入。

知识点 ​

4.1 navigator:页面跳转 ​

为什么需要:小程序页面之间要跳转,navigator 就相当于网页里的 a 标签。怎么想:先判断目标页面是不是 tabBar 页面;普通页面用默认 navigate,tabBar 页面必须用 switchTab。怎么做:在 navigator 上设置 url,支持相对路径和绝对路径;用 hover-class 控制点击态,值设为 none 可禁用点击效果;用 open-type 指定跳转方式。易错点:url 为空会报错;tabBar 页面如果仍用默认 navigate 会跳不过去,要改成 switchTab。

4.2 image:图片占位与裁剪 ​

为什么需要:页面要显示图片,但小程序里组件名是 image,不是网页的 img。怎么想:image 本身是占位容器,默认有 320*240px 的宽高;当占位容器和图片实际宽高比不一致时,图片可能显示不正常,所以要理解 mode。怎么做:按设计稿设置 image 宽高;需要拉伸铺满用 scaleToFill,需要长边完整显示用 aspectFit(可能留白),需要短边完整显示用 aspectFill(可能裁切)。一般图片比例和容器不一致时,指定 mode="aspectFill"。易错点:把 image 写成 img;只放图片不设宽高,或误以为 aspectFit 一定铺满。

4.3 swiper:轮播容器 ​

为什么需要:轮播图需要可滑动区块,swiper 就是专门做这个的。怎么想:它由容器和滑块单元组成,结构不能乱。怎么做:swiper 内部只能嵌套 swiper-item,swiper-item 内部再放任意内容,比如 image;常用属性有 indicator-dots 显示指示点、autoplay 自动切换、circular 衔接滑动。易错点:swiper 默认高度为 150px,不设高度可能显示不理想;不要在 swiper 里直接塞 image,应放在 swiper-item 里。

4.4 表单相关:input、单选、复选与 picker ​

为什么需要:移动端登记信息离不开输入、单选、复选、地区和时间选择。怎么想:小程序表单组件名称和网页相似,但属性和事件有差异,不能完全凭网页经验写。怎么做:input 用 type 指定输入类型,placeholder 设占位文字,password 设密码类型,maxlength 控制最大长度,confirm-type 可改键盘右下角按钮文字;type="nickname" 是微信生态里的昵称输入键盘,转写中在模拟器里没反应,是因为基础库版本不够,需在“详情→本地设置”里把调试基础库切到更高版本(如 3.x),之后底部会出现微信昵称。radio-group 包 radio 实现单选,checkbox-group 包 checkbox 实现多选,value 是提交数据,checked 是选中状态;用 bindchange 取 e.detail.value,单选得到一个值,多选得到数组。picker 用 mode 指定类型,region 是省市区三级联动,date 是日期选择;picker 内部要先写文字,否则高度可能为 0 点不到;选完后要通过 bindchange 拿 e.detail.value 并 setData 更新显示。日期选择器可用 start、end 限定范围,格式为 YYYY-MM-DD,end 常动态生成;value 可用于回显。易错点:单选不能靠相同 name 编组,必须用 radio-group;label 包住选项可扩大点击区域;picker 选完不更新数据,页面仍显示“请选择”。

css
/* 提前准备的样式代码 */
page {
  padding: 40rpx 0;
  box-sizing: border-box;
  background-color: #f7f8fa;
}
.legend {
  padding-left: 40rpx;
  font-size: 36rpx;
  color: #333;
  font-weight: 500;
}
.form-field {
  display: flex;
  margin-top: 20rpx;
  padding: 0 40rpx;
  height: 88rpx;
  background-color: #fff;
  line-height: 88rpx;
  color: #333;
}
.form-field label {
  width: 120rpx;
}
.form-field .field {
  flex: 1;
}
.form-field input {
  height: 100%;
}
xml
<!-- 提前准备好的布局结构代码 -->
<view class="register">
  <view class="legend">信息登记:</view>
  <view class="form-field">
    <label for="">姓名:</label>
    <view class="field">...</view>
  </view>
  <view class="form-field">
    <label for="">性别:</label>
    <view class="field">...</view>
  </view>
  <view class="form-field">
    <label for="">爱好:</label>
    <view class="field">...</view>
  </view>
  <view class="form-field">
    <label for="">籍贯:</label>
    <view class="field">...</view>
  </view>
  <view class="form-field">
    <label for="">生日:</label>
    <view class="field">...</view>
  </view>
</view>

4.5 scroll-view:可滚动区域 ​

为什么需要:内容超出区域时要能滚动,scroll-view 还能支持下拉刷新等交互。怎么想:它内部嵌套需要滚动的内容,但必须产生溢出;垂直滚动时一定要给 scroll-view 指定高度。怎么做:用 scroll-x 控制水平滚动,用 scroll-y 控制垂直滚动,用 refresher-enable 开启下拉刷新。易错点:没高度、没溢出时不会滚动;把滚动内容放错层级也会失效。

css
/* 提前准备的样式代码 */
page {
  background-color: #f2f2f2;
}
.search-bar {
  padding: 20rpx 30rpx;
  background-color:#fff;
}
.search-bar input {
  padding: 14rpx 20rpx 10rpx 40rpx;
  border: 1rpx solid #eee;
  border-radius: 70rpx;
  font-size: 28rpx;
  color: #333;
}
.page-body {
  height: 700rpx;
  display: flex;
  margin-top: 20rpx;
}
.page-body .aside {
  width: 200rpx;
  padding: 20rpx;
  background-color: #fff;
}
.page-body .aside .item {
  height: 60rpx;
  margin-bottom: 20rpx;
  border-radius: 10rpx;
  background-color: #eee
}
.page-body .aside .active {
  background-color: pink;
}
.page-body .content {
  flex: 1;
  padding: 20rpx;
  margin-left: 20rpx;
  background-color: #fff;
}
.page-body .content .item {
  float: left;
  width: 215rpx;
  height: 215rpx;
  margin: 0 20rpx 20rpx 0;
  border-radius: 10rpx;
  background-color: #eee;
}
.page-body .content .item:nth-child(even) {
  margin-right: 0;
}
xml
<!-- 提前准备好的布局结构代码 -->
<!-- 搜索框 -->
<view class="search-bar">
  <input type="text" placeholder="输入搜索关键字" />
</view>
<!-- 页面主体 -->
<view class="page-body">
  <view class="aside">
    <view class="item"></view>
    <view class="item"></view>
    <view class="item"></view>
  </view>
  <view class="content">
    <view class="item"></view>
    <view class="item"></view>
    <view class="item"></view>
  </view>
</view>

全局样式:先定公共规则,再让页面覆盖 ​

为什么需要
小程序页面很多,如果每个页面都重复写文字颜色、背景、字体图标等公共样式,维护成本高。app.wxss 就是全局样式文件,写在这里的样式会对所有页面生效。

怎么想
先区分“全局”和“局部”:全局样式放在固定的 app.wxss 中;页面自己的 .wxss 是局部样式。页面中还有一个由小程序自动添加的 page 节点,可以把它理解成网页里的 body,所以给 page 写背景、文字颜色,会影响页面整体。

怎么做
在 app.wxss 中写:

css
page {
  background-color: pink;
  color: red;
}

转写稿里的调试过程是:写完全局样式后切到首页,发现文字颜色变了;再切到另一个页面,发现没有变,原因是那个页面内部已经写过局部样式。由此可确认:局部样式存在时优先局部,局部没有覆盖时才读取全局样式。切换页面时可用开发者工具里的“普通编译”快速切路由,类似网页改地址栏。

易错点
app.wxss 文件名固定,不能随意改名;不要以为全局样式一定压过页面样式,局部样式会覆盖它;全局样式适合做初始化、公共变量式规则和字体图标引入,不适合把所有页面细节都堆进去。

静态资源:WXSS 不允许本地路径,改用网络地址或 base64 ​

为什么需要
网页里常写 background-image: url(./images/search.png),但小程序为了控制包体和首次加载速度,对 WXSS 中的静态资源有限制:不能直接使用本地图片路径。

怎么想
先判断资源用在哪里:如果是在 .wxss 里做背景图,就必须用网络路径(https:// 或 http:// 开头)或 base64;如果是 <image> 组件,本地图片仍可使用。搜索放大镜这类小图标,也可以优先考虑字体图标。

怎么做
笔记中的示例是把本地路径注释掉,换成网络图片,并用 background-size: contain 控制显示:

css
/* 使用背景图定义放大镜 */
.search-bar .button {
  position: absolute;
  top: 50%;
  right: 60rpx;
  width: 50rpx;
  height: 50rpx;
  transform: translateY(-50%);
  /* background-color: pink; */

  /* 背景图片 */
  /* background-image: url(/static/images/search.png); */
  background-image: url(https://lotjol.github.io/static-store/enjoy-plus/images/search.png);
  background-size: contain;
}

转写稿中的调试过程:先写本地背景图,路径看起来正确但不生效,工具提示“本地资源图片无法通过 WXSS 获取”;换成网络图后正常显示,再补 background-size 让图片占满容器。

易错点
不要把网页经验直接搬过来;本地图片在 WXSS 中报错不是路径写错,而是平台限制;网络图要确保可访问;base64 可用但一般由工具转换,不必手写。

字体图标:用 iconfont 在线链接,不要下载到本地 ​

为什么需要
字体图标比图片更清晰、颜色可控,也适合多个页面复用。但小程序 WXSS 同样不支持本地字体文件,所以不能像网页那样随便下载字体后本地引用。

怎么想
把字体图标当作“全局资源”:在 iconfont 平台把图标加入项目,生成在线链接,把 @font-face 和图标类名复制到样式文件中。因为多个页面都要用,通常放到 app.wxss,或抽到独立文件再 @import 引入。

怎么做
笔记保留的代码如下,核心是 @font-face 中使用在线地址或 base64,再通过 .iconfont 和具体类名显示图标:

css
@font-face {
  font-family: "iconfont"; /* Project id 3632516 */
  src: 
       url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAATYAAsAAAAACVwAAASMAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFQGYACDIgqFfIUjATYCJAMUCwwABCAFhGcHRxs0CFGU7k2N7Mdg204e4YSRdMLR9eNemN8PCiyrdGcE0VpZPQtPxIpIv8IQqHchGxsFLsrGxhhAx0bc/7WZn5C0kYUVY0mFNZOTCiVD4qRkau43dTv25XLOxDa2INyuQk54Qj83jTax/7Y8D8SS8H/u9+pPS9C6v8Itu+yBfdEPtOgA2YB35nOfim6k2DXM5CkCtZYVUBxV1DUCfc1jB7CUtOUgbI9rs5EHteyQl7SHaqGse2QO8QZUpFeKq8Br9+fjv5RQg6TIQDvP6eNyA5x8P+b9Q3K8m4PsG3tJwNYJBTLMz8wV98sDN5F+YR6pNk9SaRko5frUa8ztxsXcVzBTOWd/LsM/L0rQDPXA7+nz3VKafIJf9xV5xgewyWB8iKKE82mlFnUXxXkCGmHcHZJMLg35UwFUjBflFd1vxEL6xJ9OSP90CjR+KLzpuzGbFThHUktQW+ZlIdsrWv7QI/S8whctg46TLcOWVYTXrKYrK1xsOrytY0NuNKqWpbXYGi9ajMIGr0se0MwjabII6NAkMH6x5AUWJYTNdDSzTAk4/vv/2azv84s17vqzNoNPi6QR56SANi9l7TMve37qijdO4vQth3ab81kSDQaB8UvYqAktbBAFb6/n6YnltktVYnQe8t51ouQN5okt2t28tNJCpcl06pIWPh9i8XZo9iNTz2bOXC/FsWPr4keXGVJbkhoak5tTLjWnOuzJjSktl1KarY1J0TMbSj/siz52bPqA4Wbtm5eNlTHlUVHl0ZXbDSlJA29l9HaSp1AxuJjvFgPu5wzQM/qh9n5U1PSp7DSousf+up18OnRA8gDCL7Fpwo64weSRwr4xu5mm2otUCDWO9tF70+OoYHB8JIjpXxExR31Y/bT6iFpn6p6Gd51DTPsKfOAc4baukuywEr2PvjgsOrRa8/l/6RdCKw6/BcQLZ3A/ImRBUHnQgnJhnbjz6p1qSb1Lvc7USeH7wMZbCx2iD6EphvXewFQwG7xZJoL7J3EMHcKG0EyAW40AumKtmPC2nhmaYP2MOUuc9/ChN0aXxUTWxJ32CGaDqdM72UY+LxeGA1TOk4fJUJH6glxPcvT35AqSDa0ig76uv7H57l9qj2feP3WdEuDnrSsk4pXzSmjvUn2hA8G3ZOysiZgzGRnzvFnTJzCn80iNhFo9TQW0SKvn/ZjaaucI1TGlBEmVPshUG0Xn+Fko1FmFUrVtqDWn/Pg6bZxIkWuASZM4CM12QNLoPWSaXUDn+AdQ6PQBSs3+Q62zoM5WZzKEUhnxGBm4QSM4syA5RMOM3VXrkXGIjZezss1IdpmR5pITkpLlSuRAchf7uIYaUzAWOVGW7FyFeD1ks0mcU5YsSMAJJoydOYmJYt6nJAiSHUrJEB6GGHAGGYFjJpA4iDYyjv++eojREDY8uSa62Sdz8XJanZMsQVINdKXBUWvuTNZ3GcooBYaJ/HYimcSOU8F8iE0vSDjO/M0sEAGWwNQi55QjkZDEuoaE8U32C6z8kRdqZy9CQZCEklARfaB8gnhZMCmRwYxV7kZIsKpcJl5GAA==') format('woff2'),
       url('//at.alicdn.com/t/c/font_3632516_qjs869axt0h.woff?t=1672223363723') format('woff'),
       url('//at.alicdn.com/t/c/font_3632516_qjs869axt0h.ttf?t=1672223363723') format('truetype');
}
.iconfont {
  font-family: "iconfont" !important;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.icon-search:before {
  content: "\e67d";
}
.icon-edit:before {
  content: "\e6d8";
}
.icon-check:before {
  content: "\e6d7";
}
.icon-share:before {
  content: "\e6d6";
}

使用时写两个类名,例如 class="iconfont icon-search"。转写稿还演示了抽离:新建 styles/iconfont.wxss,在 app.wxss 中用 @import "./styles/iconfont.wxss"; 引入。若项目要用两套 iconfont,必须改 font-family 名称,避免重名。

易错点
不要下载字体到本地后直接引用;不要只写 icon-search 而漏掉 iconfont;多个 iconfont 项目不能都用同一个 font-family;@import 路径按项目实际结构调整,不要写成绝对盘符路径。

课件图示 ​

课件第4页:多⼀句没有,少⼀句不⾏,用更短时间,教会更实用的技术! ⾼级软件⼈才培训专家 小

课件第6页:多⼀句没有,少⼀句不⾏,用更短时间,教会更实用的技术! ⾼级软件⼈才培训专家 小

课件第7页:多⼀句没有,少⼀句不⾏,用更短时间,教会更实用的技术! ⾼级软件⼈才培训专家 小

课件第10页:多⼀句没有,少⼀句不⾏,用更短时间,教会更实用的技术! ⾼级软件⼈才培训专家 注

课件第15页:多⼀句没有,少⼀句不⾏,用更短时间,教会更实用的技术! ⾼级软件⼈才培训专家 搭

课件第16页:多⼀句没有,少⼀句不⾏,用更短时间,教会更实用的技术! ⾼级软件⼈才培训专家 搭

课件第19页:多⼀句没有,少⼀句不⾏,用更短时间,教会更实用的技术! ⾼级软件⼈才培训专家 总

课件第21页:多⼀句没有,少⼀句不⾏,用更短时间,教会更实用的技术! ⾼级软件⼈才培训专家 本

代码示例 ​

常见错误 ​

1. tabBar 页面点击 navigator 毫无反应 现象:<navigator url="/pages/index/index"> 点击后页面不动,控制台也无明显报错。 原因:目标页在 app.json 的 tabBar 中注册过,默认的 open-type="navigate" 无法跳转 tabBar 页面。 修法:改为 <navigator url="/pages/index/index" open-type="switchTab">;同时排查 url 是否漏写或写成空字符串(空路径会直接报错)。

2. 轮播图/图片被拉伸变形或只露出一部分 现象:设计稿 750×400 的图放进 image 后,人脸被压扁;或上下被裁掉一截。 原因:image 是占位容器(默认 320×240),未显式设宽高或宽高比与图片实际比例不一致,默认 scaleToFill 会强行拉伸。 修法:按设计稿给 image 显式设宽高,并加 mode="aspectFill"(要求铺满不留白)或 mode="aspectFit"(要求完整显示)。

3. 单选/多选"全都能选",或选完拿不到值 现象:性别两项同时高亮;或在 bindchange 里 e.detail.value 为 undefined。 原因:① 漏了外层 radio-group / checkbox-group 编组,小程序不像网页端靠 name 分组;② 忘了给 radio/checkbox 本身写 value。 修法:用 radio-group(checkbox-group)包裹并绑定 bindchange,每个子项补齐 value,取值统一走 e.detail.value(多选是数组)。

4. 选择器 picker 点不动 / 选完文字不变 现象:写了 <picker mode="region"></picker>,页面上那一行根本点不到;或能选但界面一直显示"请选择"。 原因:picker 内部没有内容时高度为 0,不可点击;且选中结果不会自动回填,必须自己接管。 修法:内部先放一段占位文字保证可点;再绑定 bindchange,在回调里 this.setData({ region: e.detail.value.join(' ') }),模板中用 &#123;&#123;region || '请选择省市区'&#125;&#125; 兜底。

5. 背景图/字体图标写了本地路径不生效 现象:background-image: url(/static/images/search.png) 编译直接报"本地资源图片无法通过 WXSS 获取";iconfont 下载到本地引入同样报错。 原因:小程序对 WXSS 中的静态资源有限制,只认网络地址或 base64(image 组件的 src 不受此限)。 修法:图片换成 https 网络地址(或转 base64);字体图标改用 iconfont 项目生成的在线 @font-face 链接,app.wxss 里 @import 引入。

6. 换页后全局样式"失效" 现象:app.wxss 里给 page 设了背景色,有的页面生效、有的页面没变。 原因:页面自身 wxss 里有同名同权重的样式覆盖了全局样式,并非全局没生效。 修法:确认页面级样式是否重复定义;需要覆盖时注意选择器权重,不要靠"再写一遍全局"来解决。

7. 数据改了但界面不动 现象:this.data.xxx = ... 后视图毫无变化;或模板里 &#123;&#123;endDate&#125;&#125; 直接渲染不出来。 原因:小程序不会监听 this.data 的直接赋值;且模板中未在 data 里声明的变量不会被响应式渲染。 修法:一律用 this.setData({ xxx: value }),并保证所有参与渲染的变量都在 data 中先声明初始值。

8. 基础库版本过低导致新能力不生效 现象:<input type="nickname"> 在模拟器里毫无反应,也不弹昵称面板。 原因:项目默认基础库(如 2.19.4)低于该特性要求的最低版本。 修法:详情 → 本地设置 → 调试基础库,选择用户占比高的较新版本(如 3.x),重新编译;真机验证键盘类特性(type、confirm-type)必须在手机上测。

练习 ​

练习 1|导航与图片 在首页放三张"活动入口"卡片:第一张跳普通详情页,第二张跳 tabBar 中的"我的"页,第三张跳外部 H5(open-type="navigate" 不行,查文档确认正确取值)。每张卡片内嵌 200×120 的 image,使用网络图片且保证不变形。要求:点击卡片有自定义点击态,长按不出现默认效果。

练习 2|轮播图 用 swiper 做一个 3 张图的轮播:自动播放、循环衔接、显示指示点、不允许用户手动滑动。高度设为 320rpx,图片铺满且不拉伸变形。思考并验证:如果把 swiper 的高度去掉会发生什么?

练习 3|信息登记表单 用笔记里准备好的结构与样式,完成"姓名 / 性别 / 爱好 / 籍贯 / 生日"五项:

  • 姓名:最多 10 个字,输入框为空时显示占位文字
  • 性别:默认选中"女",切换时把值打印到控制台并回显到页面
  • 爱好:多选,把选中的数组用 、 拼接后展示在页面下方
  • 籍贯:region 选择器,选完回填文字,未选时显示"请选择省市区"
  • 生日:date 选择器,起始 1900-01-01,结束日期取"今天"(动态生成,不能写死),并支持默认值回显 最后加一个"提交"按钮,点击后把五项数据 console.log 成完整对象。

练习 4|滚动区域 用笔记里准备好的搜索页结构:左侧分类栏独立垂直滚动,右侧内容区独立垂直滚动,且分类栏滚动时右侧不受影响。再给右侧开启下拉刷新,触发后在控制台输出提示并 1 秒后关闭刷新态。

练习 5|样式限制排查 新建一个页面,故意用本地路径给某个盒子设背景图,观察报错信息并记录;随后分别用"网络图片"和"base64"两种方式修复。再把 iconfont 的图标通过在线链接引入 app.wxss,验证在至少两个不同页面中都能正常显示,并把字体样式抽到单独的 styles/iconfont.wxss 中通过 @import 引入。

原视频对照 ​

#视频时长
1小程序表单组件-input09:35
2小程序表单组件-昵称输入键盘04:01
3小程序表单组件-单选和多项选择器10:46
4小程序表单组件-省市区选择器09:59
5小程序表单组件-日期选择器11:53
6小程序样式-全局样式08:06
7小程序样式-资源引入限制10:49

小结 ​

  1. 小程序的表单组件名与网页端大体同名,但属性体系完全不同——input 的 type 只控制键盘类型,不能变成单选框;遇到不确定的属性一律查官方文档,不要凭 HTML 经验写。
  2. 表单取值的统一范式只有一条:分组容器 + bindchange + e.detail.value + setData。单选、多选、picker 全部适用,掌握一个就能类推其余。
  3. 表单组件普遍不会自动回填,选中结果必须手动写回 data 再渲染,这是绝大多数"选了没反应"问题的根因。
  4. 组件的"能不能点"取决于有没有内容撑开高度:picker 空内容高度为 0、scroll-view 垂直滚动必须显式设高、swiper 默认仅 150px 高。
  5. 涉及原生能力(键盘类型、confirm-type、昵称键盘)的效果只能在真机验证,模拟器不会弹键盘;同时留意基础库版本是否满足最低要求。
  6. WXSS 对静态资源有限制:不支持本地路径,图片走网络地址或 base64,字体图标走在线链接——这是"小程序要小、首屏要快"的设计取舍,遵守即可。
  7. 样式作用域遵循"就近优先":app.wxss 是全局兜底,页面 wxss 覆盖它;page 等价于网页的 body,是设置全局背景/字体的入口。
  8. 换页面调试别改源码,用工具里的编译模式直接切路由,效率远高于反复改 app.json。