uni-app基础扩展 ------ 详细知识点与案例
一、学习目标
本章旨在掌握 uni-app 中的生命周期机制、条件编译、扩展组件(uni-ui)的使用、辅助样式库(uni-scss)的集成,以及通过综合案例(新闻列表)巩固所学知识。
二、生命周期
uni-app 中的生命周期分为三类:应用生命周期 、页面生命周期 和组件生命周期函数。
1. 应用生命周期(App.vue)
应用生命周期在整个 App 启动到关闭过程中只执行一次。
常用钩子函数:
onLaunch
:App 初始化完成时触发(全局只触发一次)onShow
:App 启动或从后台进入前台显示onHide
:App 从前台进入后台
案例代码(App.vue):
vue
<script>
export default {
onLaunch() {
console.log('App 启动完成');
// 可用于初始化全局状态、获取用户信息等
},
onShow() {
console.log('App 进入前台');
// 可用于刷新 token、检查网络状态等
},
onHide() {
console.log('App 进入后台');
// 可用于暂停音频、保存临时数据等
}
}
</script>
⚠️ 注意:应用生命周期只能在
App.vue
中使用,不能在页面或组件中使用。
2. 页面生命周期(pages/xxx.vue)
页面生命周期在每次页面加载/卸载时触发。
常用钩子函数:
onLoad
:监听页面加载,参数为上个页面传递的数据onShow
:监听页面显示(每次进入页面都会触发)onReady
:监听页面初次渲染完成onHide
:监听页面隐藏onUnload
:监听页面卸载(如通过navigateBack
返回)
案例代码(pages/news/news.vue):
vue
<template>
<view class="news-page">
<text>新闻列表页面</text>
</view>
</template>
<script>
export default {
onLoad(options) {
// 页面加载时触发,options 是上个页面传来的参数
console.log('页面加载,参数:', options);
// 例如:从首页跳转过来携带 id=123,则 options = { id: '123' }
},
onShow() {
console.log('新闻页面显示');
// 可用于刷新数据
},
onReady() {
console.log('页面初次渲染完成');
// 可用于操作 DOM(如调用 canvas、video 等原生组件)
},
onHide() {
console.log('新闻页面隐藏');
},
onUnload() {
console.log('新闻页面卸载');
// 清理定时器、取消网络请求等
}
}
</script>
3. 组件生命周期函数(components/xxx.vue)
组件生命周期与 Vue 3 的组合式 API 或选项式 API 兼容。uni-app 支持 Vue 2/3 语法。
常用钩子(选项式):
beforeCreate
created
mounted
(对应 uni-app 的onReady
)beforeDestroy
/unmounted
⚠️ 注意:在组件中不能使用页面生命周期 (如
onLoad
),只能使用 Vue 标准生命周期。
案例代码(components/NewsItem.vue):
vue
<template>
<view class="news-item">
<text>{{ title }}</text>
</view>
</template>
<script>
export default {
props: {
title: {
type: String,
default: '默认标题'
}
},
created() {
console.log('组件实例创建完成');
// 可进行数据初始化
},
mounted() {
console.log('组件挂载完成');
// 可操作子组件或 DOM
},
beforeDestroy() {
console.log('组件即将销毁');
// 清理工作
}
}
</script>
三、条件编译
uni-app 支持平台条件编译,可针对不同平台(H5、微信小程序、App 等)编写特定代码。
语法格式:
js
// #ifdef 平台标识
// 代码
// #endif
// #ifndef 平台标识
// 非该平台的代码
// #endif
常见平台标识:
H5
MP-WEIXIN
(微信小程序)APP-PLUS
(App 端)MP-ALIPAY
(支付宝小程序)
案例:不同平台显示不同按钮
vue
<template>
<view>
<!-- 微信小程序专属 -->
// #ifdef MP-WEIXIN
<button type="primary">微信登录</button>
// #endif
<!-- H5 专属 -->
// #ifdef H5
<button type="default">H5 登录</button>
// #endif
<!-- 非 App 端显示 -->
// #ifndef APP-PLUS
<text>当前不是 App 端</text>
// #endif
</view>
</template>
JS 中使用条件编译:
js
// #ifdef H5
const apiUrl = 'https://h5.api.example.com';
// #endif
// #ifdef MP-WEIXIN
const apiUrl = 'https://wx.api.example.com';
// #endif
四、扩展组件 uni-ui
uni-ui 是 DCloud 官方提供的跨端 UI 组件库,支持所有 uni-app 平台。
1. 安装 uni-ui
在 HBuilderX 中:
- 右键项目 →
uni_modules
→从插件市场选择
- 搜索
uni-ui
→ 安装
或手动安装:
bash
npm install @dcloudio/uni-ui
推荐使用 HBuilderX 图形化安装,自动处理依赖。
2. 引入并使用组件
全局注册(main.js):
js
import { createSSRApp } from 'vue'
import App from './App.vue'
import { UniCard, UniList, UniListItem } from '@dcloudio/uni-ui'
export function createApp() {
const app = createSSRApp(App)
app.component('UniCard', UniCard)
app.component('UniList', UniList)
app.component('UniListItem', UniListItem)
return app
}
局部引入(推荐,按需加载):
vue
<template>
<view>
<uni-card title="新闻标题" :thumbnail="thumbUrl">
这是新闻内容摘要...
</uni-card>
</view>
</template>
<script>
// 按需引入
import { UniCard } from '@dcloudio/uni-ui'
export default {
components: { UniCard },
data() {
return {
thumbUrl: 'https://example.com/thumb.jpg'
}
}
}
</script>
五、uni-scss 辅助样式
uni-scss 是一套基于 scss 的跨端样式变量库,提供统一的颜色、间距、边框等变量。
使用步骤:
- 安装
uni-scss
(通常随 uni-ui 自动安装) - 在
App.vue
或页面中引入
scss
<style lang="scss">
@import '@/uni_modules/uni-scss/index.scss';
.news-container {
padding: $uni-spacing-col-lg; // 使用预设间距变量
background-color: $uni-bg-color-grey;
}
</style>
常用变量示例:
$uni-color-primary
:主色$uni-spacing-row-base
:水平基础间距$uni-font-size-lg
:大号字体
六、案例:新闻列表(综合应用)
功能需求:
- 使用
uni-list
展示新闻列表 - 每条新闻包含标题、摘要、缩略图
- 点击跳转详情页
- 使用生命周期加载数据
- 使用 uni-scss 统一样式
- 条件编译:H5 端显示"刷新"按钮,小程序端不显示
1. pages/news/index.vue
vue
<template>
<view class="news-container">
<!-- 条件编译:仅 H5 显示刷新按钮 -->
// #ifdef H5
<button class="refresh-btn" @click="loadNews">刷新</button>
// #endif
<uni-list>
<uni-list-item
v-for="item in newsList"
:key="item.id"
:title="item.title"
:note="item.summary"
:thumb="item.thumb"
thumb-size="lg"
clickable
@click="goDetail(item.id)"
/>
</uni-list>
</view>
</template>
<script>
import { UniList, UniListItem } from '@dcloudio/uni-ui'
export default {
components: { UniList, UniListItem },
data() {
return {
newsList: []
}
},
onLoad() {
this.loadNews()
},
methods: {
loadNews() {
// 模拟网络请求
this.newsList = [
{ id: 1, title: '科技新闻1', summary: '这是第一条科技新闻摘要...', thumb: '/static/thumb1.jpg' },
{ id: 2, title: '财经新闻2', summary: '股市大涨...', thumb: '/static/thumb2.jpg' }
]
},
goDetail(id) {
uni.navigateTo({
url: `/pages/news/detail?id=${id}`
})
}
}
}
</script>
<style lang="scss">
@import '@/uni_modules/uni-scss/index.scss';
.news-container {
padding: $uni-spacing-col-base;
background-color: $uni-bg-color;
}
// #ifdef H5
.refresh-btn {
margin-bottom: $uni-spacing-col-lg;
background-color: $uni-color-primary;
color: white;
}
// #endif
</style>
2. pages/news/detail.vue
vue
<template>
<view class="detail-page">
<uni-card :title="detail.title" :thumbnail="detail.thumb">
<text>{{ detail.content }}</text>
</uni-card>
</view>
</template>
<script>
import { UniCard } from '@dcloudio/uni-ui'
export default {
components: { UniCard },
data() {
return {
detail: {}
}
},
onLoad(options) {
const id = options.id
// 模拟根据 id 获取详情
this.detail = {
title: `新闻详情 ${id}`,
thumb: '/static/thumb1.jpg',
content: '这里是详细的新闻内容...'
}
}
}
</script>
七、本章小结
知识点 | 说明 |
---|---|
生命周期 | 区分应用、页面、组件三类生命周期,避免混用 |
条件编译 | 实现多端差异化逻辑,提升兼容性 |
uni-ui | 官方 UI 库,开箱即用,支持按需引入 |
uni-scss | 提供统一设计变量,提升样式一致性 |
综合案例 | 结合生命周期、组件、样式、路由实现完整功能 |
💡 最佳实践建议:
- 页面数据初始化放在
onLoad
- 全局状态管理建议使用
vuex
或pinia
- 组件尽量使用局部注册,减少包体积
- 条件编译代码需谨慎维护,避免逻辑混乱
如需进一步扩展(如分页加载、下拉刷新、骨架屏等),可在本章基础上结合 onPullDownRefresh
、scroll-view
等 API 实现。