Skip to content

基础组件大全 - 按钮、文本、图片这些怎么用?

🧱 组件是构建页面的积木,今天我们来学习最基础也最重要的组件

什么是组件?

组件就是页面的构建块,就像搭积木一样:

  • view 组件 = 盒子(容器)
  • text 组件 = 文字
  • image 组件 = 图片
  • button 组件 = 按钮

把这些组件组合起来,就能构建出完整的页面!

1. view - 视图容器

view 是最基础的容器组件,相当于HTML中的div

基本用法

vue
<template>
  <view class="container">
    <view class="header">这是头部</view>
    <view class="content">这是内容区域</view>
    <view class="footer">这是底部</view>
  </view>
</template>

<style>
.container {
  padding: 20px;
}
.header {
  background-color: #007aff;
  color: white;
  padding: 15px;
  text-align: center;
}
.content {
  background-color: #f8f8f8;
  padding: 20px;
  margin: 10px 0;
}
.footer {
  background-color: #666;
  color: white;
  padding: 10px;
  text-align: center;
}
</style>

常用属性

vue
<view 
  class="my-view"
  hover-class="view-hover"
  hover-start-time="20"
  hover-stay-time="70"
>
  点击我试试
</view>

<style>
.my-view {
  background-color: #f0f0f0;
  padding: 20px;
  border-radius: 8px;
}
.view-hover {
  background-color: #e0e0e0;
}
</style>

2. text - 文本组件

text 用于显示文本,相当于HTML中的span

基本用法

vue
<template>
  <view>
    <text>普通文本</text>
    <text class="title">标题文本</text>
    <text class="highlight">高亮文本</text>
  </view>
</template>

<style>
.title {
  font-size: 20px;
  font-weight: bold;
  color: #333;
}
.highlight {
  color: #ff6b6b;
  background-color: #fff3cd;
  padding: 2px 6px;
  border-radius: 4px;
}
</style>

特殊属性

vue
<template>
  <view>
    <!-- 可选择的文本 -->
    <text selectable>这段文本可以被选择和复制</text>
    
    <!-- 解码HTML实体 -->
    <text decode><hello> & "world"</text>
    
    <!-- 显示连续空格 -->
    <text space="nbsp">hello     world</text>
  </view>
</template>

3. image - 图片组件

image 用于显示图片:

基本用法

vue
<template>
  <view>
    <!-- 本地图片 -->
    <image src="/static/logo.png" class="logo"></image>
    
    <!-- 网络图片 -->
    <image 
      src="https://example.com/image.jpg" 
      class="banner"
      @load="onImageLoad"
      @error="onImageError"
    >&lt;/image&gt;
    
    &lt;!-- 动态图片 --&gt;
    &lt;image :src="dynamicImageUrl" class="dynamic"&gt;&lt;/image&gt;
  &lt;/view&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  data() {
    return {
      dynamicImageUrl: '/static/default.png'
    }
  },
  methods: {
    onImageLoad(e) {
      console.log('图片加载成功', e)
    },
    onImageError(e) {
      console.log('图片加载失败', e)
      // 设置默认图片
      this.dynamicImageUrl = '/static/error.png'
    }
  }
}
&lt;/script&gt;

&lt;style&gt;
.logo {
  width: 100px;
  height: 100px;
}
.banner {
  width: 100%;
  height: 200px;
}
.dynamic {
  width: 150px;
  height: 150px;
  border-radius: 8px;
}
&lt;/style&gt;

图片模式(mode属性)

vue
&lt;template&gt;
  &lt;view class="image-modes"&gt;
    &lt;!-- 缩放模式 --&gt;
    &lt;image src="/static/demo.jpg" mode="scaleToFill" class="img"&gt;&lt;/image&gt;
    &lt;text&gt;scaleToFill: 拉伸填满&lt;/text&gt;
    
    &lt;image src="/static/demo.jpg" mode="aspectFit" class="img"&gt;&lt;/image&gt;
    &lt;text&gt;aspectFit: 保持比例,完整显示&lt;/text&gt;
    
    &lt;image src="/static/demo.jpg" mode="aspectFill" class="img"&gt;&lt;/image&gt;
    &lt;text&gt;aspectFill: 保持比例,填满容器&lt;/text&gt;
    
    &lt;!-- 裁剪模式 --&gt;
    &lt;image src="/static/demo.jpg" mode="top" class="img"&gt;&lt;/image&gt;
    &lt;text&gt;top: 显示顶部&lt;/text&gt;
    
    &lt;image src="/static/demo.jpg" mode="center" class="img"&gt;&lt;/image&gt;
    &lt;text&gt;center: 显示中间&lt;/text&gt;
  &lt;/view&gt;
&lt;/template&gt;

&lt;style&gt;
.image-modes {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.img {
  width: 200px;
  height: 100px;
  border: 1px solid #ddd;
}
&lt;/style&gt;

4. button - 按钮组件

button 是用户交互的重要组件:

基本用法

vue
&lt;template&gt;
  &lt;view class="button-demo"&gt;
    &lt;!-- 基础按钮 --&gt;
    &lt;button @click="handleClick"&gt;默认按钮&lt;/button&gt;
    
    &lt;!-- 不同类型的按钮 --&gt;
    &lt;button type="primary" @click="handlePrimary"&gt;主要按钮&lt;/button&gt;
    &lt;button type="warn" @click="handleWarn"&gt;警告按钮&lt;/button&gt;
    
    &lt;!-- 不同尺寸的按钮 --&gt;
    &lt;button size="mini" @click="handleMini"&gt;小按钮&lt;/button&gt;
    &lt;button size="default" @click="handleDefault"&gt;默认按钮&lt;/button&gt;
    
    &lt;!-- 按钮状态 --&gt;
    &lt;button :disabled="isDisabled" @click="handleDisabled"&gt;
      \{\{ isDisabled ? '已禁用' : '可点击' \}\}
    &lt;/button&gt;
    
    &lt;button :loading="isLoading" @click="handleLoading"&gt;
      \{\{ isLoading ? '加载中...' : '点击加载' \}\}
    &lt;/button&gt;
  &lt;/view&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  data() {
    return {
      isDisabled: false,
      isLoading: false
    }
  },
  methods: {
    handleClick() {
      uni.showToast({
        title: '按钮被点击了',
        icon: 'success'
      })
    },
    
    handlePrimary() {
      console.log('主要按钮被点击')
    },
    
    handleWarn() {
      uni.showModal({
        title: '警告',
        content: '这是一个警告按钮',
        showCancel: false
      })
    },
    
    handleMini() {
      console.log('小按钮被点击')
    },
    
    handleDefault() {
      console.log('默认按钮被点击')
    },
    
    handleDisabled() {
      this.isDisabled = !this.isDisabled
    },
    
    handleLoading() {
      this.isLoading = true
      
      // 模拟异步操作
      setTimeout(() => {
        this.isLoading = false
        uni.showToast({
          title: '加载完成',
          icon: 'success'
        })
      }, 2000)
    }
  }
}
&lt;/script&gt;

&lt;style&gt;
.button-demo {
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 15px;
}
&lt;/style&gt;

特殊功能按钮

vue
&lt;template&gt;
  &lt;view class="special-buttons"&gt;
    &lt;!-- 分享按钮 --&gt;
    &lt;button open-type="share" type="primary"&gt;分享给朋友&lt;/button&gt;
    
    &lt;!-- 获取用户信息 --&gt;
    &lt;button 
      open-type="getUserInfo" 
      @getuserinfo="onGetUserInfo"
      type="primary"
    &gt;
      获取用户信息
    &lt;/button&gt;
    
    &lt;!-- 获取手机号 --&gt;
    &lt;button 
      open-type="getPhoneNumber" 
      @getphonenumber="onGetPhoneNumber"
      type="primary"
    &gt;
      获取手机号
    &lt;/button&gt;
    
    &lt;!-- 客服会话 --&gt;
    &lt;button open-type="contact" type="primary"&gt;联系客服&lt;/button&gt;
  &lt;/view&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  methods: {
    onGetUserInfo(e) {
      console.log('用户信息:', e.detail)
      if (e.detail.userInfo) {
        uni.showToast({
          title: '获取成功',
          icon: 'success'
        })
      }
    },
    
    onGetPhoneNumber(e) {
      console.log('手机号信息:', e.detail)
      if (e.detail.encryptedData) {
        // 需要发送到后端解密
        this.decryptPhoneNumber(e.detail)
      }
    },
    
    async decryptPhoneNumber(detail) {
      try {
        const res = await uni.request({
          url: '/api/decrypt-phone',
          method: 'POST',
          data: detail
        })
        console.log('解密后的手机号:', res.data.phoneNumber)
      } catch (err) {
        console.error('解密失败:', err)
      }
    }
  }
}
&lt;/script&gt;

5. icon - 图标组件

icon 用于显示小图标:

vue
&lt;template&gt;
  &lt;view class="icon-demo"&gt;
    &lt;view class="icon-item"&gt;
      &lt;icon type="success" size="30" color="#4cd964"&gt;&lt;/icon&gt;
      &lt;text&gt;成功&lt;/text&gt;
    &lt;/view&gt;
    
    &lt;view class="icon-item"&gt;
      &lt;icon type="info" size="30" color="#007aff"&gt;&lt;/icon&gt;
      &lt;text&gt;信息&lt;/text&gt;
    &lt;/view&gt;
    
    &lt;view class="icon-item"&gt;
      &lt;icon type="warn" size="30" color="#f0ad4e"&gt;&lt;/icon&gt;
      &lt;text&gt;警告&lt;/text&gt;
    &lt;/view&gt;
    
    &lt;view class="icon-item"&gt;
      &lt;icon type="waiting" size="30" color="#666"&gt;&lt;/icon&gt;
      &lt;text&gt;等待&lt;/text&gt;
    &lt;/view&gt;
    
    &lt;view class="icon-item"&gt;
      &lt;icon type="cancel" size="30" color="#dd524d"&gt;&lt;/icon&gt;
      &lt;text&gt;取消&lt;/text&gt;
    &lt;/view&gt;
  &lt;/view&gt;
&lt;/template&gt;

&lt;style&gt;
.icon-demo {
  display: flex;
  justify-content: space-around;
  padding: 20px;
}
.icon-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
&lt;/style&gt;

实际应用案例:用户卡片

让我们用这些基础组件做一个用户卡片:

vue
&lt;template&gt;
  &lt;view class="user-card"&gt;
    &lt;!-- 用户头像 --&gt;
    &lt;image 
      :src="userInfo.avatar || '/static/default-avatar.png'" 
      class="avatar"
      mode="aspectFill"
      @error="onAvatarError"
    &gt;&lt;/image&gt;
    
    &lt;!-- 用户信息 --&gt;
    &lt;view class="user-info"&gt;
      &lt;text class="username"&gt;\{\{ userInfo.name || '未知用户' \}\}&lt;/text&gt;
      &lt;text class="user-desc"&gt;\{\{ userInfo.description || '这个人很懒,什么都没留下' \}\}&lt;/text&gt;
      
      &lt;!-- 用户标签 --&gt;
      &lt;view class="user-tags"&gt;
        &lt;view 
          class="tag" 
          v-for="tag in userInfo.tags" 
          :key="tag"
        &gt;
          &lt;text class="tag-text"&gt;\{\{ tag \}\}&lt;/text&gt;
        &lt;/view&gt;
      &lt;/view&gt;
    &lt;/view&gt;
    
    &lt;!-- 操作按钮 --&gt;
    &lt;view class="actions"&gt;
      &lt;button 
        class="follow-btn" 
        :class="{ 'followed': userInfo.isFollowed }"
        @click="toggleFollow"
        size="mini"
      &gt;
        \{\{ userInfo.isFollowed ? '已关注' : '关注' \}\}
      &lt;/button&gt;
      
      &lt;button 
        class="message-btn" 
        @click="sendMessage"
        size="mini"
        type="primary"
      &gt;
        私信
      &lt;/button&gt;
    &lt;/view&gt;
  &lt;/view&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  data() {
    return {
      userInfo: {
        id: 1,
        name: '张三',
        avatar: 'https://example.com/avatar.jpg',
        description: '前端开发工程师,热爱技术分享',
        tags: ['前端', 'Vue.js', 'UniApp'],
        isFollowed: false
      }
    }
  },
  
  methods: {
    onAvatarError() {
      // 头像加载失败,使用默认头像
      this.userInfo.avatar = '/static/default-avatar.png'
    },
    
    toggleFollow() {
      this.userInfo.isFollowed = !this.userInfo.isFollowed
      
      uni.showToast({
        title: this.userInfo.isFollowed ? '关注成功' : '取消关注',
        icon: 'success'
      })
    },
    
    sendMessage() {
      uni.navigateTo({
        url: `/pages/chat/chat?userId=\${this.userInfo.id}`
      })
    }
  }
}
&lt;/script&gt;

&lt;style&gt;
.user-card {
  background-color: white;
  border-radius: 12px;
  padding: 20px;
  margin: 15px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  gap: 15px;
}

.avatar {
  width: 60px;
  height: 60px;
  border-radius: 30px;
  border: 2px solid #f0f0f0;
}

.user-info {
  flex: 1;
}

.username {
  font-size: 18px;
  font-weight: bold;
  color: #333;
  display: block;
  margin-bottom: 5px;
}

.user-desc {
  font-size: 14px;
  color: #666;
  display: block;
  margin-bottom: 10px;
}

.user-tags {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.tag {
  background-color: #f0f8ff;
  border-radius: 12px;
  padding: 2px 8px;
}

.tag-text {
  font-size: 12px;
  color: #007aff;
}

.actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.follow-btn {
  background-color: #007aff;
  color: white;
  border: none;
  border-radius: 15px;
  font-size: 12px;
}

.follow-btn.followed {
  background-color: #f0f0f0;
  color: #666;
}

.message-btn {
  border-radius: 15px;
  font-size: 12px;
}
&lt;/style&gt;

小结

今天我们学习了:

  • view - 万能容器组件
  • text - 文本显示组件
  • image - 图片显示组件
  • button - 按钮交互组件
  • icon - 图标组件
  • ✅ 实际应用案例

记住这个口诀

  • view 做容器,布局靠它
  • text 显示文字,样式随意
  • image 展示图片,模式重要
  • button 用户交互,事件处理
  • icon 小小图标,画龙点睛

下一篇预告

下一篇我们将学习《表单组件详解 - 输入框、选择器、开关按钮》,学习如何收集用户输入。


基础组件是页面的基石,掌握了这些,你就能构建出丰富多彩的页面了!