小程序开发:开启定制化custom-tab-bar但不生效问题,以及使用NutUI-React Taro的安装和使用

在开发微信小程序时,发现使用webpack可以自动识别使用定制的custom-tab-bar,而使用vite则不能走定制的现象。这是在 微信小程序 里,custom-tab-bar 是否能生效,并不是框架层(React / Vue / Taro / ...)直接决定的,而是 编译工具链对小程序配置的支持程度 不一样导致的。

一、custom-tab-bar问题

这是常见的app.config.ts的配置,导航栏样式和tabBar都是走的定制化。

javascript 复制代码
export default defineAppConfig({
  pages: ['pages/index/index', 'pages/about/index'],
  subPackages: [
    {
      root: 'subpackages/login',
      pages: ['index']
    }
  ],
  window: {
    navigationStyle: 'custom'
    // backgroundTextStyle: 'light',
    // navigationBarBackgroundColor: '#fff',
    // navigationBarTitleText: 'WeChat',
    // navigationBarTextStyle: 'black'
  },
  tabBar: {
    custom: true,
    color: '#333',
    selectedColor: '#058fae',
    list: [
      {
        pagePath: 'pages/index/index',
        text: '首页',
        iconPath: 'assets/images/tabBar/icon1.png',
        selectedIconPath: 'assets/images/tabBar/icon1-active.png'
      },

      {
        pagePath: 'pages/about/index',
        text: '关于',
        iconPath: 'assets/images/tabBar/icon2.png',
        selectedIconPath: 'assets/images/tabBar/icon2-active.png'
      }
    ]
  },
  usingComponents: {},
  lazyCodeLoading: 'requiredComponents'
});

1. Webpack 场景

Taro + Webpack 这样的方案,官方在构建时会把 app.json 里的

javascript 复制代码
"tabBar": {
  "custom": true,
  "list": [...]
}

以及 custom-tab-bar 目录下的代码一并编译进产物,微信小程序就能识别并使用自定义 tab bar。

2. Vite 场景

目前(尤其是 Taro Vite 模式),Vite 插件对小程序 非页面/组件目录 的处理不完整:

  • custom-tab-bar 目录不会被默认打包

  • 导致运行时找不到 custom-tab-bar/index,从而退回使用原生 tab bar

所以表现就是:Webpack 能跑,Vite 不能跑。

3. 解决方案

如果要在 Vite 模式下使用自定义 tabbar ,需要额外配置。完整的 vite.config.ts 示例 ,包含了 custom-tab-bar 的处理配置。这样在 Vite 模式 下打包时,会自动把 src/custom-tab-bar 目录复制到小程序 dist 目录中,微信就能正常识别自定义 tabbar。(注意custom-tab-bar文件位置一定是在src下和page同级,这是官网定义的)

javascript 复制代码
import { defineConfig } from 'vite'
import { viteStaticCopy } from 'vite-plugin-static-copy'

export default defineConfig({
  plugins: [
    viteStaticCopy({
      targets: [
        {
          src: 'src/custom-tab-bar', // custom-tab-bar 源目录
          dest: ''                   // 复制到 dist/custom-tab-bar
        }
      ]
    })
  ],
  build: {
    outDir: 'dist', // 小程序编译输出目录
    emptyOutDir: true
  }
})

二、推荐使用京东NutUI-React Taro开发小程序(推荐方式一,简单方便)

官网步骤:NutUI-React Taro

安装 Taro 脚手架

bash 复制代码
# pnpm
pnpm install -g @tarojs/cli
# npm
npm install -g @tarojs/cli
# yarn
yarn global add @tarojs/cli

方式一:使用 Taro 内置的 NutUI 模板快速创建项目

1、使用命令创建 Taro 项目:
复制代码
taro init
2、参考下方操作,选择 NutUI React 模板
复制代码
👽 Taro

Taro 即将创建一个新项目!
Need help? Go and open issue: https://tls.jd.com/taro-issue-helper

? 请输入项目名称! MyProject
? 请输入项目介绍
? 请选择框架 React
? 是否需要使用 TypeScript ? Yes
? 请选择 CSS 预处理器(Sass/Less/Stylus) Sass
? 请选择编译工具 Webpack5
? 请选择包管理工具 pnpm
? 请选择模板源 Github(最新)
✔ 拉取远程模板仓库成功!
  默认模板
  harmony
  mobx
  pwa
❯ react-NutUI(使用 NutUI React 的模板)
  react-native
  ......

方式二:在已有 Taro 项目中引入 NutUI React

1、安装 NutUI React
复制代码
# pnpm
pnpm add @nutui/nutui-react-taro
# npm
npm i @nutui/nutui-react-taro
# yarn
yarn add @nutui/nutui-react-taro
2、Taro 相关配置

安装 @tarojs/plugin-html

注意,这里安装的版本 version 必须与项目中 Taro 版本保持一致!

复制代码
# pnpm
pnpm add @tarojs/plugin-html@version
# yarn
yarn add @tarojs/plugin-html@version
# npm
npm i @tarojs/plugin-html@version

在项目中配置

javascript 复制代码
// config/index.js
config = {
  // 开启 HTML 插件
  plugins: ['@tarojs/plugin-html'],
  designWidth(input) {
    // 配置 NutUI 375 尺寸
    if (input?.file?.replace(/\\+/g, '/').indexOf('@nutui') > -1) {
      return 375
    }
    // 全局使用 Taro 默认的 750 尺寸
    return 750
  },
  deviceRatio: {
    640: 2.34 / 2,
    750: 1,
    828: 1.81 / 2,
    375: 2 / 1,
  },
}
3、组件使用与按需引入

您可以选择全量引入样式文件:

javascript 复制代码
// 默认主题
import '@nutui/nutui-react-taro/dist/style.css'
// 默认主题暗黑模式
// import '@nutui/nutui-react-taro/dist/style.css'
// JMAPP 主题
// import '@nutui/nutui-react-taro/dist/style-jmapp.css'
// JRKF 主题
// import '@nutui/nutui-react-taro/dist/style-jrkf.css'
3.1、通过插件实现按需引入

需要注意的是,在手动按需加载时,你还需要在入口文件中引入 global 类的文件来加载一些 NutUI React Taro 的全局性逻辑和样式:

javascript 复制代码
// css 主题文件路径
// 默认主题
import '@nutui/nutui-react-taro/dist/styles/themes/default.css'
// 默认暗黑主题
// import '@nutui/nutui-react-taro/dist/styles/themes/default-dark.css'
// JMAPP 主题
// import '@nutui/nutui-react-taro/dist/styles/themes/jmapp.css'
// JRKF 主题
// import '@nutui/nutui-react-taro/dist/styles/themes/jrkf.css'

// scss 主题文件路径
// 默认主题
// import '@nutui/nutui-react-taro/dist/styles/theme-default.scss'
// 默认暗黑主题
// import '@nutui/nutui-react-taro/dist/styles/theme-dark.scss'
// JMAPP 主题
// import '@nutui/nutui-react-taro/dist/styles/theme-jmapp.scss'
// JRKF 主题
// import '@nutui/nutui-react-taro/dist/styles/theme-jrkf.scss'

首先安装 babel-plugin-import 插件

复制代码
# pnpm
pnpm add babel-plugin-import
# npm
npm i babel-plugin-import
# yarn
yarn add babel-plugin-import

入口文件需要引入全局样式

javascript 复制代码
// app.js

// css 主题文件路径
// 默认主题
import '@nutui/nutui-react-taro/dist/styles/themes/default.css'
// 默认暗黑主题
// import '@nutui/nutui-react-taro/dist/styles/themes/default-dark.css'
// JMAPP 主题
// import '@nutui/nutui-react-taro/dist/styles/themes/jmapp.css'
// JRKF 主题
// import '@nutui/nutui-react-taro/dist/styles/themes/jrkf.css'

// scss 主题文件路径
// 默认主题
// import '@nutui/nutui-react-taro/dist/styles/theme-default.scss'
// 默认暗黑主题
// import '@nutui/nutui-react-taro/dist/styles/theme-dark.scss'
// JMAPP 主题
// import '@nutui/nutui-react-taro/dist/styles/theme-jmapp.scss'
// JRKF 主题
// import '@nutui/nutui-react-taro/dist/styles/theme-jrkf.scss'

babel 相关配置:

javascript 复制代码
// babel.config.js
module.exports = {
  presets: [
    // ...
  ],
  plugins: [
    [
      'import',
      {
        libraryName: '@nutui/nutui-react-taro',
        camel2DashComponentName: false,
        customName: (name, file) => {
          return `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}`
        },
        // 自动加载 scss 样式文件
        customStyleName: (name) =>
          `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style`,
        // 自动加载 css 样式文件
        // customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style/css`

        // JMAPP 主题
        // 自动加载 scss 样式文件
        // customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style-jmapp`,
        // 自动加载 css 样式文件
        // customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style-jmapp/css`

        // jrkf 端主题
        // 自动加载 scss 样式文件
        // customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style-jrkf`,
        // 自动加载 css 样式文件
        // customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style-jrkf/css`
      },
      'nutui-react',
    ],
  ],
}

若您的项目采用 scss,则需要在 config/index 中增加如下配置:

javascript 复制代码
{
  sass: {
    data: '@import "@nutui/nutui-react-taro/dist/styles/variables.scss";'
    // JMAPP 主题
    // data: `@import '@nutui/nutui-react-taro/dist/styles/variables-jmapp.scss';`
    // JRKF 主题
    // data: `@import '@nutui/nutui-react-taro/dist/styles/variables-jrkf.scss';`
  }
}

注意事项

1、检查 Taro 是否安装成功
复制代码
taro -v

出现 Taro 版本号说明安装成功。

2、安装 Taro 过程中出现 Saas 相关错误

可以考虑安装 mirror-config-china 后重试。

复制代码
npm install -g mirror-config-china
3、小程序项目运行时出现「找不到模板」的错误提示

解决方案:在 Taro 配置文件中关闭 prebundle 及 cache

javascript 复制代码
// config/index.js
config = {
  compiler: {
    type: 'webpack5',
    prebundle: {
      exclude: ['@nutui/nutui-react-taro', '@nutui/icons-react-taro'],
    },
  },
  cache: {
    enable: false,
  },
}
4、样式单位转化

组件 CSS 单位使用的是 px ,但是在 Taro 编译时,Taro 会帮你对样式做尺寸转换操作,需要注意的是,要对 NutUI 相关的样式设置在黑名单里,如:

javascript 复制代码
// config/index.js
config = {
  h5: {
    postcss: {
      pxtransform: {
        enable: true,
        // 包含 `nut-` 的类名选择器中的 px 单位不会被解析
        config: { selectorBlackList: ['nut-'] },
      },
    },
  },
}

三、总结

使用NutUI-React Taro,操作简单易上手,开发简洁快速。根据步骤即可,也不会出现custom-tab-bar不生效问题。选用的是webpack,scss和less可根据自己习惯选用那个。

  • Webpack 是官方长期维护的稳定方案,能自动识别 custom-tab-bar

  • Vite 模式下需要 手动处理 custom-tab-bar 的输出升级 Taro 插件

相关推荐
weixin_lynhgworld4 小时前
淘宝扭蛋机小程序的社交化运营策略
大数据·小程序·扭蛋机
低代码布道师6 小时前
少儿舞蹈小程序(20):手机号登录与多角色注册
低代码·小程序
说私域6 小时前
基于开源AI智能名片的S2B2C商城小程序中搜索联想功能的优化策略研究
人工智能·小程序
2501_9160074716 小时前
iOS 混淆与团队协作,研发、安全、运维、测试如何在加固流程中高效配合(iOS 混淆、ipa 加固、协作治理)
android·ios·小程序·https·uni-app·iphone·webview
2501_916008891 天前
iOS 不上架怎么安装?多种应用分发方式解析,ipa 文件安装、企业签名、Ad Hoc 与 TestFlight 实战经验
android·macos·ios·小程序·uni-app·cocoa·iphone
CRMEB定制开发1 天前
PHP多商户接入阿里云识图找商品
android·阿里云·小程序·php·商城系统·微信商城·crmeb
00后程序员张1 天前
iOS App 混淆实战,在源码不可用情况下的成品加固与测试流程
android·ios·小程序·https·uni-app·iphone·webview
说私域1 天前
基于开源AI智能名片与链动2+1模式的S2B2C商城小程序研究:构建“信息找人”式精准零售新范式
人工智能·小程序·开源
知识分享小能手1 天前
微信小程序入门学习教程,从入门到精通,微信小程序页面交互 —— 知识点详解与案例实现(3)
前端·javascript·学习·react.js·微信小程序·小程序·交互