微信小程序代码复用技巧

1. 自定义组件复用

基本组件封装

js 复制代码
// components/common-button/common-button.js
Component({
  properties: {
    // 定义属性
    type: {
      type: String,
      value: 'primary'  // primary/default/danger
    },
    text: String,
    disabled: Boolean
  },
  methods: {
    handleTap() {
      if (!this.data.disabled) {
        this.triggerEvent('tap')
      }
    }
  }
})
html 复制代码
<!-- components/common-button/common-button.wxml -->
<button 
  class="common-btn {{type}} {{disabled ? 'disabled' : ''}}"
  bindtap="handleTap"
>
  {{text}}
</button>
css 复制代码
/* components/common-button/common-button.wxss */
.common-btn {
  padding: 20rpx 40rpx;
  border-radius: 8rpx;
  font-size: 28rpx;
}
.common-btn.primary {
  background: #07c160;
  color: #fff;
}
.common-btn.disabled {
  opacity: 0.5;
}

使用组件

json 复制代码
// 页面.json
{
  "usingComponents": {
    "common-button": "/components/common-button/common-button"
  }
}
html 复制代码
<!-- 页面.wxml -->
<common-button 
  text="提交" 
  type="primary" 
  bindtap="onSubmit"
/>

<common-button 
  text="取消" 
  type="default" 
  bindtap="onCancel"
/>

2. Behavior(行为)复用

创建公共Behavior

js 复制代码
// behaviors/loading-behavior.js
module.exports = Behavior({
  data: {
    isLoading: false
  },
  methods: {
    // 显示加载
    showLoading(text = '加载中...') {
      wx.showLoading({ title: text })
      this.setData({ isLoading: true })
    },
    
    // 隐藏加载
    hideLoading() {
      wx.hideLoading()
      this.setData({ isLoading: false })
    },
    
    // 带加载状态的请求
    async requestWithLoading(options) {
      this.showLoading()
      try {
        const res = await this.request(options)
        return res
      } finally {
        this.hideLoading()
      }
    }
  }
})

在多个组件中复用

js 复制代码
// components/user-card/user-card.js
const loadingBehavior = require('../../behaviors/loading-behavior')

Component({
  behaviors: [loadingBehavior],
  methods: {
    async fetchUserInfo() {
      const data = await this.requestWithLoading({
        url: '/api/user/info'
      })
      this.setData({ userInfo: data })
    }
  }
})
js 复制代码
// components/product-list/product-list.js
const loadingBehavior = require('../../behaviors/loading-behavior')

Component({
  behaviors: [loadingBehavior],
  methods: {
    async loadProducts() {
      const products = await this.requestWithLoading({
        url: '/api/products'
      })
      this.setData({ products })
    }
  }
})

3. Mixins模式实现

虽然小程序不直接支持Mixins,但可以通过Behavior模拟:

js 复制代码
// behaviors/form-behavior.js
module.exports = Behavior({
  data: {
    formData: {},
    formErrors: {}
  },
  methods: {
    // 表单字段变化
    onFormChange(e) {
      const { field } = e.currentTarget.dataset
      const { value } = e.detail
      
      this.setData({
        [`formData.${field}`]: value,
        [`formErrors.${field}`]: ''
      })
    },
    
    // 表单验证
    validateForm(rules) {
      const errors = {}
      let isValid = true
      
      Object.keys(rules).forEach(field => {
        const value = this.data.formData[field]
        const rule = rules[field]
        
        if (rule.required && !value) {
          errors[field] = rule.message || '该字段必填'
          isValid = false
        }
        // 更多验证规则...
      })
      
      this.setData({ formErrors: errors })
      return isValid
    }
  }
})

4. 高阶组件模式

创建高阶组件工厂

js 复制代码
// utils/with-auth.js
function withAuth(Component) {
  return function(options) {
    const originalOnLoad = options.methods.onLoad || function() {}
    
    options.methods.onLoad = function(params) {
      // 检查登录状态
      if (!this.checkAuth()) {
        wx.redirectTo({ url: '/pages/login/login' })
        return
      }
      
      originalOnLoad.call(this, params)
    }
    
    // 添加登录检查方法
    options.methods.checkAuth = function() {
      const token = wx.getStorageSync('token')
      return !!token
    }
    
    return Component(options)
  }
}

使用高阶组件

js 复制代码
// pages/user/user.js
import withAuth from '../../utils/with-auth'

const originalOptions = {
  data: { userInfo: {} },
  methods: {
    onLoad() {
      this.loadUserInfo()
    },
    loadUserInfo() {
      // 加载用户信息
    }
  }
}

// 包装原始配置
withAuth(Component)(originalOptions)

5. 工具函数复用

按功能分类的工具函数

js 复制代码
// utils/date-util.js
// 日期格式化
export function formatDate(date, format = 'YYYY-MM-DD') {
  if (!date) return ''
  const d = new Date(date)
  const year = d.getFullYear()
  const month = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  
  return format
    .replace('YYYY', year)
    .replace('MM', month)
    .replace('DD', day)
}

// 相对时间
export function relativeTime(date) {
  const now = new Date()
  const target = new Date(date)
  const diff = now - target
  
  const minutes = Math.floor(diff / 60000)
  if (minutes < 60) return `${minutes}分钟前`
  
  const hours = Math.floor(minutes / 60)
  if (hours < 24) return `${hours}小时前`
  
  const days = Math.floor(hours / 24)
  if (days < 30) return `${days}天前`
  
  return formatDate(date)
}
js 复制代码
// utils/request-util.js
// 统一的网络请求
export function request(options) {
  const token = wx.getStorageSync('token')
  const header = {
    'Content-Type': 'application/json',
    ...options.header
  }
  
  if (token) {
    header['Authorization'] = `Bearer ${token}`
  }
  
  return new Promise((resolve, reject) => {
    wx.request({
      url: `https://api.example.com${options.url}`,
      method: options.method || 'GET',
      data: options.data,
      header,
      success: (result) => {
        if (result.statusCode === 200) {
          resolve(result.data)
        } else {
          reject(result.data)
        }
      },
      fail: reject
    })
  })
}

6. 组合式复用

复杂组件的组合

js 复制代码
// components/smart-form/smart-form.js
const formBehavior = require('../../behaviors/form-behavior')
const validationBehavior = require('../../behaviors/validation-behavior')

Component({
  behaviors: [formBehavior, validationBehavior],
  
  methods: {
    // 继承自formBehavior的onFormChange
    // 继承自validationBehavior的validateForm
    
    async onSubmit() {
      if (!this.validateForm(this.data.rules)) {
        return
      }
      
      // 提交表单
      const result = await this.submitData(this.data.formData)
      
      if (result.success) {
        this.triggerEvent('success', result.data)
      }
    }
  }
})

7. 模板复用

WXML模板

html 复制代码
<!-- templates/empty-state.wxml -->
<template name="emptyState">
  <view class="empty-container">
    <image src="{{icon}}" class="empty-icon" />
    <text class="empty-text">{{text}}</text>
    <button wx:if="{{showButton}}" bindtap="onButtonTap">
      {{buttonText}}
    </button>
  </view>
</template>

<template name="loading">
  <view class="loading-container">
    <image src="/images/loading.gif" class="loading-icon" />
    <text>{{text || '加载中...'}}</text>
  </view>
</template>

使用模板

html 复制代码
<!-- 页面.wxml -->
<import src="/templates/empty-state.wxml" />
<import src="/templates/loading.wxml" />

<view wx:if="{{isLoading}}">
  <template is="loading" data="{{text: '拼命加载中...'}}" />
</view>

<view wx:elif="{{isEmpty}}">
  <template 
    is="emptyState" 
    data="{{{
      icon: '/images/empty.png',
      text: '暂无数据',
      showButton: true,
      buttonText: '刷新试试'
    }}}" 
  />
</view>

8. 样式复用策略

创建样式变量

css 复制代码
/* styles/variables.wxss */
:root {
  --primary-color: #07c160;
  --danger-color: #fa5151;
  --text-color: #333;
  --border-color: #eee;
  --font-size-sm: 24rpx;
  --font-size-md: 28rpx;
  --font-size-lg: 32rpx;
  --border-radius: 8rpx;
}

复用样式类

css 复制代码
/* styles/common.wxss */
.flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

.text-ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hairline {
  position: relative;
}
.hairline::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  border-bottom: 1rpx solid var(--border-color);
  transform: scaleY(0.5);
}

在页面中引入

css 复制代码
/* 页面.wxss */
@import "/styles/variables.wxss";
@import "/styles/common.wxss";

.user-card {
  composes: flex-center;
  padding: 20rpx;
  border-radius: var(--border-radius);
  background: #fff;
}

9. 数据状态复用

创建全局状态管理器

js 复制代码
// store/user-store.js
class UserStore {
  constructor() {
    this._listeners = []
    this._userInfo = null
  }
  
  // 获取用户信息
  getUserInfo() {
    if (!this._userInfo) {
      this._userInfo = wx.getStorageSync('userInfo')
    }
    return this._userInfo
  }
  
  // 更新用户信息
  setUserInfo(userInfo) {
    this._userInfo = userInfo
    wx.setStorageSync('userInfo', userInfo)
    this._notifyListeners()
  }
  
  // 订阅变化
  subscribe(listener) {
    this._listeners.push(listener)
    return () => {
      const index = this._listeners.indexOf(listener)
      if (index > -1) this._listeners.splice(index, 1)
    }
  }
  
  _notifyListeners() {
    this._listeners.forEach(listener => listener(this._userInfo))
  }
}

// 导出单例
export default new UserStore()

在多个页面中使用

js 复制代码
// pages/profile/profile.js
import userStore from '../../store/user-store'

Page({
  onLoad() {
    // 获取用户信息
    this.setData({ 
      userInfo: userStore.getUserInfo() 
    })
    
    // 订阅更新
    this.unsubscribe = userStore.subscribe((userInfo) => {
      this.setData({ userInfo })
    })
  },
  
  onUnload() {
    // 取消订阅
    this.unsubscribe && this.unsubscribe()
  }
})

10. 复用最佳实践

1. 按职责分层

bash 复制代码
utils/
  ├── date-util.js        # 日期处理
  ├── request-util.js     # 网络请求
  ├── validate-util.js    # 验证工具
  └── storage-util.js     # 存储工具

behaviors/
  ├── form-behavior.js
  ├── loading-behavior.js
  └── auth-behavior.js

components/
  ├── common/            # 通用组件
  ├── business/          # 业务组件
  └── layout/            # 布局组件

mixins/                  # 混合功能
templates/               # 模板文件
styles/                  # 样式文件

2. 创建配置中心

arduino 复制代码
// config/app-config.js
export default {
  // API配置
  api: {
    baseURL: 'https://api.example.com',
    timeout: 10000
  },
  
  // 页面路径
  pages: {
    login: '/pages/login/login',
    home: '/pages/home/home'
  },
  
  // 存储键名
  storageKeys: {
    token: 'user_token',
    userInfo: 'user_info'
  }
}

3. 文档和示例

为每个复用组件创建示例页面:

css 复制代码
components/common-button/
  ├── common-button.js
  ├── common-button.wxml
  ├── common-button.wxss
  └── example/
      ├── example.js      # 使用示例
      └── example.wxml

复用带来的好处

  1. 减少代码量:避免重复编写相同逻辑
  2. 便于维护:修改只需在一处进行
  3. 一致性:保证功能和行为统一
  4. 团队协作:提供标准化的开发模式
  5. 包体积优化:显著减少重复代码

通过合理的代码复用,不仅能减小包体积,还能提升开发效率和代码质量。建议在项目初期就规划好复用策略,建立代码规范。

相关推荐
求学中--2 小时前
进阶实战:构建一个完整的微信小程序博客系统(含云开发与状态管理)
微信小程序·小程序
大肚子飞行员2 小时前
基于arthas的一次提升定时任务TPS总结
后端·性能优化
国科安芯5 小时前
车规MCU在农业无人机电机驱动中的可靠性分析
单片机·嵌入式硬件·性能优化·无人机·安全威胁分析·安全性测试
赵得C5 小时前
软件设计师前沿考点精讲:新兴技术与性能优化实战
java·开发语言·分布式·算法·设计模式·性能优化
计算机毕设指导65 小时前
基于微信小程序的宠物走失信息管理系统【源码文末联系】
java·spring boot·mysql·微信小程序·小程序·tomcat·宠物
小雨下雨的雨5 小时前
第7篇:Redis性能优化实战
数据库·redis·性能优化
古城小栈7 小时前
Java 应对 Rust 竞争的 性能优化策略
java·性能优化·rust
Wang's Blog7 小时前
Elastic Stack梳理: 生产环境部署与性能优化深度指南之从集群配置到读写调优实战
性能优化
拾忆,想起7 小时前
Dubbo服务注册与发现深度解析:微服务架构的“通讯录”与“导航系统”
微服务·云原生·性能优化·架构·dubbo·safari