Bootstrap

Vite + Vue3 +Vant4构建项目时,按需引入使用Toast组件,引用 showToast 时出现编译报错的解决方案

Vite + Vue3 +Vant4构建项目时,按需引入使用Toast组件,引用 showToast 时出现编译报错的解决方案

一.问题定位

在Vite + Vue3 +Vant4构建项目时,需要使用Toast组件显示提示信息,按照官方文档使用函数调用

/**函数调用
*为了便于使用 Toast,Vant 提供了一系列辅助函数,通过辅助函数可以快速唤起全局的 Toast 组件。
*比如使用 showToast 函数,调用后会直接在页面中渲染对应的轻提示。
*/

import { showToast } from 'vant';

showToast('提示内容');

使用后直接报错,说是找不到对应的样式文件(如下图):

请添加图片描述

在项目中查找node-moudles文件,确实没有找到,只有一个toast文件(如下图):

请添加图片描述

在百度搜索解决方法,说是需要单独引入以下样式文件:
请添加图片描述

但是,引用完之后依然报错,不管用。

继续查看官方文档,发现在官方文档最下方的常见问题里有解决方法:

Vant 从 4.0 版本开始不再支持 babel-plugin-import 插件,请参考 迁移指南 移除该插件。

请添加图片描述

请添加图片描述

按照官方文档说明,移除 babel-plugin-import插件,结果在项目中根本没使用该插件,到此为止,问题依然没有解决。



后来经过仔细观察发现,在项目文件vite.config.js中按需引入vant4时使用到了 vite-plugin-style-import 这个插件,

请添加图片描述

此时的 name 参数 其实就是 引入vant 组件的大括号内的名称,对比报错截图

请添加图片描述

既然show-toast/style/index找不到,那不妨直接修改路径 ,改为 toast/style/index

resolveStyle: (name) => {
          if (name == 'show-toast') {
            return `../es/toast/style/index`; //修改vant show-toast引入路径
          } else {
            return `../es/${name}/style/index`; //修改vant引入路径
          }
        },

修改后果然不再报错,局部注册和全局注册均正常:

请添加图片描述
请添加图片描述

二.以下为完整解决代码:

局部引入Toast

1.vite.config.js

import {
  defineConfig
} from 'vite';
import vue from '@vitejs/plugin-vue';
import {
  resolve
} from 'path'; //引入路径
import styleImport, {
  VantResolve
} from 'vite-plugin-style-import'; //按需引入插件

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    styleImport({
      resolves: [VantResolve()], //引入vant
      libs: [{
        libraryName: "vant",
        esModule: true,
        resolveStyle: (name) => {
           if (name == 'show-toast') {
             return `../es/toast/style/index`; //修改vant引入路径
           } else {
             return `../es/${name}/style/index`; //修改vant引入路径
           }
         },
      }],
    }),
  ],
})

2.在使用组件的页面

<template>
  <div class="container" style="padding-top: 30px">
    <div style="display: flex; justify-content: center">
      <van-button type="primary" @click="showLocalToast"
        >显示局部toast消息</van-button
      >
    </div>
  </div>
</template>

<script setup>
import { ref, getCurrentInstance, onMounted } from "vue";
import { showToast } from "vant";//引入showToast

const showLocalToast = () => {
  showToast("我是局部toast消息");
};
</script>
全局引入Toast

1.vite.config.js

import {
  defineConfig
} from 'vite';
import vue from '@vitejs/plugin-vue';
import {
  resolve
} from 'path'; //引入路径
import styleImport, {
  VantResolve
} from 'vite-plugin-style-import'; //按需引入插件

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    styleImport({
      resolves: [VantResolve()], //引入vant
      libs: [{
        libraryName: "vant",
        esModule: true,
        resolveStyle: (name) => {
           if (name == 'show-toast') {
             return `../es/toast/style/index`; //修改vant引入路径
           } else {
             return `../es/${name}/style/index`; //修改vant引入路径
           }
         },
      }],
    }),
  ],
})

2.在main.js全局引入

import {
    createApp
} from 'vue'
import App from './App.vue'

// 按需引入vant组件
import {
    showToast,
} from 'vant';
const app = createApp(App);
app.config.globalProperties.$toast = showToast; //全局使用showToast组件

app.mount('#app')

3.在使用组件的页面

<template>
  <div class="container" style="padding-top: 30px">
   <div style="display: flex; justify-content: center; margin-top: 50px">
      <van-button type="success" @click="showGlobalToast"
        >显示全局toast消息</van-button
      >
    </div>
  </div>
</template>

<script setup>
import { ref, getCurrentInstance, onMounted } from "vue";
const instance = getCurrentInstance(); //获取当前实例对象
const _this = instance.appContext.config.globalProperties; //vue3获取当前this
const showGlobalToast = () => {
  _this.$toast("我是全局注册消息");
};
</script>
;