2026/10/26 18:16:26

微信小程序:文件引用——include 引入 WXML 片段与条件渲染

微信小程序:文件引用——include 引入 WXML 片段与条件渲染 一、前言一个页面如果只有几十行 WXML全部堆在index.wxml里也还看得懂但真实项目的页面动辄几百行头部、正文、底部、侧栏混在一起改一处样式要在一大段代码里翻找。WXML 提供了文件引用机制可以把页面拆成多个小片段文件主页面只保留在哪里嵌入什么的结构逻辑一下子清晰起来。本文通过一个科技进展简报页面演示用include把页面拆成 header、main、footer、expand 四个片段文件主页面依次引入前三段第四段拓展阅读则包在wx:if里由两个按钮控制显隐。案例还会对比include、import、自定义组件三者在用途和作用域上的区别。二、核心概念include 引入include src/files/header/include会把目标文件的代码原样嵌入到当前位置相当于把那段 WXML 抄了进来。案例用四次include分别引入头部、正文、底部和拓展阅读。src 路径写法推荐使用以/开头的绝对路径从项目根目录算起不是从当前页面算起并且不写.wxml后缀。写成src/files/header即可写成/files/header.wxml反而可能找不到文件。include 与 import 的区别import只引入目标文件里template定义的内容且必须配合template is名字 data...才能真正渲染include则把整个文件除template、wxs以外的内容全部搬过来不需要额外调用。本案例引入的是整段结构所以用include。片段文件files/目录下的四个文件都不是完整页面没有Page({})也没有对应的.json它们只是被切成小块的视图结构。这类文件不能单独访问只能被别的文件引用。样式不随引用走include只搬结构不搬样式。被引入片段里用到的.header、.main、.footer、.expand这些类名必须在引用方的 wxss 或全局app.wxss里有定义。案例把这些样式统一写在app.wxss里所以每个片段都能取到。wx:if 条件渲染view wx:if{{showFlag}}里的内容只有在showFlag为 true 时才渲染。区别于hiddenwx:if在条件为 false 时节点会被真正销毁条件变 true 时重新创建。setData 更新视图showExpand与hideExpand两个方法分别调用this.setData({ showFlag: true })和this.setData({ showFlag: false })数据一变视图立刻重新计算wx:if。全局标签选择器app.wxss里直接写button { background-color: #39c5bb; color: #fff; }会作用到所有页面的所有button组件案例用它统一按钮配色省去在每个页面重复写类名。flex 的 gap 属性.btn-group用display: flex; gap: 20rpx;让两个按钮横向排列并自动保持 20rpx 间距不需要给按钮单独加 margin。三、项目文件结构文件引用/ ├── app.js 小程序逻辑注册小程序实例 ├── app.json 全局配置页面路径、窗口表现 ├── app.wxss 全局样式片段样式与按钮配色 ├── .eslintrc.js 代码规范配置 ├── sitemap.json 微信索引配置 ├── project.config.json 项目配置appid、编译设置等 ├── project.private.config.json 项目私有配置 ├── components/ 自定义组件目录 │ └── navigation-bar/ 自定义导航栏组件 │ ├── navigation-bar.js │ ├── navigation-bar.json │ ├── navigation-bar.wxml │ └── navigation-bar.wxss ├── files/ 被引入的 WXML 片段 │ ├── header.wxml 页面头部大标题 │ ├── main.wxml 正文科技进展列表 │ ├── footer.wxml 底部日期 │ └── expand.wxml 拓展阅读航天规划 └── pages/ 页面目录 └── index/ 首页 ├── index.js 页面逻辑显隐标志与两个切换方法 ├── index.json 页面配置注册自定义组件 ├── index.wxml 页面结构四次 include 与按钮组 └── index.wxss 页面样式页面级布局骨架四、代码实现1. pages/index/index.wxml【结构页面】navigation-bar title文件引用 back{{false}} colorblack background#FFF/navigation-bar scroll-view classscrollarea scroll-y typelist view classbox include src/files/header/include include src/files/main/include include src/files/footer/include view classbtn-group button bindtapshowExpand显示扩展内容/button button bindtaphideExpand隐藏扩展内容/button /view view wx:if{{showFlag}} include src/files/expand/include /view /view /scroll-view主页面本身非常薄只有四行include和一组按钮页面的实际内容全在files/目录下。2. files/header.wxml【头部片段】view classheader 2026 年重大科技进展 /view3. files/main.wxml【正文片段】view classmain 天问二号小行星探测2026.7、轻舟试验飞船2026.3.30 发射、地月双向高速激光通信验证2026.8、中国空间站常态化运营、九章四号光量子原型机2026.5、AI 辅助新药靶点发现、多模态大模型向工业落地深化、核光钟研制成功、柔性光子芯片 /view4. files/footer.wxml【底部片段】view classfooter 2026年10月17日 /view5. files/expand.wxml【拓展阅读片段】view classexpand 拓展阅读我国航天后续重大规划br / 1、天问三号火星采样返回任务br / 2、载人登月工程br / 3、大型空间基础设施建设 /view6. pages/index/index.js【页面数据】// index.js Page({ data:{ // 控制拓展阅读是否显示默认不显示 showFlag:false }, // 显示扩展内容 showExpand(){ this.setData({ showFlag:true }) }, // 隐藏扩展内容 hideExpand(){ this.setData({ showFlag:false }) } })7. app.wxss【全局样式】/**app.wxss**/ .box { margin: 20rpx; padding: 20rpx; border: 6rpx solid #F4C2C8; } .header { text-align: center; margin: 20rpx; color: #1E40AF; font-size: x-large; font-weight: bolder; } .main { font-size: large; text-indent: 2em; margin: 20rpx; line-height: 2em; text-align: justify; color: #475569; } .footer { margin-right: 30rpx; font-size: medium; text-align: right; color: #475569; } /*拓展阅读样式*/ .expand { margin: 20rpx; padding: 20rpx; border: 4rpx solid #F4C2C8; color: #475569; } /*按钮组样式*/ .btn-group { display: flex; gap: 20rpx; margin: 20rpx; } button { background-color: #39c5bb; color: #fff; }8. pages/index/index.wxss【页面样式】/*index.wxss*/ page { height: 100vh; display: flex; flex-direction: column; } .scrollarea { flex: 1; overflow-y: hidden; }9. pages/index/index.json【页面配置】{ usingComponents: { navigation-bar: /components/navigation-bar/navigation-bar } }五、运行效果页面顶部是自定义导航栏「文件引用」。内容区外围是一圈 6rpx 的浅粉色描边框框内自上而下依次排布。最上方是居中、加粗、深蓝色的标题「2026 年重大科技进展」。标题下方是一段正文首行缩进两个字符行高为字号的 2 倍两端对齐文字颜色是偏灰的深蓝读起来比较舒展。正文里用顿号把九项科技进展串成一段。再往下是右对齐的日期「2026年10月17日」。日期下方是一组并排的按钮两个按钮背景均为青绿色#39c5bb、文字白色中间自动保持 20rpx 的间距。初始状态下页面上只有标题、正文、日期和两个按钮看不到航天规划的内容。点击「显示扩展内容」后按钮下方会立刻出现一块带浅粉描边的区域内容是拓展阅读的标题加三条编号列表点击「隐藏扩展内容」这块区域又消失页面回到初始状态。六、知识点总结1、include的语义是把这文件的代码搬到这里。案例里三次include依次嵌入 header、main、footer编译后等价于把这三段 WXML 直接写进index.wxml的对应位置因此它们共享同一个页面作用域。2、src用的是从项目根目录算起的绝对路径/files/header并且没有写.wxml后缀。写成相对路径如../../files/header也能用但页面目录层级一变就得跟着改绝对路径更省心。3、include与import不能混用import只认出template定义引入后还得写template isxxx /才渲染include则把整段结构搬过来不需要调用。案例引入的是完整结构块所以选include。此外include会忽略目标文件里的template和wxs这两类内容它不搬。4、样式不会随include一起过来。files/*.wxml里的.header、.main、.footer这些类名样式必须写在引用方能看到的地方——本案例写在app.wxss全局样式里所以任何页面引用这些片段都能正常显示。如果把样式写在pages/index/index.wxss里一旦换成别的页面引用同一片段样式就丢了。5、files/下的四个文件不是页面它们是片段没有Page({})没有独立 json也不能在app.json的pages数组里注册。判断标准很简单——能不能单独打开能打开的是页面不能的是片段。6、include不支持传参。片段里的内容都是写死的文本主页面无法告诉它这次显示什么标题。如果需要参数就得改用template定义 data传值或者干脆封装成自定义组件。这是include最大的局限。7、wx:if{{showFlag}}控制拓展阅读的显隐条件为 false 时整个节点不会创建。这和hidden属性不同hidden只是把元素藏起来节点仍然存在于页面结构中用调试器能看到wx:if是真正不渲染。内容较重、默认又不需要显示时用wx:if更省资源。8、两个按钮分别绑定了showExpand和hideExpand各自调用setData把showFlag置为 true 或 false。小程序是数据驱动的不需要手动操作 DOM只改数据视图自动跟着变。9、app.wxss里的button { ... }是标签选择器会作用到全局所有button组件案例用它统一了按钮配色。好处是省事风险是难以针对单个按钮做例外——真要做差异化时应该改用类选择器避免污染面过大。10、.btn-group用display: flex加gap: 20rpx实现按钮横排并自动留间距。相比过去给每个按钮写margin-right的做法gap不会在最后一个元素后面留出多余空白也不需要写:last-child { margin-right: 0 }。11、片段里的换行用的是br /标签如 expand.wxml 中的三行规划。WXML 对br /的支持与 Web 不同更稳妥的写法是给每行套一个view或者用\n配合white-space: pre-wrap。案例用br /能正常断行但在不同渲染引擎下的表现不如块级元素稳定。12、include是编译期展开不是运行时组件所以它没有独立的作用域、没有样式隔离、也没有生命周期。这也是它与components/navigation-bar那种自定义组件的本质区别组件是封装include只是代码分割。七、拓展思考当页面越写越长时拆片段是最低成本的整理手段。比如把一个个人中心页面拆成头像区、数据区、功能列表区、设置区四个片段主文件只剩四行include改哪块就打开哪个文件比在几百行里上下翻找快得多。但include只解决代码变短不解决逻辑复用。一旦某个片段需要在不同页面显示不同内容就该升级为template轻量、可传数据、无独立样式或自定义组件有独立作用域、可定义属性和事件。三者的演进路径可以概括为先include拆分再template传参最后组件化封装。