小程序开发skill入门指南:从零到上线的完整避坑手册

2次阅读
没有评论

共计 3103 个字符,预计需要花费 8 分钟才能阅读完成。

image.webp

背景痛点:新手常踩的三大坑

最近帮几个朋友排查小程序问题,发现新手常在这些地方翻车:

小程序开发 skill 入门指南:从零到上线的完整避坑手册

  1. 开发环境配置
  2. 微信开发者工具突然报错,需要清除缓存重装
  3. npm 包安装后构建失败,版本冲突频繁

  4. API 调用混乱

  5. wx.login 拿到 code 后不知道要传给后端
  6. 获取用户信息时没处理拒绝授权的情况

  7. 调试困难

  8. 真机预览时样式错乱
  9. 安卓机上页面卡顿找不到原因

框架选型:别急着写代码

先看看主流方案对比:

方案 优势 劣势
原生开发 官方支持好,性能最优 多端需重复开发
Taro React 语法,生态丰富 复杂项目编译略慢
uni-app 跨端能力强,文档完善 自定义组件略繁琐

决策建议
– 只要做微信小程序 → 选原生
– 需要兼容 H5/APP → uni-app
– 团队熟悉 React → Taro

核心实现:这些代码要背下来

Page 生命周期管理

// 用 TS 定义页面数据类型
interface IData {list: any[]
  loading: boolean
}

Page<IData>({
  data: {list: [],
    loading: true
  },

  async onLoad() {
    // 异步数据处理示例
    try {const res = await this.fetchData()
      this.setData({ 
        list: res.data,
        loading: false
      })
    } catch (error) {console.error('数据加载失败', error)
    }
  },

  fetchData(): Promise<any> {return new Promise((resolve) => {
      wx.request({
        url: 'https://api.example.com/list',
        success: resolve
      })
    })
  }
})

请求封装实战

class ApiClient {
  private static instance: ApiClient
  private retryCount = 0

  static getInstance() {if (!ApiClient.instance) {ApiClient.instance = new ApiClient()
    }
    return ApiClient.instance
  }

  /**
   * 带 Token 刷新的请求封装
   * @param options 请求参数
   * @param maxRetry 最大重试次数 
   */
  async request(options: WechatMiniprogram.RequestOption, maxRetry = 3) {
    // 先从缓存获取 token
    let token = wx.getStorageSync('token')

    return new Promise((resolve, reject) => {
      const finalOptions = {
        ...options,
        header: {'Authorization': `Bearer ${token}`,
          ...options.header
        }
      }

      wx.request({
        ...finalOptions,
        success: (res) => {if (res.statusCode === 401) {this.refreshToken().then(() => {
              this.retryCount++
              if (this.retryCount <= maxRetry) {return this.request(options, maxRetry)
              }
              reject(new Error('授权失败'))
            })
          } else {resolve(res.data)
          }
        },
        fail: reject
      })
    })
  }
}

性能优化:让你的小程序飞起来

图片懒加载实战

在 page.json 中配置:

{
  "usingComponents": {"lazy-image": "/components/lazy-image"}
}

组件实现:

Component({
  properties: {
    src: String,
    placeholder: {
      type: String,
      value: '/assets/placeholder.png'
    }
  },

  data: {loaded: false},

  observers: {'src': function(src) {if (!src) return

      const observer = wx.createIntersectionObserver(this)
      observer.relativeToViewport({bottom: 300}).observe('.image', (res) => {if (res.intersectionRatio > 0 && !this.data.loaded) {this.setData({ loaded: true})
          observer.disconnect()}
      })
    }
  }
})

setData 优化策略

错误示范:

// 频繁触发渲染
this.setData({a: 1})
this.setData({b: 2})
this.setData({c: 3})

正确做法:

// 合并更新
this.setData({
  a: 1,
  b: 2,
  c: 3
})

原理 :小程序底层会对 setData 做 diff 计算,合并操作能减少通信次数。

避坑指南:血泪经验总结

处理用户拒绝授权

// 获取用户信息的安全写法
function getUserProfile() {return new Promise((resolve) => {
    wx.getUserProfile({
      desc: '用于完善会员资料',
      success: resolve,
      fail: () => {
        wx.showToast({
          title: '授权后可获得完整功能',
          icon: 'none'
        })
        // 降级方案:使用默认头像
        resolve({ 
          userInfo: {avatarUrl: '/assets/default-avatar.png'}
        })
      }
    })
  })
}

样式兼容技巧

/* 安卓按钮默认有灰色背景 */
button::after {display: none;}

/* iOS 滚动更流畅 */
scroll-view {-webkit-overflow-scrolling: touch;}

代码规范:专业团队的秘密

ESLint 配置示例

module.exports = {
  env: {
    browser: true,
    es6: true
  },
  extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
  parser: '@typescript-eslint/parser',
  rules: {
    '@typescript-eslint/explicit-function-return-type': 'off',
    'no-unused-vars': 'warn'
  }
}

单元测试示例

// 测试自定义组件
import {mount} from '@vue/test-utils'
import MyComponent from '@/components/my-component.vue'

describe('MyComponent', () => {it('渲染带 props 的组件', () => {
    const wrapper = mount(MyComponent, {
      propsData: {title: '测试标题'}
    })
    expect(wrapper.text()).toContain('测试标题')
  })
})

延伸思考

试着实现这些进阶需求:
1. 如何让图片组件支持 WebP 自动降级?
2. 设计一个全局错误监控系统
3. 实现页面预加载策略

完整 Demo 已放在 GitHub: 小程序实战 Demo 仓库 (包含所有示例代码)

刚开始可能会觉得配置繁琐,但坚持规范后会发现后期维护效率大幅提升。遇到问题多看官方文档,善用开发者工具的调试功能,祝你少走弯路!

正文完
 0
评论(没有评论)