当前位置: 首页 > article >正文

uniapp 系统学习,从入门到实战(五)—— 组件库与常用 UI 组件

全篇大概 7000 字(含代码),建议阅读时间 30min


UniApp 基于 Vue.js 的跨平台特性,提供了丰富的内置组件和灵活的扩展能力。本文将从内置组件、扩展组件库和自定义组件开发三个维度,系统解析 UniApp 的组件生态,并结合实际开发场景提供实践建议。

📚 目录

  1. 内置组件
  2. 扩展组件库
  3. 自定义组件开发
  4. 总结

1. 内置组件

UniApp 内置组件经过多端适配,可自动转换为原生控件,确保一致性和性能。以下是核心分类及使用要点:

1.1 视图容器​

标签名描述
view基础容器,类似HTML的div,支持fle布局和嵌套
scroll-view可滚动区域,需设置固定高度(纵向滚动)或 white-space: nowrap(横向滚动)。支持触底事件 @scrolltolower 和下拉刷新。
swiper轮播容器,需搭配 swiper-item 使用。通过 indicator-dots 显示指示点,autoplay 实现自动切换。

view示例代码:

<template>
  <!-- 基础布局容器 -->
  <view class="container">
    <view class="box" style="background-color: #f0ad4e;">Box 1</view>
    <view class="box" style="background-color: #5bc0de;">Box 2</view>
  </view>
</template>

<style>
.container {
  display: flex;
  padding: 20px;
}
.box {
  width: 100px;
  height: 100px;
  margin: 10px;
  text-align: center;
  line-height: 100px;
}
</style>

scroll-view示例代码:

<template>
  <!-- 纵向滚动 -->
  <scroll-view 
    scroll-y 
    :style="{height: '300px'}" 
    @scrolltolower="onReachBottom"
  >
    <view v-for="i in 20" :key="i" class="item">Item {{i}}</view>
  </scroll-view>
</template>

<script>
export default {
  methods: {
    onReachBottom() {
      uni.showToast({ title: '触底了' })
    }
  }
}
</script>

<style>
.item {
  height: 80px;
  line-height: 80px;
  border-bottom: 1px solid #eee;
}
</style>

swiper示例代码:

<template>
  <!-- 自动轮播 -->
  <swiper 
    :indicator-dots="true" 
    :autoplay="true" 
    interval="2000"
  >
    <swiper-item>
      <view class="swiper-item" style="background-color: #4cd964;">Page 1</view>
    </swiper-item>
    <swiper-item>
      <view class="swiper-item" style="background-color: #007aff;">Page 2</view>
    </swiper-item>
  </swiper>
</template>

<style>
.swiper-item {
  height: 200px;
  text-align: center;
  line-height: 200px;
}
</style>

1.2 基础内容​

标签名描述
text文本组件,支持 selectable 长按选中和 space 控制空格显示(如 ensp、emsp)。
image图片组件,支持 mode=“aspectFit” 等比缩放。注意默认宽高为 300px×225px,建议通过 CSS 优化加载闪烁问题。

text示例代码:

<template>
  <!-- 可选中文本 -->
  <text selectable space="ensp">
    这是  带空格的文本(ENSP空格)
  </text>
  
  <!-- 换行文本 -->
  <text>\n换行文本示例</text>
</template>

image示例代码:

<template>
  <!-- 等比缩放图片 -->
  <image 
    src="https://example.com/image.jpg"
    mode="aspectFit"
    style="width: 300px; height: 200px;"
  />
</template>

1.3表单交互​

标签名描述
input/textarea输入框支持 v-model 双向绑定。textarea 需设置 white-space: pre-wrap 实现自动换行。
picker数据选择器,支持 mode=“selector”(普通选择器)或 mode=“date”(日期选择),通过 @change 事件获取选中值。
button按钮类型包括 primary(蓝色)、warn(红色),支持 loading 状态和 open-type 微信开放能力。

input/textarea示例代码:

<template>
  <!-- 双向绑定 -->
  <input v-model="inputValue" placeholder="请输入内容" />
  
  <!-- 自动换行文本域 -->
  <textarea 
    v-model="textValue" 
    :style="{whiteSpace: 'pre-wrap'}"
    placeholder="多行输入"
  />
</template>

<script>
export default {
  data() {
    return {
      inputValue: '',
      textValue: ''
    }
  }
}
</script>

picker示例代码:

<template>
  <!-- 日期选择器 -->
  <picker 
    mode="date" 
    :value="date" 
    @change="onDateChange"
  >
    <view>选择日期:{{date}}</view>
  </picker>

  <!-- 普通选择器 -->
  <picker 
    mode="selector" 
    :range="options"
    @change="onSelectChange"
  >
    <view>当前选择:{{options[selectedIndex]}}</view>
  </picker>
</template>

<script>
export default {
  data() {
    return {
      date: '2023-01-01',
      options: ['选项A', '选项B', '选项C'],
      selectedIndex: 0
    }
  },
  methods: {
    onDateChange(e) {
      this.date = e.detail.value
    },
    onSelectChange(e) {
      this.selectedIndex = e.detail.value
    }
  }
}
</script>

button示例代码:

<template>
  <!-- 带加载状态的按钮 -->
  <button 
    type="primary" 
    :loading="isLoading"
    @click="handleSubmit"
  >
    提交
  </button>

  <!-- 微信开放能力 -->
  <button 
    open-type="getUserInfo"
    @getuserinfo="onGetUserInfo"
  >
    微信登录
  </button>
</template>

<script>
export default {
  data() {
    return {
      isLoading: false
    }
  },
  methods: {
    handleSubmit() {
      this.isLoading = true
      setTimeout(() => {
        this.isLoading = false
      }, 2000)
    },
    onGetUserInfo(e) {
      console.log('用户信息:', e.detail.userInfo)
    }
  }
}
</script>

1.4 导航与媒体​

标签名描述
navigator页面跳转组件,支持 open-type=“navigate”(保留当前页)或 redirect(关闭当前页)。
video视频播放器,需注意 iOS 平台可能需添加 webkit-playsinline 属性实现内联播放。

navigator示例代码:

<template>
  <!-- 保留当前页跳转 -->
  <navigator 
    url="/pages/detail/detail" 
    open-type="navigate"
  >
    跳转到详情页
  </navigator>

  <!-- 关闭当前页跳转 -->
  <navigator 
    url="/pages/home/home" 
    open-type="redirect"
  >
    返回首页
  </navigator>
</template>

video示例代码:

<template>
  <!-- 内联播放视频 -->
  <video 
    src="https://example.com/video.mp4"
    :webkit-playsinline="true"
    controls
    style="width: 100%; height: 300px;"
  />
</template>

1.5 跨平台差异处理:

组件样式默认已适配多端,但如 button 在 H5 显示蓝色,小程序显示绿色。
原生组件(如 map、video)层级高于前端组件,需使用 cover-view 覆盖。

2. 扩展组件库

对于复杂场景,UniApp 生态提供了多款高质量扩展库:

2.1 uni-ui​

功能:官方维护的组件库,包含 uni-card(卡片)、uni-popup(弹窗)等 50+ 组件,支持主题定制和国际化。
安装方式

  1. ​通过命令安装
 npm install @dcloudio/uni-ui
  1. 通过HBuilderX 插件市场导入
    在这里插入图片描述

2.2 uView UI​

优势:提供表格、级联选择器等交互组件,内置工具函数如日期格式化,适合中后台系统开发。
在这里插入图片描述

2.3 ColorUI​

设计:强调视觉表现,提供渐变色按钮、动画图标,适合电商、社交类应用。
示例:uni-ui 按钮使用​

<template>
  <uni-button type="primary" @click="submit">提交</uni-button>
</template>
<script>
	import { UniButton } from '@dcloudio/uni-ui';
	export default { components: { UniButton } }
</script>

3. 自定义组件开发

当内置组件无法满足需求时,可通过以下步骤开发自定义组件:

3.1 创建组件​

目录规范:在 components 目录下创建 MyButton.vue,包含模板、逻辑、样式三部分。
代码示例

<template>
  <button :class="type" @click="$emit('click')">
    <slot></slot>
  </button>
</template>
<script>
	export default { 
		props: { 
			type: { 
				type: String, 
				default: 'default' } 
			} 
		}
</script>

3.2 组件通信​

Props 传值:父组件通过 :color=“red” 传递数据。

子组件 MyButton.vue

<template>
  <!-- 使用父组件传入的颜色 -->
  <view 
    class="custom-btn" 
    :style="{backgroundColor: color}" 
    @click="handleClick"
  >
    <slot>默认按钮</slot>
  </view>
</template>

<script>
export default {
  props: {
    // 接收颜色值,默认值为灰色
    color: {
      type: String,
      default: '#cccccc'
    }
  },
  methods: {
    handleClick() {
      // 向父组件触发 click 事件
      this.$emit('click')
    }
  }
}
</script>

<style>
.custom-btn {
  padding: 10px 20px;
  border-radius: 8px;
  color: white;
  display: inline-block;
}
</style>

父组件Parent.vuew

<template>
  <view>
    <!-- 传递颜色并监听事件 -->
    <my-button 
      :color="btnColor" 
      @click="onButtonClick"
    >
      红色按钮
    </my-button>

    <text>点击次数:{{count}}</text>
  </view>
</template>

<script>
export default {
  data() {
    return {
      btnColor: '#dd514c', // 红色
      count: 0
    }
  },
  methods: {
    onButtonClick() {
      this.count++
      uni.showToast({ title: `点击了 ${this.count}` })
    }
  }
}
</script>

事件触发:子组件通过 $emit(‘click’) 通知父组件。
子组件DataSender.vue

<template>
  <view>
    <input v-model="inputValue" />
    <button @click="sendData">提交数据</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      inputValue: ''
    }
  },
  methods: {
    sendData() {
      // 携带输入框数据触发事件
      this.$emit('data-submit', this.inputValue)
      this.inputValue = ''
    }
  }
}
</script>

父组件ParentAdvanced.vue

<template>
  <view>
    <!-- 监听自定义事件并接收参数 -->
    <data-sender @data-submit="handleDataSubmit" />

    <view v-for="(item, index) in list" :key="index">
      {{index + 1}}. {{item}}
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      list: []
    }
  },
  methods: {
    handleDataSubmit(data) {
      if (data.trim()) {
        this.list.push(data)
        uni.showToast({ title: '收到数据:' + data })
      }
    }
  }
}
</script>

3.3 优化实践​

easycom 规范:无需手动注册,组件自动全局引用。

  1. 配置 pages.json
// pages.json
{
  "easycom": {
    "autoscan": true,
    "custom": {
      // 匹配 components 目录下的所有vue文件
      "^u-(.*)": "@/components/uni-$1/uni-$1.vue"
    }
  }
}
  1. 创建组件文件
# 目录结构
components/
  └── uni-button/
        └── uni-button.vue
  1. 使用组件
<template>
  <view>
    <!-- 自动识别 components/uni-button/uni-button.vue -->
    <u-button @click="handleClick">Easycom按钮</u-button>
  </view>
</template>

<script>
export default {
  methods: {
    handleClick() {
      uni.showToast({ title: '按钮点击' })
    }
  }
}
</script>

CSS 变量:通过 --theme-color 统一主题色,提升可维护性。

  1. 全局定义变量
/* App.vue 的 <style> 标签 */
:root {
  --theme-color: #007aff;    /* 主色调 */
  --warning-color: #ff4444;  /* 警告色 */
  --text-size: 16px;         /* 基础字号 */
}
  1. 使用变量
<template>
  <view class="card">
    <text class="title">CSS变量示例</text>
    <text class="warning-text">警告信息</text>
  </view>
</template>

<style>
.card {
  padding: 20px;
  background-color: var(--theme-color); /* 使用主色调 */
}

.title {
  font-size: var(--text-size);
  color: white;
}

.warning-text {
  color: var(--warning-color);
}
</style>
  1. 动态修改变量
<script>
export default {
  methods: {
    // 切换夜间模式
    toggleDarkMode() {
      const root = document.documentElement
      if (this.isDark) {
        root.style.setProperty('--theme-color', '#007aff')
        root.style.setProperty('--text-size', '16px')
      } else {
        root.style.setProperty('--theme-color', '#2c2c2c')
        root.style.setProperty('--text-size', '14px')
      }
      this.isDark = !this.isDark
    }
  }
}
</script>

4. 总结

基础功能:优先使用内置组件(如 scroll-view 区域滚动),确保跨端兼容性。
复杂交互:选择 uni-ui 或 uView 减少重复开发,例如表格渲染、复杂表单。
定制需求:通过自定义组件封装业务逻辑,如实现拖拽缩放视图(参考 movable-view 组件)。


http://www.kler.cn/a/567068.html

相关文章:

  • 【MySQL】增删改查
  • 目录遍历文件包含测试
  • 基于Milvus 向量数据库和Sentence Transformer构建智能问答系统
  • SqlServer占用CPU过高情况排查
  • 【C++奇迹之旅】:字符串转换成数字将数字转换成字符串大全
  • 深度学习五大模型:CNN、Transformer、BERT、RNN、GAN详细解析
  • Android15 am命令 APP安装流程
  • anaconda配置pytorch
  • C++ primer plus 第四节 复合类型
  • 深入解析 Svelte:下一代前端框架的革命
  • 前端实现上传图片到OSS(Vue3+vant)
  • 《深入浅出 Vue.js 组件化开发》
  • 设计一个“车速计算”SWC,通过Sender-Receiver端口输出车速信号。
  • Prometheus + Grafana 监控
  • 解决“两数之和”问题:两种实现方法详解
  • 双臂机器人的动力学建模
  • 浅入浅出Selenium DevTools
  • Oracle日常管理(8)——DB日常管理(2)
  • 正大杯攻略|量表类问卷数据分析基本步骤
  • Html5学习教程,从入门到精通,HTML 5 图像语法知识点语法知识点及案例代码(9)