🧱 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 篇。