Skip to content

uni-app 基础组件指南

本指南详细介绍uni-app的基础组件,包括视图容器和基础内容组件的使用方法。

目录


视图容器组件

视图容器组件是构建页面布局的基础,提供了各种容器和布局能力。

view 视图容器

view 是最基础的视图容器组件,类似于HTML中的div元素。

主要属性

属性名类型默认值说明
hover-classStringnone指定按下去的样式类
hover-stop-propagationBooleanfalse指定是否阻止本节点的祖先节点出现点击态
hover-start-timeNumber50按住后多久出现点击态,单位毫秒
hover-stay-timeNumber400手指松开后点击态保留时间,单位毫秒

使用示例

基础用法

vue
<template>
  <view class="container">
    <view class="box">基础视图容器</view>
  </view>
</template>

<style>
.container {
  padding: 20px;
}
.box {
  background-color: #42b983;
  color: #fff;
  padding: 20px;
  text-align: center;
  border-radius: 8px;
}
</style>

hover效果

vue
<template>
  <view class="container">
    <view class="box" hover-class="box-hover">
      点击我查看hover效果
    </view>
  </view>
</template>

<style>
.box {
  background-color: #42b983;
  color: #fff;
  padding: 20px;
  text-align: center;
  border-radius: 8px;
  transition: all 0.3s;
}
.box-hover {
  background-color: #35495e;
  transform: scale(0.95);
}
</style>

嵌套布局

vue
<template>
  <view class="container">
    <view class="card">
      <view class="card-header">卡片标题</view>
      <view class="card-body">
        <view class="card-item">项目1</view>
        <view class="card-item">项目2</view>
        <view class="card-item">项目3</view>
      </view>
      <view class="card-footer">卡片底部</view>
    </view>
  </view>
</template>

<style>
.card {
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  overflow: hidden;
  background: #fff;
}
.card-header, .card-footer {
  background-color: #f8f9fa;
  padding: 15px;
  font-weight: bold;
}
.card-body {
  padding: 15px;
}
.card-item {
  padding: 10px 0;
  border-bottom: 1px solid #eee;
}
.card-item:last-child {
  border-bottom: none;
}
</style>

scroll-view 可滚动视图

scroll-view 是可滚动的视图区域组件,用于展示超出容器的内容。

主要属性

属性名类型默认值说明
scroll-xBooleanfalse允许横向滚动
scroll-yBooleanfalse允许纵向滚动
upper-thresholdNumber50距顶部/左边多远时触发scrolltoupper事件
lower-thresholdNumber50距底部/右边多远时触发scrolltolower事件
scroll-topNumber-设置竖向滚动条位置
scroll-leftNumber-设置横向滚动条位置
refresher-enabledBooleanfalse开启下拉刷新

使用示例

横向滚动

vue
<template>
  <view class="container">
    <scroll-view class="scroll-view-h" scroll-x>
      <view class="scroll-item" v-for="n in 10" :key="n">
        项目{{ n }}
      </view>
    </scroll-view>
  </view>
</template>

<style>
.scroll-view-h {
  white-space: nowrap;
  width: 100%;
}
.scroll-item {
  display: inline-block;
  width: 150px;
  height: 150px;
  margin-right: 10px;
  background-color: #42b983;
  color: #fff;
  text-align: center;
  line-height: 150px;
  border-radius: 8px;
}
</style>

纵向滚动

vue
<template>
  <view class="container">
    <scroll-view 
      class="scroll-view-v" 
      scroll-y 
      :scroll-top="scrollTop"
      @scrolltoupper="onScrollToUpper"
      @scrolltolower="onScrollToLower"
    >
      <view class="scroll-item-v" v-for="n in 20" :key="n">
        项目{{ n }}
      </view>
    </scroll-view>
    <button @click="scrollToTop">回到顶部</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      scrollTop: 0
    }
  },
  methods: {
    onScrollToUpper() {
      console.log('滚动到顶部')
    },
    onScrollToLower() {
      console.log('滚动到底部')
    },
    scrollToTop() {
      this.scrollTop = 0
    }
  }
}
</script>

<style>
.scroll-view-v {
  height: 300px;
}
.scroll-item-v {
  height: 100px;
  margin-bottom: 10px;
  background-color: #42b983;
  color: #fff;
  text-align: center;
  line-height: 100px;
  border-radius: 8px;
}
</style>

下拉刷新

vue
<template>
  <view class="container">
    <scroll-view 
      class="scroll-view-v" 
      scroll-y 
      refresher-enabled
      :refresher-triggered="triggered"
      @refresherrefresh="onRefresh"
    >
      <view class="scroll-item-v" v-for="item in list" :key="item.id">
        {{ item.text }}
      </view>
    </scroll-view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      triggered: false,
      list: [
        { id: 1, text: '项目1' },
        { id: 2, text: '项目2' },
        { id: 3, text: '项目3' }
      ]
    }
  },
  methods: {
    onRefresh() {
      if (this._refreshing) return
      this._refreshing = true
      
      setTimeout(() => {
        const newItem = { 
          id: Date.now(), 
          text: `新项目${Math.floor(Math.random() * 100)}` 
        }
        this.list.unshift(newItem)
        this.triggered = false
        this._refreshing = false
      }, 2000)
    }
  }
}
</script>

swiper 滑块视图容器

swiper 是滑块视图容器组件,用于实现轮播图等效果。

主要属性

属性名类型默认值说明
indicator-dotsBooleanfalse是否显示面板指示点
indicator-colorColorrgba(0,0,0,.3)指示点颜色
indicator-active-colorColor#000000当前选中的指示点颜色
autoplayBooleanfalse是否自动切换
currentNumber0当前所在滑块的index
intervalNumber5000自动切换时间间隔
durationNumber500滑动动画时长
circularBooleanfalse是否采用衔接滑动

使用示例

基础轮播图

vue
<template>
  <view class="container">
    <swiper 
      class="swiper" 
      indicator-dots 
      autoplay 
      :interval="3000" 
      :duration="500"
    >
      <swiper-item v-for="(item, index) in swiperList" :key="index">
        <view class="swiper-item" :style="{ backgroundColor: item.color }">
          {{ item.text }}
        </view>
      </swiper-item>
    </swiper>
  </view>
</template>

<script>
export default {
  data() {
    return {
      swiperList: [
        { text: '轮播图1', color: '#42b983' },
        { text: '轮播图2', color: '#35495e' },
        { text: '轮播图3', color: '#ff7e67' }
      ]
    }
  }
}
</script>

<style>
.swiper {
  height: 200px;
}
.swiper-item {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  color: #fff;
  font-size: 18px;
  border-radius: 8px;
  margin: 0 10px;
}
</style>

自定义指示器

vue
<template>
  <view class="container">
    <swiper 
      class="swiper" 
      :current="current" 
      @change="onSwiperChange"
      autoplay 
      :interval="3000"
    >
      <swiper-item v-for="(item, index) in swiperList" :key="index">
        <view class="swiper-item" :style="{ backgroundColor: item.color }">
          {{ item.text }}
        </view>
      </swiper-item>
    </swiper>
    
    <view class="custom-indicator">
      <view 
        v-for="(item, index) in swiperList" 
        :key="index" 
        class="indicator-dot" 
        :class="{ active: current === index }"
        @click="changeCurrent(index)"
      ></view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      current: 0,
      swiperList: [
        { text: '轮播图1', color: '#42b983' },
        { text: '轮播图2', color: '#35495e' },
        { text: '轮播图3', color: '#ff7e67' }
      ]
    }
  },
  methods: {
    onSwiperChange(e) {
      this.current = e.detail.current
    },
    changeCurrent(index) {
      this.current = index
    }
  }
}
</script>

<style>
.custom-indicator {
  display: flex;
  justify-content: center;
  margin-top: 15px;
}
.indicator-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #ccc;
  margin: 0 4px;
  transition: all 0.3s;
}
.indicator-dot.active {
  background-color: #42b983;
  transform: scale(1.2);
}
</style>

movable-area 和 movable-view 可移动视图

movable-areamovable-view 组合使用,可以实现拖拽、缩放等交互效果。

movable-view 主要属性

属性名类型默认值说明
directionStringnone移动方向,属性值有all、vertical、horizontal、none
inertiaBooleanfalse是否带有惯性
out-of-boundsBooleanfalse超过可移动区域后,是否还可以移动
xNumber-定义x轴方向的偏移
yNumber-定义y轴方向的偏移
scaleBooleanfalse是否支持双指缩放
scale-minNumber0.5定义缩放倍数最小值
scale-maxNumber10定义缩放倍数最大值

使用示例

基础拖拽

vue
<template>
  <view class="container">
    <movable-area class="movable-area">
      <movable-view 
        class="movable-view" 
        direction="all" 
        @change="onChange"
      >
        拖动我
      </movable-view>
    </movable-area>
  </view>
</template>

<script>
export default {
  methods: {
    onChange(e) {
      console.log('位置变化:', e.detail)
    }
  }
}
</script>

<style>
.movable-area {
  width: 300px;
  height: 300px;
  background-color: #f8f9fa;
  margin: 0 auto;
  border-radius: 8px;
}
.movable-view {
  width: 80px;
  height: 80px;
  background-color: #42b983;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 8px;
  font-size: 14px;
}
</style>

限制移动方向

vue
<template>
  <view class="container">
    <text class="title">只能横向移动</text>
    <movable-area class="movable-area">
      <movable-view class="movable-view" direction="horizontal">
        横向
      </movable-view>
    </movable-area>
    
    <text class="title">只能纵向移动</text>
    <movable-area class="movable-area">
      <movable-view class="movable-view" direction="vertical">
        纵向
      </movable-view>
    </movable-area>
  </view>
</template>

<style>
.title {
  display: block;
  margin: 20px 0 10px;
  font-weight: bold;
  text-align: center;
}
.movable-area {
  width: 300px;
  height: 120px;
  background-color: #f8f9fa;
  margin: 0 auto 20px;
  border-radius: 8px;
}
</style>

cover-view 和 cover-image 覆盖视图

cover-viewcover-image 可以覆盖在原生组件(如map、video等)上的视图容器。

主要特点

  • 只能覆盖在原生组件上,如 mapvideocanvascamera
  • 支持的CSS样式有限
  • 事件模型与普通组件一致

使用示例

覆盖在视频上

vue
<template>
  <view class="container">
    <video 
      id="myVideo" 
      class="video" 
      src="your-video-url.mp4"
      controls
    >
      <cover-view class="video-title">
        视频标题
      </cover-view>
      
      <cover-view class="video-controls">
        <cover-view class="control-btn" @click="playVideo">
          播放
        </cover-view>
      </cover-view>
    </video>
  </view>
</template>

<script>
export default {
  data() {
    return {
      videoContext: null
    }
  },
  onReady() {
    this.videoContext = uni.createVideoContext('myVideo')
  },
  methods: {
    playVideo() {
      this.videoContext.play()
    }
  }
}
</script>

<style>
.video {
  width: 100%;
  height: 200px;
  position: relative;
}
.video-title {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  color: #fff;
  padding: 10px;
  font-size: 14px;
}
.video-controls {
  position: absolute;
  bottom: 10px;
  right: 10px;
}
.control-btn {
  background-color: #42b983;
  color: #fff;
  padding: 8px 16px;
  border-radius: 4px;
  font-size: 14px;
}
</style>

基础内容组件

基础内容组件用于展示文本、图标等基础内容。

text 文本组件

text 组件用于显示文本内容,是唯一支持文本选择的组件。

主要属性

属性名类型默认值说明
selectableBooleanfalse文本是否可选
user-selectBooleanfalse文本是否可选,该属性会使文本节点显示为inline-block
spaceString-显示连续空格,可选值:ensp、emsp、nbsp
decodeBooleanfalse是否解码

使用示例

基础文本

vue
<template>
  <view class="container">
    <text>普通文本</text>
    <text selectable>可选择的文本</text>
    <text space="ensp">带有  空格  的文本</text>
    <text decode>&lt;div&gt;解码文本&lt;/div&gt;</text>
  </view>
</template>

<style>
.container text {
  display: block;
  margin: 10px 0;
  padding: 10px;
  background-color: #f8f9fa;
  border-radius: 4px;
}
</style>

文本样式

vue
<template>
  <view class="container">
    <text class="text-primary">主要文本</text>
    <text class="text-secondary">次要文本</text>
    <text class="text-success">成功文本</text>
    <text class="text-warning">警告文本</text>
    <text class="text-danger">危险文本</text>
  </view>
</template>

<style>
.text-primary { color: #007bff; }
.text-secondary { color: #6c757d; }
.text-success { color: #28a745; }
.text-warning { color: #ffc107; }
.text-danger { color: #dc3545; }
</style>

rich-text 富文本组件

rich-text 组件用于显示富文本内容,支持HTML标签和内联样式。

主要属性

属性名类型默认值说明
nodesArray/String[]节点列表/HTML String
spaceString-显示连续空格

使用示例

vue
<template>
  <view class="container">
    <rich-text :nodes="htmlContent"></rich-text>
  </view>
</template>

<script>
export default {
  data() {
    return {
      htmlContent: `
        <div style="color: #333; font-size: 16px;">
          <h2 style="color: #42b983;">富文本标题</h2>
          <p>这是一段<strong>加粗</strong>的文本,还有<em>斜体</em>文本。</p>
          <ul>
            <li>列表项1</li>
            <li>列表项2</li>
          </ul>
        </div>
      `
    }
  }
}
</script>

progress 进度条组件

progress 组件用于显示操作进度。

主要属性

属性名类型默认值说明
percentNumber0百分比0~100
show-infoBooleanfalse在进度条右侧显示百分比
border-radiusNumber0圆角大小
font-sizeNumber16右侧百分比字体大小
stroke-widthNumber6进度条线的宽度
colorString#09BB07进度条颜色
activeColorString#09BB07已选择的进度条的颜色
backgroundColorString#EBEBEB未选择的进度条的颜色
activeBooleanfalse进度条从左往右的动画

使用示例

vue
<template>
  <view class="container">
    <view class="progress-item">
      <text>基础进度条</text>
      <progress :percent="30" show-info />
    </view>
    
    <view class="progress-item">
      <text>自定义颜色</text>
      <progress 
        :percent="60" 
        show-info 
        color="#42b983"
        :stroke-width="8"
        :border-radius="4"
      />
    </view>
    
    <view class="progress-item">
      <text>动画效果</text>
      <progress 
        :percent="progress" 
        show-info 
        active
        color="#ff7e67"
      />
      <button @click="updateProgress">更新进度</button>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      progress: 0
    }
  },
  methods: {
    updateProgress() {
      this.progress = Math.floor(Math.random() * 100)
    }
  }
}
</script>

<style>
.progress-item {
  margin: 20px 0;
}
.progress-item text {
  display: block;
  margin-bottom: 10px;
  font-weight: bold;
}
button {
  margin-top: 10px;
  padding: 8px 16px;
  background-color: #42b983;
  color: #fff;
  border: none;
  border-radius: 4px;
}
</style>

总结

本指南介绍了uni-app中最常用的基础组件:

视图容器组件

  • view:基础容器,支持hover效果
  • scroll-view:可滚动容器,支持下拉刷新
  • swiper:轮播容器,支持自动播放和指示器
  • movable-area/movable-view:可拖拽容器,支持缩放
  • cover-view/cover-image:覆盖原生组件的容器

基础内容组件

  • text:文本显示,支持选择和空格处理
  • rich-text:富文本显示,支持HTML内容
  • progress:进度条显示,支持动画效果

这些组件是构建uni-app应用的基础,掌握它们的使用方法对开发高质量的跨平台应用至关重要。

一次开发,多端部署 - 让跨平台开发更简单