🎉 限时特惠活动公告、获取优惠码、最高立减3200元
UniApp 移动端组件详细文档
rpx 作为尺寸单位var(--color-primary)p-[20rpx], m-[10rpx]<template>
<chat-input
v-model="message"
placeholder="请输入消息..."
:loading="loading"
@send="handleSend"
@clear="handleClear"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import ChatInput from '@/components/chat-input/chat-input.vue'
const message = ref('')
const loading = ref(false)
function handleSend(text: string) {
console.log('发送消息:', text)
loading.value = true
// 发送消息逻辑
loading.value = false
}
function handleClear() {
message.value = ''
}
</script>| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue | string | - | 输入框内容(必填) |
placeholder | string | '请输入...' | 占位提示文字 |
loading | boolean | false | 是否加载中 |
showStop | boolean | undefined | 是否显示停止按钮 |
showContinue | boolean | false | 是否显示继续按钮 |
showFileUpload | boolean | false | 是否显示文件上传 |
safeAreaInsetBottom | boolean | false | 是否适配安全区域 |
filePlugin | object | {} | 文件插件配置 |
| 事件名 | 参数 | 说明 |
|---|---|---|
update:modelValue | string | 输入内容变化 |
send | string | 发送消息 |
clear | - | 清空会话 |
pause | - | 暂停生成 |
continue | - | 继续生成 |
focus | - | 输入框聚焦 |
fileSelect | file | 文件选择 |
| 插槽名 | 说明 |
|---|---|
actions | 操作按钮区域 |
file-list | 文件列表区域 |
<template>
<chat-input
v-model="message"
:loading="loading"
:show-stop="true"
:show-continue="true"
:show-file-upload="true"
:file-plugin="filePlugin"
@send="handleSend"
@pause="handlePause"
@continue="handleContinue"
@clear="handleClear"
>
<template #actions>
<view class="flex gap-2">
<u-tag text="联网" @click="toggleWebSearch" />
<u-tag text="深度思考" @click="toggleDeepThink" />
</view>
</template>
<template #file-list>
<view v-for="file in fileList" :key="file.id">
{{ file.name }}
</view>
</template>
</chat-input>
</template>
<script setup lang="ts">
const filePlugin = ref({
url: '',
name: ''
})
const fileList = ref([])
</script><template>
<ua-markdown :content="markdownContent" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import UaMarkdown from '@/components/ua-markdown/ua-markdown.vue'
const markdownContent = ref(`
# 标题
## 二级标题
这是一段**加粗**的文字和*斜体*文字。
\`\`\`javascript
const hello = 'world'
console.log(hello)
\`\`\`
| 表头1 | 表头2 |
|-------|-------|
| 内容1 | 内容2 |
`)
</script>| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
content | string | '' | Markdown内容 |
showLine | boolean/string | true | 是否显示代码行号 |
linkList | array | [] | 链接列表配置 |
| 事件名 | 参数 | 说明 |
|---|---|---|
click-link | { href, text } | 点击链接 |
<template>
<ua-markdown :content="mathContent" />
</template>
<script setup>
const mathContent = `
行内公式:$E=mc^2$
块级公式:
$$
\\int_{a}^{b} f(x) dx = F(b) - F(a)
$$
`
</script><template>
<audio-play
:src="audioUrl"
:autoplay="false"
@play="onPlay"
@pause="onPause"
@ended="onEnded"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import AudioPlay from '@/components/audio-play/audio-play.vue'
const audioUrl = ref('https://example.com/audio.mp3')
function onPlay() {
console.log('开始播放')
}
function onPause() {
console.log('暂停播放')
}
function onEnded() {
console.log('播放结束')
}
</script>| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
src | string | '' | 音频地址 |
autoplay | boolean | false | 自动播放 |
loop | boolean | false | 循环播放 |
showProgress | boolean | true | 显示进度条 |
| 事件名 | 参数 | 说明 |
|---|---|---|
play | - | 开始播放 |
pause | - | 暂停播放 |
ended | - | 播放结束 |
error | error | 播放错误 |
timeupdate | currentTime | 时间更新 |
<template>
<file-upload
v-model="fileList"
:limit="5"
:max-size="10"
accept="image/*"
@success="handleSuccess"
@error="handleError"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import FileUpload from '@/components/file-upload/file-upload.vue'
const fileList = ref([])
function handleSuccess(file) {
console.log('上传成功:', file)
}
function handleError(error) {
console.error('上传失败:', error)
}
</script>| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue | array | [] | 文件列表 |
limit | number | 9 | 最大文件数 |
maxSize | number | 10 | 单个文件大小限制(MB) |
accept | string | 'image/*' | 接受文件类型 |
multiple | boolean | true | 多选 |
disabled | boolean | false | 禁用 |
| 事件名 | 参数 | 说明 |
|---|---|---|
update:modelValue | array | 文件列表变化 |
success | file | 上传成功 |
error | error | 上传失败 |
remove | file | 删除文件 |
exceed | files | 超出限制 |
<template>
<tabbar
v-model="activeIndex"
:list="tabList"
@change="handleChange"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Tabbar from '@/components/tabbar/tabbar.vue'
const activeIndex = ref(0)
const tabList = ref([
{
name: '首页',
icon: 'home',
path: '/pages/index/index'
},
{
name: '知识库',
icon: 'grid',
path: '/pages/kb/kb'
},
{
name: '我的',
icon: 'account',
path: '/pages/user/user'
}
])
function handleChange(index) {
console.log('切换到:', index)
}
</script>| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue | number | 0 | 当前选中索引 |
list | array | [] | 导航项列表 |
fixed | boolean | true | 是否固定底部 |
safeAreaInsetBottom | boolean | true | 适配安全区域 |
<template>
<page-status
:status="pageStatus"
:empty-text="'暂无数据'"
:error-text="'加载失败'"
@retry="handleRetry"
>
<!-- 正常内容 -->
<view v-if="pageStatus === 'success'">
页面内容
</view>
</page-status>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import PageStatus from '@/components/page-status/page-status.vue'
const pageStatus = ref<'loading' | 'success' | 'empty' | 'error'>('loading')
function handleRetry() {
pageStatus.value = 'loading'
// 重新加载数据
loadData()
}
</script>| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
status | string | 'loading' | 页面状态 |
emptyText | string | '暂无数据' | 空状态文字 |
emptyImage | string | - | 空状态图片 |
errorText | string | '加载失败' | 错误状态文字 |
errorImage | string | - | 错误状态图片 |
loadingText | string | '加载中...' | 加载状态文字 |
| 事件名 | 参数 | 说明 |
|---|---|---|
retry | - | 点击重试 |
<template>
<loading :show="loading" type="flower" text="加载中..." />
</template>
<script setup>
import { ref } from 'vue'
import Loading from '@/components/loading/loading.vue'
const loading = ref(true)
</script>| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
show | boolean | false | 是否显示 |
type | string | 'flower' | 加载类型 |
text | string | '' | 加载文字 |
size | number | 40 | 图标大小 |
color | string | '#2979ff' | 图标颜色 |
flower - 花朵旋转circle - 圆环旋转wave - 波浪动画<template>
<price :value="99.99" :precision="2" prefix="¥" />
</template>
<script setup>
import Price from '@/components/price/price.vue'
</script>| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | number/string | 0 | 价格数值 |
precision | number | 2 | 小数位数 |
prefix | string | '¥' | 货币符号 |
suffix | string | '' | 后缀 |
color | string | '#ff0000' | 颜色 |
size | number | 28 | 字体大小(rpx) |
<template>
<recorder
:max-duration="60"
@start="onStart"
@stop="onStop"
@cancel="onCancel"
/>
</template>
<script setup>
import Recorder from '@/components/recorder/recorder.vue'
function onStart() {
console.log('开始录音')
}
function onStop(file) {
console.log('录音完成:', file)
}
function onCancel() {
console.log('取消录音')
}
</script>| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
maxDuration | number | 60 | 最大录音时长(秒) |
minDuration | number | 1 | 最小录音时长(秒) |
format | string | 'mp3' | 音频格式 |
| 事件名 | 参数 | 说明 |
|---|---|---|
start | - | 开始录音 |
stop | file | 录音完成 |
cancel | - | 取消录音 |
error | error | 录音错误 |
components/
└── my-component/
├── my-component.vue # 主组件文件
├── props.ts # Props类型定义
├── types.ts # 类型定义
├── utils.ts # 工具函数
└── README.md # 组件说明<template>
<view class="my-component">
<!-- 组件内容 -->
</view>
</template>
<script setup lang="ts">
/**
* 组件名称:MyComponent
* 组件描述:组件功能描述
* 作者:作者名称
* 日期:2024-01-01
*/
import { computed, ref, watch } from 'vue'
// Props定义
interface Props {
modelValue?: string
title?: string
disabled?: boolean
}
const props = withDefaults(defineProps<Props>(), {
modelValue: '',
title: '',
disabled: false
})
// Emits定义
const emit = defineEmits<{
'update:modelValue': [value: string]
'change': [value: string]
}>()
// 内部状态
const internalValue = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val)
})
// 方法
function handleClick() {
if (props.disabled) return
emit('change', internalValue.value)
}
</script>
<style lang="scss" scoped>
.my-component {
/* 组件样式 */
}
</style>