插件和第三方库 - 站在巨人的肩膀上
🔧 不要重复造轮子!今天我们来学习如何使用现成的插件和库来提高开发效率
1. UniApp插件市场
插件市场介绍
UniApp插件市场是官方提供的插件生态平台,包含:
- UI组件库
- 功能插件
- 模板项目
- 原生插件
访问地址:https://ext.dcloud.net.cn/
安装插件的方式
方式1:HBuilderX导入
- 在插件市场找到需要的插件
- 点击"使用HBuilderX导入插件"
- 选择项目导入
方式2:手动下载
- 下载插件压缩包
- 解压到项目的
uni_modules
目录
方式3:npm安装
bash
npm install @dcloudio/uni-ui
2. 常用UI组件库
uni-ui官方组件库
bash
# 安装uni-ui
npm install @dcloudio/uni-ui
vue
<template>
<view class="uni-ui-demo">
<!-- 数字角标 -->
<uni-badge text="99+" type="error">
<button>消息</button>
</uni-badge>
<!-- 卡片 -->
<uni-card title="卡片标题" sub-title="副标题" extra="额外信息">
<text>卡片内容</text>
</uni-card>
<!-- 折叠面板 -->
<uni-collapse>
<uni-collapse-item title="面板1" open>
<text>面板1的内容</text>
</uni-collapse-item>
<uni-collapse-item title="面板2">
<text>面板2的内容</text>
</uni-collapse-item>
</uni-collapse>
<!-- 倒计时 -->
<uni-countdown
:time="countdownTime"
@timeup="onTimeup"
/>
<!-- 抽屉 -->
<uni-drawer ref="drawer" mode="left" width="300">
<view class="drawer-content">
<text>抽屉内容</text>
</view>
</uni-drawer>
<button @click="openDrawer">打开抽屉</button>
<!-- 悬浮按钮 -->
<uni-fab
:pattern="fabPattern"
@trigger="onFabClick"
/>
</view>
</template>
<script>
export default {
data() {
return {
countdownTime: 60000, // 60秒
fabPattern: {
color: '#007aff',
backgroundColor: '#fff',
selectedColor: '#fff',
buttonColor: '#007aff',
iconColor: '#fff',
content: [
{
iconPath: '/static/add.png',
selectedIconPath: '/static/add-active.png',
text: '添加',
active: false
},
{
iconPath: '/static/share.png',
selectedIconPath: '/static/share-active.png',
text: '分享',
active: false
}
]
}
}
},
methods: {
onTimeup() {
uni.showToast({
title: '倒计时结束',
icon: 'success'
})
},
openDrawer() {
this.$refs.drawer.open()
},
onFabClick(e) {
console.log('悬浮按钮点击:', e)
}
}
}
</script>
<style>
.uni-ui-demo {
padding: 20rpx;
}
.drawer-content {
padding: 30rpx;
height: 100vh;
background: #f8f9fa;
}
</style>
uView UI组件库
bash
# 安装uView
npm install uview-ui
javascript
// main.js
import uView from 'uview-ui'
Vue.use(uView)
vue
<template>
<view class="uview-demo">
<!-- 按钮 -->
<u-button type="primary" @click="handleClick">主要按钮</u-button>
<u-button type="success" shape="circle">圆形按钮</u-button>
<!-- 输入框 -->
<u-input
v-model="inputValue"
placeholder="请输入内容"
border="bottom"
/>
<!-- 选择器 -->
<u-picker
:show="showPicker"
:columns="pickerColumns"
@confirm="onPickerConfirm"
@cancel="showPicker = false"
/>
<!-- 步骤条 -->
<u-steps :list="stepsList" :current="currentStep" />
<!-- 标签 -->
<u-tag text="标签1" type="primary" />
<u-tag text="标签2" type="success" closable />
<!-- 时间轴 -->
<u-timeline>
<u-timeline-item title="订单创建" content="2024-01-01 10:00" />
<u-timeline-item title="订单支付" content="2024-01-01 10:05" />
<u-timeline-item title="订单发货" content="2024-01-01 14:00" />
</u-timeline>
</view>
</template>
<script>
export default {
data() {
return {
inputValue: '',
showPicker: false,
pickerColumns: [
['北京', '上海', '广州', '深圳']
],
stepsList: [
{ name: '下单' },
{ name: '支付' },
{ name: '发货' },
{ name: '收货' }
],
currentStep: 1
}
},
methods: {
handleClick() {
this.showPicker = true
},
onPickerConfirm(value) {
console.log('选择结果:', value)
this.showPicker = false
}
}
}
</script>
3. 实用功能插件
图表插件 - uCharts
bash
# 安装uCharts
npm install @qiun/ucharts
vue
<template>
<view class="charts-demo">
<canvas
canvas-id="lineChart"
id="lineChart"
class="chart-canvas"
@touchstart="touchChart"
@touchmove="touchChart"
@touchend="touchChart"
/>
<canvas
canvas-id="pieChart"
id="pieChart"
class="chart-canvas"
/>
</view>
</template>
<script>
import uCharts from '@qiun/ucharts'
export default {
data() {
return {
lineChart: null,
pieChart: null
}
},
onReady() {
this.initLineChart()
this.initPieChart()
},
methods: {
initLineChart() {
const chartData = {
categories: ['1月', '2月', '3月', '4月', '5月', '6月'],
series: [
{
name: '销售额',
data: [35, 20, 25, 37, 4, 20]
},
{
name: '利润',
data: [15, 10, 12, 18, 2, 8]
}
]
}
this.lineChart = new uCharts({
type: 'line',
context: uni.createCanvasContext('lineChart', this),
width: 350,
height: 250,
categories: chartData.categories,
series: chartData.series,
animation: true,
background: '#FFFFFF',
color: ['#1890FF', '#91CB74'],
padding: [15, 15, 0, 15],
legend: {
show: true,
position: 'bottom',
float: 'center',
backgroundColor: 'rgba(0,0,0,0)',
borderColor: 'rgba(0,0,0,0)',
fontColor: '#666666',
fontSize: 13,
margin: 5
},
xAxis: {
disableGrid: false,
gridType: 'dash',
fontColor: '#666666'
},
yAxis: {
gridType: 'dash',
splitNumber: 5,
min: 0,
fontColor: '#666666',
format: (val) => val.toFixed(0)
},
extra: {
line: {
type: 'curve',
width: 2,
activeType: 'hollow'
}
}
})
},
initPieChart() {
const chartData = {
series: [
{ name: 'iOS', data: 50 },
{ name: 'Android', data: 30 },
{ name: 'Web', data: 20 }
]
}
this.pieChart = new uCharts({
type: 'pie',
context: uni.createCanvasContext('pieChart', this),
width: 350,
height: 250,
series: chartData.series,
animation: true,
background: '#FFFFFF',
color: ['#1890FF', '#91CB74', '#FAC858'],
padding: [5, 5, 5, 5],
legend: {
show: true,
position: 'right',
float: 'middle'
},
extra: {
pie: {
activeOpacity: 0.5,
activeRadius: 10,
offsetAngle: 0,
labelWidth: 15,
border: true,
borderWidth: 3,
borderColor: '#FFFFFF'
}
}
})
},
touchChart(e) {
if (this.lineChart) {
this.lineChart.showToolTip(e, {
format: function (item, category) {
return category + ' ' + item.name + ':' + item.data
}
})
}
}
}
}
</script>
<style>
.charts-demo {
padding: 20rpx;
}
.chart-canvas {
width: 350px;
height: 250px;
margin: 20rpx auto;
border: 1px solid #eee;
}
</style>
二维码插件
vue
<template>
<view class="qrcode-demo">
<button @click="generateQRCode">生成二维码</button>
<button @click="scanQRCode">扫描二维码</button>
<canvas
v-if="showQRCode"
canvas-id="qrcode"
class="qrcode-canvas"
/>
<view v-if="scanResult" class="scan-result">
<text>扫描结果:\{\{ scanResult \}\}</text>
</view>
</view>
</template>
<script>
import QRCode from '@/uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js'
export default {
data() {
return {
showQRCode: false,
scanResult: ''
}
},
methods: {
generateQRCode() {
this.showQRCode = true
this.$nextTick(() => {
QRCode.make({
canvasId: 'qrcode',
componentInstance: this,
text: 'https://www.example.com',
size: 200,
margin: 10,
backgroundColor: '#ffffff',
foregroundColor: '#000000',
fileType: 'jpg',
errorCorrectLevel: QRCode.errorCorrectLevel.M,
success: (res) => {
console.log('二维码生成成功:', res)
}
})
})
},
scanQRCode() {
uni.scanCode({
success: (res) => {
this.scanResult = res.result
uni.showToast({
title: '扫描成功',
icon: 'success'
})
},
fail: (err) => {
console.error('扫描失败:', err)
uni.showToast({
title: '扫描失败',
icon: 'error'
})
}
})
}
}
}
</script>
<style>
.qrcode-demo {
padding: 20rpx;
text-align: center;
}
.qrcode-demo button {
margin: 20rpx;
width: 300rpx;
}
.qrcode-canvas {
width: 200px;
height: 200px;
margin: 20rpx auto;
border: 1px solid #eee;
}
.scan-result {
margin-top: 30rpx;
padding: 20rpx;
background: #f8f9fa;
border-radius: 8rpx;
}
</style>
4. 工具类库
日期处理 - dayjs
bash
npm install dayjs
javascript
// utils/date.js
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import 'dayjs/locale/zh-cn'
dayjs.extend(relativeTime)
dayjs.locale('zh-cn')
export default {
// 格式化日期
format(date, format = 'YYYY-MM-DD HH:mm:ss') {
return dayjs(date).format(format)
},
// 相对时间
fromNow(date) {
return dayjs(date).fromNow()
},
// 是否是今天
isToday(date) {
return dayjs(date).isSame(dayjs(), 'day')
},
// 是否是本周
isThisWeek(date) {
return dayjs(date).isSame(dayjs(), 'week')
},
// 获取月份天数
daysInMonth(date) {
return dayjs(date).daysInMonth()
},
// 添加时间
add(date, value, unit) {
return dayjs(date).add(value, unit)
},
// 减少时间
subtract(date, value, unit) {
return dayjs(date).subtract(value, unit)
}
}
数据验证 - async-validator
bash
npm install async-validator
javascript
// utils/validator.js
import Schema from 'async-validator'
export default class Validator {
constructor(rules) {
this.schema = new Schema(rules)
}
validate(data) {
return new Promise((resolve, reject) => {
this.schema.validate(data, (errors, fields) => {
if (errors) {
reject({ errors, fields })
} else {
resolve(data)
}
})
})
}
}
// 常用验证规则
export const commonRules = {
required: { required: true, message: '此字段为必填项' },
email: { type: 'email', message: '请输入正确的邮箱地址' },
phone: {
pattern: /^1[3-9]\d{9}$/,
message: '请输入正确的手机号码'
},
password: {
min: 6,
max: 20,
message: '密码长度应在6-20位之间'
}
}
使用验证器
vue
<template>
<view class="form-validation">
<view class="form-group">
<input
v-model="formData.username"
placeholder="用户名"
:class="{ error: errors.username }"
/>
<text v-if="errors.username" class="error-text">
\{\{ errors.username \}\}
</text>
</view>
<view class="form-group">
<input
v-model="formData.email"
placeholder="邮箱"
:class="{ error: errors.email }"
/>
<text v-if="errors.email" class="error-text">
\{\{ errors.email \}\}
</text>
</view>
<view class="form-group">
<input
v-model="formData.phone"
placeholder="手机号"
:class="{ error: errors.phone }"
/>
<text v-if="errors.phone" class="error-text">
\{\{ errors.phone \}\}
</text>
</view>
<button @click="handleSubmit" :disabled="isSubmitting">
\{\{ isSubmitting ? '提交中...' : '提交' \}\}
</button>
</view>
</template>
<script>
import Validator, { commonRules } from '@/utils/validator.js'
export default {
data() {
return {
formData: {
username: '',
email: '',
phone: ''
},
errors: {},
isSubmitting: false,
validator: new Validator({
username: [
commonRules.required,
{ min: 3, max: 20, message: '用户名长度应在3-20位之间' }
],
email: [
commonRules.required,
commonRules.email
],
phone: [
commonRules.required,
commonRules.phone
]
})
}
},
methods: {
async handleSubmit() {
this.errors = {}
this.isSubmitting = true
try {
await this.validator.validate(this.formData)
// 验证通过,提交数据
await this.submitForm()
uni.showToast({
title: '提交成功',
icon: 'success'
})
} catch ({ errors, fields }) {
// 验证失败,显示错误信息
this.errors = {}
errors.forEach(error => {
this.errors[error.field] = error.message
})
uni.showToast({
title: '请检查表单信息',
icon: 'error'
})
} finally {
this.isSubmitting = false
}
},
async submitForm() {
// 模拟提交
return new Promise(resolve => {
setTimeout(resolve, 1000)
})
}
}
}
</script>
<style>
.form-validation {
padding: 20rpx;
}
.form-group {
margin-bottom: 30rpx;
}
.form-group input {
width: 100%;
padding: 20rpx;
border: 1rpx solid #ddd;
border-radius: 8rpx;
font-size: 28rpx;
}
.form-group input.error {
border-color: #ff3b30;
}
.error-text {
color: #ff3b30;
font-size: 24rpx;
margin-top: 8rpx;
display: block;
}
</style>
5. 插件开发
创建自定义插件
javascript
// uni_modules/my-plugin/index.js
const MyPlugin = {
install(Vue, options = {}) {
// 添加全局方法
Vue.prototype.$myMethod = function(message) {
uni.showToast({
title: message,
icon: 'none'
})
}
// 添加全局指令
Vue.directive('highlight', {
bind(el, binding) {
el.style.backgroundColor = binding.value || 'yellow'
}
})
// 添加全局混入
Vue.mixin({
created() {
if (options.debug) {
console.log('组件创建:', this.$options.name)
}
}
})
}
}
export default MyPlugin
使用自定义插件
javascript
// main.js
import MyPlugin from '@/uni_modules/my-plugin/index.js'
Vue.use(MyPlugin, {
debug: true
})
小结
今天我们学习了:
- ✅ UniApp插件市场的使用
- ✅ 常用UI组件库的集成
- ✅ 实用功能插件的应用
- ✅ 工具类库的使用
- ✅ 自定义插件的开发
插件使用要点:
- 选择活跃度高、文档完善的插件
- 注意插件的兼容性和性能影响
- 合理评估插件的必要性
- 学会阅读插件文档和源码
下一篇预告
下一篇我们将学习《性能优化技巧 - 让你的小程序跑得更快》,学习各种性能优化的方法和技巧。
站在巨人的肩膀上,我们能看得更远!合理使用插件和库,能让开发事半功倍!