Appearance
组件开发
组件类型
内置组件
Taro 提供了丰富的内置组件,与各端原生组件保持一致,包括:
- 基础组件:View、Text、Image、ScrollView、Swiper 等
- 表单组件:Button、Input、Checkbox、Radio、Picker 等
- 导航组件:Navigator、TabBar 等
- 媒体组件:Audio、Video、Camera 等
- 地图组件:Map 等
自定义组件
Taro 支持使用 React、Vue 等框架创建自定义组件。
React 组件开发
函数组件
jsx
import React from 'react'
import { View, Text } from '@tarojs/components'
import './index.scss'
export default function CustomComponent(props) {
const { title, content } = props
return (
<View className="custom-component">
<Text className="title">{title}</Text>
<Text className="content">{content}</Text>
</View>
)
}类组件
jsx
import React, { Component } from 'react'
import { View, Text, Button } from '@tarojs/components'
import './index.scss'
export default class Counter extends Component {
state = {
count: 0
}
handleIncrement = () => {
this.setState(prevState => ({
count: prevState.count + 1
}))
}
render() {
const { count } = this.state
return (
<View className="counter">
<Text className="count">{count}</Text>
<Button onClick={this.handleIncrement}>增加</Button>
</View>
)
}
}Vue 组件开发
单文件组件
vue
<template>
<view class="custom-component">
<text class="title">{{ title }}</text>
<text class="content">{{ content }}</text>
</view>
</template>
<script>
export default {
name: 'CustomComponent',
props: {
title: {
type: String,
default: ''
},
content: {
type: String,
default: ''
}
}
}
</script>
<style scoped>
.custom-component {
padding: 20px;
background-color: #f5f5f5;
border-radius: 8px;
}
.title {
font-size: 18px;
font-weight: bold;
margin-bottom: 10px;
}
.content {
font-size: 14px;
color: #666;
}
</style>组件生命周期
React 组件生命周期
- 挂载阶段:constructor → getDerivedStateFromProps → render → componentDidMount
- 更新阶段:getDerivedStateFromProps → shouldComponentUpdate → render → getSnapshotBeforeUpdate → componentDidUpdate
- 卸载阶段:componentWillUnmount
Vue 组件生命周期
- 创建阶段:beforeCreate → created → beforeMount → mounted
- 更新阶段:beforeUpdate → updated
- 销毁阶段:beforeUnmount → unmounted
组件通信
父子组件通信
- Props:父组件向子组件传递数据
- 事件:子组件向父组件传递数据
- Context:跨层级组件通信
全局状态管理
- Redux:React 生态的状态管理库
- MobX:简单可扩展的状态管理库
- Vuex:Vue 生态的状态管理库
- Pinia:Vue 3 推荐的状态管理库
组件样式
样式文件
- CSS:基础样式文件
- Sass/Less:CSS 预处理器
- CSS Modules:局部作用域样式
样式注意事项
- 选择器:尽量使用类选择器,避免使用标签选择器
- 单位:使用 rpx 作为单位,自动适配不同屏幕
- 样式隔离:使用 CSS Modules 或 scoped 样式
- 性能优化:避免使用复杂的选择器和过度的样式嵌套
组件复用
高阶组件
jsx
import React from 'react'
const withLoading = (WrappedComponent) => {
return class WithLoading extends React.Component {
state = {
isLoading: true
}
componentDidMount() {
setTimeout(() => {
this.setState({ isLoading: false })
}, 1000)
}
render() {
const { isLoading } = this.state
if (isLoading) {
return <View>加载中...</View>
}
return <WrappedComponent {...this.props} />
}
}
}
export default withLoading组件组合
jsx
import React from 'react'
import { View, Text } from '@tarojs/components'
const Layout = ({ header, content, footer }) => {
return (
<View className="layout">
<View className="header">{header}</View>
<View className="content">{content}</View>
<View className="footer">{footer}</View>
</View>
)
}
export default Layout组件测试
单元测试
使用 Jest 进行组件单元测试:
javascript
import React from 'react'
import { render, fireEvent } from '@testing-library/react'
import Counter from './Counter'
describe('Counter', () => {
test('renders initial count', () => {
const { getByText } = render(<Counter />)
expect(getByText('0')).toBeInTheDocument()
})
test('increments count when button is clicked', () => {
const { getByText } = render(<Counter />)
const button = getByText('增加')
fireEvent.click(button)
expect(getByText('1')).toBeInTheDocument()
})
})组件最佳实践
- 单一职责:每个组件只负责一个功能
- 可复用性:设计通用组件,提高代码复用率
- 性能优化:使用 React.memo、useMemo、useCallback 等优化渲染性能
- 代码规范:遵循 ESLint 和 Prettier 规范
- 文档完善:为组件添加详细的文档和示例