NervJS / taro

开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5/React Native 等应用。 https://taro.zone/
https://docs.taro.zone/
Other
35.58k stars 4.8k forks source link

微信小程序自定义tabBar npm run dev功能正常,npm run build后提示方法为undefined taro版本为3.4.12 #11975

Closed ccerlc closed 2 years ago

ccerlc commented 2 years ago

相关平台

微信小程序

复现仓库

https://github.com/ccerlc/custom-tabbar-vue3 小程序基础库: 2.24.6 使用框架: Vue 3

复现步骤

官方vue3模版改为不通过vuex实现,通过暴露方法改变tarbar菜单,仅贴JS代码部分

import Taro from '@tarojs/taro'
import { ref }  from 'vue'
const selected = ref(0);

const color = '#000000'
const selectedColor = '#DC143C'
const list = [
  {
    pagePath: '/pages/index/index',
    selectedIconPath: '../images/tabbar_home_on.png',
    iconPath: '../images/tabbar_home.png',
    text: '首页'
  },
  {
    pagePath: '/pages/cate/index',
    selectedIconPath: '../images/tabbar_cate_on.png',
    iconPath: '../images/tabbar_cate.png',
    text: '分类'
  },
  {
    pagePath: '/pages/cart/index',
    selectedIconPath: '../images/tabbar_cart_on.png',
    iconPath: '../images/tabbar_cart.png',
    text: '购物车'
  },
  {
    pagePath: '/pages/my/index',
    selectedIconPath: '../images/tabbar_my_on.png',
    iconPath: '../images/tabbar_my.png',
    text: '个人中心'
  }
]

function switchTab(index, url) {
  setSelected(index)
  Taro.switchTab({ url })
}

function setSelected (index) {
  selected.value = index
}

在包含tabbar的页面通过以下方式设置

onShow () {
    const pageObj = Taro.getCurrentInstance().page;
    const tabbar = Taro.getTabBar(pageObj);
    tabbar.setSelected(0);
  }

期望结果

期望能正确切换和选中tabbar,npm run dev 可以正确实现效果

实际结果

npm run build以后提示t.setSelected is not a function

环境信息

 Taro v3.4.12

  Taro CLI 3.4.12 environment info:
    System:
      OS: macOS 12.3
      Shell: 5.8 - /bin/zsh
    Binaries:
      Node: 16.15.0 - /usr/local/bin/node
      Yarn: 1.22.18 - /usr/local/bin/yarn
      npm: 8.9.0 - /usr/local/bin/npm
    npmPackages:
      @tarojs/components: 3.4.12 => 3.4.12 
      @tarojs/mini-runner: 3.4.12 => 3.4.12 
      @tarojs/runtime: 3.4.12 => 3.4.12 
      @tarojs/taro: 3.4.12 => 3.4.12 
      @tarojs/webpack-runner: 3.4.12 => 3.4.12 
      babel-preset-taro: 3.4.12 => 3.4.12 
      eslint-config-taro: 3.4.12 => 3.4.12 
Barrierml commented 2 years ago

webpack在打包时会自动分析依赖进行treeShaking, prod环境下setSelectedswitchTab没有被导出,也没有被其他任何文件所引入,自然就会被舍弃掉了。 在dev环境下可以运行的原因是因为 <script setup>模式 会把当前作用域下所有的变量,包括引入的变量作为setup的返回值返回,于是setSelectedswitchTab就被绑定在了page实例上可以调用。 解决这个问题其实就是需要让webpack不再对custom-tab-bar组件进行treeShaking。 可以这样改写

<script>
import Taro from "@tarojs/taro";
import { ref } from "vue";
const selected = ref(0);

const color = "#000000";
const selectedColor = "#DC143C";
const list = [
  {
    pagePath: "/pages/index/index",
    selectedIconPath: "../images/tabbar_home_on.png",
    iconPath: "../images/tabbar_home.png",
    text: "首页",
  },
  {
    pagePath: "/pages/cate/index",
    selectedIconPath: "../images/tabbar_cate_on.png",
    iconPath: "../images/tabbar_cate.png",
    text: "分类",
  },
  {
    pagePath: "/pages/cart/index",
    selectedIconPath: "../images/tabbar_cart_on.png",
    iconPath: "../images/tabbar_cart.png",
    text: "购物车",
  },
  {
    pagePath: "/pages/my/index",
    selectedIconPath: "../images/tabbar_my_on.png",
    iconPath: "../images/tabbar_my.png",
    text: "个人中心",
  },
];

function switchTab(index, url) {
  setSelected(index);
  Taro.switchTab({ url });
}

function setSelected(index) {
  selected.value = index;
}

export default {
  setup() {
    return {
      setSelected,
      switchTab,
      list,
      selectedColor,
      color,
      selected,
    };
  },
};
</script> 

手动导出setup变量,则局部变量不会被treeShaking,会完整的被export出去

ccerlc commented 2 years ago

webpack在打包时会自动分析依赖进行treeShaking, prod环境下setSelectedswitchTab没有被导出,也没有被其他任何文件所引入,自然就会被舍弃掉了。 在dev环境下可以运行的原因是因为 <script setup>模式 会把当前作用域下所有的变量,包括引入的变量作为setup的返回值返回,于是setSelectedswitchTab就被绑定在了page实例上可以调用。 解决这个问题其实就是需要让webpack不再对custom-tab-bar组件进行treeShaking。 可以这样改写

<script>
import Taro from "@tarojs/taro";
import { ref } from "vue";
const selected = ref(0);

const color = "#000000";
const selectedColor = "#DC143C";
const list = [
  {
    pagePath: "/pages/index/index",
    selectedIconPath: "../images/tabbar_home_on.png",
    iconPath: "../images/tabbar_home.png",
    text: "首页",
  },
  {
    pagePath: "/pages/cate/index",
    selectedIconPath: "../images/tabbar_cate_on.png",
    iconPath: "../images/tabbar_cate.png",
    text: "分类",
  },
  {
    pagePath: "/pages/cart/index",
    selectedIconPath: "../images/tabbar_cart_on.png",
    iconPath: "../images/tabbar_cart.png",
    text: "购物车",
  },
  {
    pagePath: "/pages/my/index",
    selectedIconPath: "../images/tabbar_my_on.png",
    iconPath: "../images/tabbar_my.png",
    text: "个人中心",
  },
];

function switchTab(index, url) {
  setSelected(index);
  Taro.switchTab({ url });
}

function setSelected(index) {
  selected.value = index;
}

export default {
  setup() {
    return {
      setSelected,
      switchTab,
      list,
      selectedColor,
      color,
      selected,
    };
  },
};
</script> 

手动导出setup变量,则局部变量不会被treeShaking,会完整的被export出去

问题已解决,感谢。 我也想到是export的问题,但是直接在setup script 导出,就会报错了。看来还是要对setup script进行好好理解。