在本节中,我们将通过具体的代码示例,展示Vue3开发小程序的最佳实践,帮助开发者更好地理解和应用Vue3进行小程序开发。
1. 基础组件示例
<template>
<view class="counter">
<text class="title">{{ title }}</text>
<text class="count">{{ count }}</text>
<button class="btn" @click="increment">增加</button>
<button class="btn" @click="decrement">减少</button>
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
// 响应式状态
const count = ref(0)
// 计算属性
const title = computed(() => `计数器示例: ${count.value}`)
// 方法
function increment() {
count.value++
}
function decrement() {
count.value--
}
</script>
<style scoped>
.counter {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
.title {
font-size: 18px;
margin-bottom: 10px;
}
.count {
font-size: 24px;
font-weight: bold;
margin-bottom: 20px;
}
.btn {
margin: 5px;
padding: 8px 16px;
background-color: #1976d2;
color: white;
border-radius: 4px;
}
</style>
2. 列表渲染示例
<template>
<view class="list-container">
<view class="search-box">
<input
v-model="searchText"
placeholder="搜索商品"
@input="handleSearch"
/>
</view>
<view class="product-list">
<view
v-for="(item, index) in filteredProducts"
:key="item.id"
class="product-item"
@click="navigateToDetail(item.id)"
>
<image :src="item.image" class="product-image"></image>
<view class="product-info">
<text class="product-name">{{ item.name }}</text>
<text class="product-price">¥{{ item.price }}</text>
</view>
</view>
</view>
<view v-if="filteredProducts.length === 0" class="empty-tip">
没有找到相关商品
</view>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { useProductStore } from '@/store/product'
const productStore = useProductStore()
const searchText = ref('')
// 计算属性:过滤后的商品列表
const filteredProducts = computed(() => {
if (!searchText.value) return productStore.products
return productStore.products.filter(product =>
product.name.toLowerCase().includes(searchText.value.toLowerCase())
)
})
// 方法
function handleSearch() {
// 搜索逻辑已在计算属性中处理
}
function navigateToDetail(id) {
uni.navigateTo({
url: `/pages/product/detail?id=${id}`
})
}
// 生命周期钩子
onMounted(() => {
productStore.fetchProducts()
})
</script>
3. 网络请求封装示例
// utils/request.js
import { useUserStore } from '@/store/user'
// 基础请求方法
const request = (options) => {
return new Promise((resolve, reject) => {
// 获取用户状态管理
const userStore = useUserStore()
// 添加请求头
const header = {
'Content-Type': 'application/json'
}
// 如果有token,添加到请求头
if (userStore.token) {
header['Authorization'] = `Bearer ${userStore.token}`
}
uni.request({
url: `${BASE_URL}${options.url}`,
method: options.method || 'GET',
data: options.data || {},
header,
success: (res) => {
if (res.statusCode === 200) {
resolve(res.data)
} else if (res.statusCode === 401) {
// token过期,跳转到登录页
userStore.logout()
uni.navigateTo({
url: '/pages/login/login'
})
reject(new Error('登录已过期,请重新登录'))
} else {
reject(res)
}
},
fail: (err) => {
reject(err)
}
})
})
}
// 便捷方法
export const get = (url, data) => {
return request({
url,
method: 'GET',
data
})
}
export const post = (url, data) => {
return request({
url,
method: 'POST',
data
})
}
export const put = (url, data) => {
return request({
url,
method: 'PUT',
data
})
}
export const del = (url, data) => {
return request({
url,
method: 'DELETE',
data
})
}
4. 最佳实践
- 组件设计:遵循单一职责原则,每个组件只负责一个功能点,提高复用性
- 状态管理:合理使用Pinia进行状态管理,避免过度使用全局状态
- 性能优化:合理使用计算属性和watch,避免不必要的计算和渲染
- 代码组织:使用组合式API按逻辑关注点组织代码,提高可读性和可维护性
- 错误处理:统一处理网络请求错误和异常情况,提供友好的用户提示
- 条件编译:合理使用条件编译处理平台差异,避免过度使用导致代码混乱
在Vue3小程序开发中,推荐使用setup语法糖(<script setup>),它提供了更简洁的语法和更好的编译时优化,是Vue3组合式API的首选写法。