当前位置:   article > 正文

微信小程序开发_微信小程序开发csdn

微信小程序开发csdn

1.微信小程序开发框架

1.1 框架说明

1.1.1 开发工具、调试工具

1.1.2 框架结构

使用vue-cli脚手架创建uni-app框架,vue3 + vite应用框架,uview-plusUI组件库,pinia状态管理器,pnpm依赖包管理。

nodeJs版本要求:^14.18.0 || >=16.0.0

npm:8.5.0 pnpm:6.32.6

vue/cli版本:@5.0.8 vue:^3.2.45 vite:^3.2.4

uview-plus:^3.1.26 pinia:^2.0.30

pnpm install -g @vue/cli vue create -p dcloudio/uni-preset-vue#vite 项目名

1.1.3 框架目录结构

  1. ┌─src
  2. │ ├─api 请求地址目录
  3. │ ├─assets 静态资源目录
  4. │ │ └─css 样式
  5. │ │ │ ├─common 公共样式、字体图标样式、uview组件库
  6. │ │ │ └─app.styl 全局样式引入
  7. │ │ └─icon-font 字体图标库
  8. │ └─common
  9. │ │ ├─http 网络请求封装
  10. │ │ ├─bus.js eventBus封装
  11. │ │ └─common.js 公共方法封装
  12. │ ├─component 公共组件
  13. │ ├─conf 系统配置文件
  14. │ ├─pages 主包目录
  15. │ ├─pagesAffairs 办事页面目录
  16. │ ├─pagesCommon 公用页面目录(办理流程、办事指南)
  17. │ ├─pagesIndex 首页页面目录
  18. │ ├─pagesServiced 服务页面目录
  19. │ ├─pagesUser 我的页面目录
  20. │ ├─plugins 插件引入
  21. │ │ └─uview.js uview-plusUI组件库
  22. │ ├─static 静态图片资源目录
  23. │ ├─stores pinia状态管理
  24. │ ├─utils 公用函数、工具目录
  25. │ ├─App.vue 应用配置,用来配置小程序全局样式以及监听、应用生命周期
  26. │ ├─main.js Vue初始化入口文件
  27. │ ├─manifest.json 配置应用名称、appid、logo、版本等打包信息
  28. │ ├─pages.json 配置页面路由、导航条、选项卡等页面类信息
  29. │─.editorconfig 统一代码编辑器配置
  30. │─.eslintignore 统一代码编辑器配置忽略文件
  31. │─.eslintrc.js eslint代码约束配置
  32. │─.gitignore git代码提交忽略文件
  33. │─.prettierrc.json 文件代码格式化配置
  34. │─index.html 静态资源目录
  35. │─jsconfig.json javascript根目录
  36. │─package.json 常见的配置有配置项目启动、打包命令,声明依赖包等
  37. │─pnpm-lock.yaml
  38. │─postcss.config.js css适配方案
  39. └─vite.config.js 项目打包、插件引入、编译相关配置

1.2 组件库

UI组件库: uview-plus@3.1.26

  1. // 安装命令
  2. pnpm install uview-plus@3.1.26

引入方式:

  1. // plugins/uview.js 初始化配置
  2. import uviewPlus from "uview-plus"
  3. export const $toast = (message) => {
  4. uni.$u.toast(message)
  5. }
  6. export default app => {
  7. app.provide('$toast', $toast)
  8. app.use(uviewPlus)
  9. }
  10. // main.js 主入口文件进行引用
  11. import uviewPlusFn from '@/plugins/uview'
  12. // 挂载uviewPlus
  13. uviewPlusFn(app)
  14. // App.vue 引入样式文件
  15. <style lang="scss" scope>
  16. // uview-plus
  17. @import 'uview-plus/index.scss';
  18. // 引入uview-plus主题
  19. @import 'uview-plus/theme.scss';
  20. </style>
  21. // 注意:uview-plus开发还不完善,小程序中相关组件样式不生效,存在报错,需在node_modules中手动引入主题样式
  22. // node_modules/-plus/libs/css/components.css中引入
  23. @import "../../theme.scss";

1.3 状态管理器

项目使用:pinia@2.0.30

  1. // 安装命令
  2. pnpm install pinia@3.1.26
  3. // 使用持久化存储-安装命令
  4. pnpm install pinia-plugin-persist

引入方式:

  1. // stores/index.js 初始化配置
  2. import { createPinia } from "pinia"
  3. import piniaPersist from 'pinia-plugin-persist'
  4. const store = createPinia()
  5. // 持久化存储 小程序暂不支持sessionStorage、localStorage所以不能使用
  6. store.use(piniaPersist)
  7. export function setupStore (app) {
  8. app.use(store)
  9. }
  10. export { store }
  11. // main.js 主入口文件进行引用
  12. import { setupStore } from './stores/index'
  13. // 挂载pinia
  14. setupStore(app))

使用方式:

  1. import { defineStore } from 'pinia'
  2. import { store } from "../index"
  3. export const userCommonStore = defineStore({
  4. id: 'common',
  5. state: () => {
  6. return {
  7. token: ''
  8. }
  9. },
  10. actions: {
  11. // token
  12. setToken (token) {
  13. this.token = token
  14. }
  15. },
  16. persist: {
  17. // 开启持久化存储
  18. enabled: true,
  19. // 自定义持久化参数
  20. strategies: [
  21. {
  22. // 自定义key,默认就是仓库的key
  23. key: 'token',
  24. // 自定义存储方式,默认sessionStorage
  25. storage: localStorage,
  26. // 指定要持久化的数据,默认所有 state 都会进行缓存,可以通过 paths 指定要持久化的字段,其他的则不会进行持久化。
  27. paths: ['token']
  28. }
  29. ]
  30. }
  31. })
  32. // 导出状态hook
  33. export function userCommonStoreHook () {
  34. return userCommonStore(store)
  35. }
  36. // vue文件使用
  37. import { userCommonStoreHook } from '@/stores/modules/common'
  38. <script>
  39. // 存储
  40. userCommonStoreHook().setToken('value')
  41. // 获取
  42. const token = userCommonStoreHook().token
  43. </script>

1.4 网络请求封装

项目使用:结合new Promise + uni.request(OBJECT)

相关配置方法:uniapp-request

系统配置:

  1. // conf/index.js 相关系统配置文件
  2. export const API = {
  3. // 开发环境
  4. development: {
  5. DEFAULT: 'http://192.168.1.246:19601/iframework' || import.meta.env.BASE_URL,
  6. JR: 'http://192.168.1.246:19601/iframework' || '/api', // 测试环境
  7. API: 'http://192.168.18.91:8001' // 第三方api
  8. },
  9. // 生产环境
  10. production: {
  11. DEFAULT: 'http://192.168.1.246:19601/iframework' || import.meta.env.BASE_URL,
  12. JR: 'http://192.168.1.246:19601/iframework' || '/api',
  13. API: 'http://192.168.18.91:8001' // 第三方api
  14. }
  15. }
  16. const isProd = import.meta.env.MODE === 'production'
  17. export const BASE_CONFIG = isProd ? API.production : API.development

使用方法:

  1. // common/http/http-async.js 目录文件
  2. 'use strict'
  3. import { API as configApi } from '@/conf/'
  4. import qs from 'querystring'
  5. import { getStorage, removeStorage } from '@/utils/storage'
  6. import { linkJump } from '@/common/common'
  7. import { userCommonStoreHook } from '@/stores/modules/common'
  8. // 获取接口根路径
  9. const isProd = import.meta.env.MODE === 'production'
  10. const BASE_PATH = isProd ? configApi.production : configApi.development
  11. export const request = (options) => {
  12. return new Promise((resolve, reject) => {
  13. let url = options.url
  14. // 简化类型设置
  15. const headers = {
  16. 'Content-Type': 'application/json; charset=UTF-8',
  17. 'Cookie': `JSESSIONID=${getStorage('JSESSIONID') || ''}`
  18. }
  19. // 提交表单类型
  20. if (options.isForm) {
  21. headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
  22. delete options.isForm
  23. }
  24. // 提交上传类型
  25. if (options.isFile) {
  26. headers['Content-Type'] = 'multipart/form-data; charset=UTF-8'
  27. delete options.isFile
  28. }
  29. // 校验post数据格式
  30. const contentTyoe = headers['Content-Type']
  31. if (
  32. typeof options.params === 'object' &&
  33. contentTyoe &&
  34. String(contentTyoe).indexOf('application/x-www-form-urlencoded') > -1
  35. ) {
  36. options.params = qs.stringify(options.params)
  37. }
  38. // 添加token
  39. if (userCommonStoreHook().token) {
  40. headers['token'] = userCommonStoreHook().token
  41. }
  42. // 设置请求路径
  43. options.url = BASE_PATH[options.apiType || 'JR'] + url
  44. console.log('url', options, options.params)
  45. uni.request({
  46. url: options.url,
  47. method: options.method,
  48. data: options.params,
  49. withCredentials: true,
  50. header: headers,
  51. success (response) {
  52. const status = +response.statusCode
  53. const data = response.data || {}
  54. if (status === 200 || status === 304) {
  55. // 第三方api接口判断
  56. if (data.statusCode === 200 && options.url.indexOf('api.jsp')) {
  57. if (data.statusCode === 200) {
  58. resolve(data)
  59. } else {
  60. uni.$u.toast(data.msg || '')
  61. reject(data)
  62. }
  63. return
  64. }
  65. if (data.id === 500) {
  66. uni.$u.toast(data.msg || '')
  67. // 退出登录
  68. userCommonStoreHook().clearOut()
  69. } else if (data.id === '01') {
  70. resolve(data)
  71. } else if (data.id === '02' && data.msg === 'token不能为空') {
  72. uni.$u.toast(data.msg || '')
  73. // 退出登录
  74. userCommonStoreHook().clearOut()
  75. } else {
  76. uni.$u.toast(data.msg || '')
  77. reject(data)
  78. }
  79. } else if (status === 404) {
  80. linkJump('/pages/404/index')
  81. reject(data)
  82. } else {
  83. reject(data)
  84. }
  85. },
  86. fail (error) {
  87. if (err.errMsg === 'request:fail timeout') {
  88. uni.$u.toast('请求超时,请重试')
  89. } else if (err.errMsg === 'request:fail ') {
  90. uni.$u.toast('无网络')
  91. } else {
  92. uni.$u.toast('服务器繁忙' || error.errMsg)
  93. }
  94. reject(error)
  95. }
  96. })
  97. })
  98. }

请求调用:

  1. 'use strict'
  2. import { request } from '@/common/http/http-async'
  3. export const login = (params = {}) => {
  4. const param = {
  5. apiType: 'JR',
  6. method: 'post',
  7. json: true,
  8. url: '/api/internet/login',
  9. params: params
  10. }
  11. return request(param)
  12. }
  13. // 第三方api调用
  14. export const getChannelIdList = (params = {}) => {
  15. const param = {
  16. apiType: 'API',
  17. method: 'get',
  18. json: true,
  19. url: '/api.jsp',
  20. params: params
  21. }
  22. return request(param)
  23. }
  24. // vue文件使用
  25. import { getChannelIdList } from '@/api/index'
  26. let params = {}
  27. getChannelIdList(params).then((result) => {}).catch((err) => {})

1.5 .eslintrc.js和.prettierrc配置

  1. // .eslintrc.js
  2. module.exports = {
  3. // 默认情况下,ESLint会在所有父级组件中寻找配置文件,一直到根目录。ESLint一旦发现配置文件中有 "root": true,它就会停止在父级目录中寻找。
  4. root: true,
  5. env: {
  6. node: true,
  7. es6: true,
  8. 'vue/setup-compiler-macros': true
  9. },
  10. extends: [
  11. 'plugin:vue/vue3-essential',
  12. 'eslint:recommended',
  13. 'prettier',
  14. '@vue/prettier',
  15. 'plugin:prettier/recommended'
  16. ],
  17. plugins: ['prettier'],
  18. // 对Babel解析器的包装使其与 ESLint 兼容。
  19. parserOptions: {
  20. ecmaVersion: 2020,
  21. parse: 'babel-eslint',
  22. // 代码是 ECMAScript 模块
  23. sourceType: 'module'
  24. },
  25. // 去掉校验
  26. globals: {
  27. Atomics: 'readonly',
  28. SharedArrayBuffer: 'readonly',
  29. defineProps: 'readonly',
  30. defineEmits: 'readonly',
  31. defineExpose: 'readonly',
  32. withDefaults: 'readonly'
  33. },
  34. rules: {
  35. 'prettier/prettier': 'error',
  36. 'arrow-body-style': 'off',
  37. 'prefer-arrow-callback': 'off',
  38. // 关闭名称校验
  39. 'vue/multi-word-component-names': 'off'
  40. }
  41. }
  42. // .prettierrc.json 代码格式化配置
  43. {
  44. "semi": false,
  45. "eslintIntegration": true,
  46. "singleQuote": true,
  47. "endOfLine": "lf",
  48. "tabWidth": 2,
  49. "trailingComma": "none",
  50. "bracketSpacing": true,
  51. "arrowParens": "avoid"
  52. }

2. 项目避坑

2.1 包js文件超过2MB无法运行

原因:微信官方对小程序的体积大小有硬性要求,上限为2048KB

处理方法:

  • 分包
  • 优化代码,删除掉不用的代码
  • 图片压缩或者上传服务器
  1. // manifest.json 相关配置
  2. "mp-weixin": {
  3. // 开启分包优化
  4. "optimization": {
  5. "subPackages": true
  6. }
  7. }
  8. // pages.json 路径配置
  9. // 分包
  10. "subPackages": [
  11. {
  12. "root": "pagesCommon",
  13. "name": "pagesCommon",
  14. "pages": [
  15. {
  16. "path": "handle-event/index",
  17. "style": {
  18. "navigationBarTitleText": "办事",
  19. "enablePullDownRefresh": true,
  20. "navigationStyle": "custom"
  21. }
  22. }
  23. ]
  24. },
  25. {
  26. "root": "pagesIndex",
  27. "name": "pagesIndex",
  28. "pages": [
  29. {
  30. "path": "notice-list/index",
  31. "style": {
  32. "navigationBarTitleText": "通知公告",
  33. "enablePullDownRefresh": true,
  34. "navigationStyle": "custom"
  35. }
  36. },
  37. {
  38. "path": "problem-list/index",
  39. "style": {
  40. "navigationBarTitleText": "常见问题",
  41. "enablePullDownRefresh": true,
  42. "navigationStyle": "custom"
  43. }
  44. },
  45. {
  46. "path": "notice-detail/index",
  47. "style": {
  48. "navigationBarTitleText": "通知公告详情",
  49. "enablePullDownRefresh": true,
  50. "navigationStyle": "custom"
  51. }
  52. }
  53. ]
  54. }
  55. }

2.2 图片生产环境无法预览

原因:微信小程序background-image只能用网络url或者base64图片编码

处理方法:

  • 使用https协议的cdn线上地址访问静态资源(放到服务器访问)
  • 通过base64图片访问
  1. /**
  2. * 本地图片转换base64
  3. * @param {*} folder 文件夹名称
  4. * @param {*} fileName 文件名称
  5. * @param {*} format 文件后缀
  6. */
  7. export const getLocalImgToBase64 = (folder, fileName, format = 'png') => {
  8. let imgUrl = `/static/${folder}/${fileName}.${format}`
  9. let base64 = uni.getFileSystemManager().readFileSync(imgUrl, 'base64')
  10. return `data:image/png;base64,${base64}`
  11. }
  12. // 使用
  13. :style="{ backgroundImage: `url(${getLocalImgToBase64('文件夹名称', '文件名', 'png')})`}"
  14. // 小程序图片模糊失真处理(作用于image图片)
  15. image-rendering -moz-crisp-edges
  16. image-rendering -o-crisp-edges
  17. image-rendering -webkit-optimize-contrast // 设置图像缩放算法
  18. image-rendering crisp-edges // 缩放后不会变模糊
  19. -ms-interpolation-mode nearest-neighbor

2.3 无法显示彩色图标,兼容微信小程序

下载字体包

  1. 安装插件
  1. // 安装插件
  2. cnpm install -g iconfont-tools
  3. // 进入到文件夹里面用cmd执行下列命令
  4. iconfont-tools

  1. // main.js
  2. // 引入阿里彩色矢量字体
  3. @import '@/assets/icon-font/iconfont.css'

2.4 字体图标显示空白或者报错

下载字体包

ttf文件转换成base64格式,转换地址:transfonter.org

  1. 将下载后的iconfont.ttf文件引入
  1. @font-face {
  2. font-family 'iconfont'
  3. src url('../../icon-font/iconfont.woff') format('woff'), url('../../icon-font/iconfont.woff2') format('woff2'), url('base64编码') format('truetype')
  4. .iconfont {
  5. font-family 'iconfont' !important
  6. font-size 45rpx
  7. font-style normal
  8. // 抗锯齿
  9. -webkit-font-smoothing antialiased
  10. -moz-osx-font-smoothing grayscale
  11. }
  12. .icon-jiantou-zuo:before {
  13. content: "\e71b";
  14. }

3. 打包

pnpm run build:mp-weixin

登录微信公众平台,设置 > 账号信息 > AppID,获取到ID后打开微信开发者工具,扫码登录需要发布小程序的微信,右侧基本信息,绑定AppId

  1. 上传代码,代码包不能超过2MB

打开微信公众平台,设置项目成员、体验成员

修改打开页面路径

如需发布上线,点击提交审核即可

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/682736
推荐阅读
相关标签
  

闽ICP备14008679号