03-内置组件与页面开发

2 阅读2分钟

🧱 Taro+Vue3 入门(三):Taro 内置组件与页面开发

系列导读:Taro 的组件在 Vue3 中以标签形式使用,和 HTML 标签很像但有差异。 本文详解常用组件 + Vue3 模板语法实战。


📦 1. 常用组件

容器与文本

<template>
  <!-- view = div,text = span -->
  <view class="card" @tap="handleTap">
    <text class="title">{{ title }}</text>
    <text class="desc">{{ description }}</text>
  </view>
</template>

图片与轮播

<template>
  <!-- 轮播图 -->
  <swiper class="banner" autoplay circular :indicator-dots="true" :interval="3000">
    <swiper-item v-for="item in banners" :key="item.id">
      <image :src="item.image" mode="aspectFill" class="banner-img" />
    </swiper-item>
  </swiper>

  <!-- 圆角图片 -->
  <image
    :src="product.image"
    mode="widthFix"
    class="product-img"
    @error="onImageError"
    lazy-load
  />
</template>

ScrollView 滚动列表

<script setup lang="ts">
import { ref } from 'vue'

const items = ref([/* ... */])
const refreshing = ref(false)

async function onRefresh() {
  refreshing.value = true
  await fetchData()
  refreshing.value = false
}

function onLoadMore() {
  loadNextPage()
}
</script>

<template>
  <scroll-view
    scroll-y
    class="list"
    style="height: 100vh"
    :refresher-enabled="true"
    :refresher-triggered="refreshing"
    @refresherrefresh="onRefresh"
    @scrolltolower="onLoadMore"
  >
    <view v-for="item in items" :key="item.id" class="item">
      <text>{{ item.name }}</text>
    </view>
    <view class="loading-more">
      <text>加载中...</text>
    </view>
  </scroll-view>
</template>

表单组件

<script setup lang="ts">
import { reactive } from 'vue'

const form = reactive({
  nickname: '',
  gender: '男',
  agree: false,
})

function handleSubmit() {
  if (!form.agree) {
    Taro.showToast({ title: '请同意协议', icon: 'none' })
    return
  }
  console.log('提交:', form)
}
</script>

<template>
  <view class="form">
    <view class="form-item">
      <text class="label">昵称</text>
      <input v-model="form.nickname" placeholder="请输入昵称" />
    </view>

    <view class="form-item">
      <text class="label">性别</text>
      <radio-group @change="(e) => form.gender = e.detail.value">
        <radio value="男" :checked="form.gender === '男'">男</radio>
        <radio value="女" :checked="form.gender === '女'">女</radio>
      </radio-group>
    </view>

    <view class="form-item">
      <checkbox-group @change="(e) => form.agree = e.detail.value.length > 0">
        <checkbox value="agree" :checked="form.agree" />
        <text>同意用户协议</text>
      </checkbox-group>
    </view>

    <button type="primary" @tap="handleSubmit">提交</button>
  </view>
</template>

🔄 2. 页面生命周期 + Vue3 实践

<!-- 完整的列表页示例 -->
<script setup lang="ts">
import { ref } from 'vue'
import { useLoad, useDidShow, usePullDownRefresh, useReachBottom, useShareAppMessage } from '@tarojs/taro'
import Taro from '@tarojs/taro'
import ProductCard from '@/components/ProductCard.vue'

const products = ref<Product[]>([])
const page = ref(1)
const loading = ref(true)
const hasMore = ref(true)

// 页面加载
useLoad((options) => {
  const category = options?.category || 'all'
  fetchProducts(category)
})

// 页面显示(切回来时刷新)
useDidShow(() => {
  // 每次回到页面刷新数据
})

// 下拉刷新
usePullDownRefresh(async () => {
  page.value = 1
  hasMore.value = true
  await fetchProducts()
  Taro.stopPullDownRefresh()
})

// 触底加载更多
useReachBottom(async () => {
  if (!hasMore.value || loading.value) return
  page.value++
  await fetchProducts()
})

// 分享
useShareAppMessage(() => ({
  title: '发现好物,快来看看',
  path: '/pages/list/index',
}))

async function fetchProducts(category?: string) {
  loading.value = true
  try {
    const res = await productApi.getList({ page: page.value, category })
    if (page.value === 1) {
      products.value = res.list
    } else {
      products.value.push(...res.list)
    }
    hasMore.value = products.value.length < res.total
  } finally {
    loading.value = false
  }
}
</script>

<template>
  <view class="list-page">
    <ProductCard
      v-for="item in products"
      :key="item.id"
      v-bind="item"
      @tap="(id) => Taro.navigateTo({ url: `/pages/detail/index?id=${id}` })"
    />

    <view v-if="loading" class="status">加载中...</view>
    <view v-else-if="!hasMore" class="status">没有更多了</view>
  </view>
</template>

✅ 本篇小结 Checklist

  • 掌握 view/text/image/swiper 常用组件
  • 会用 scroll-view 实现下拉刷新 + 触底加载
  • 掌握小程序表单组件(input/radio/checkbox)
  • 熟练运用 Taro 页面生命周期

下一篇预告:《路由与页面导航》


本文是「Taro+Vue3 入门」系列第 3 篇,共 10 篇。