You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel+Vue项目中正确加载tw-elements?

Laravel + Vue 3 集成 TW Elements 问题解决

问题概述

  • 已通过npm安装tw-elements,在app.js中导入后,使用带data-te-*属性的组件时无法正常渲染,无控制台报错
  • 出现TypeScript类型警告:No declaration file found for module 'tw-elements'. 'index.min.js' in 'c:/sites/ReservationSystem/node_modules/tw-elements/dist/js/' has an implicitly 'any' type.

解决步骤

1. 补全TW Elements资源引入

TW Elements需要同时引入CSS和JS资源,在app.js开头添加CSS导入:

import 'tw-elements/dist/css/tw-elements.min.css';

2. 正确初始化TW Elements

TW Elements不能直接通过Vue的use()方法注册,需要手动调用初始化方法,同时适配Inertia单页应用的页面切换场景:
修改app.js中的应用初始化部分,替换原有的.use(te),改为全局初始化+页面切换监听:

// 全局初始化TW Elements
te.default.init();

// 监听Inertia页面切换完成事件,重新初始化组件
document.addEventListener('inertia:page:finish', () => {
  te.default.init();
});

3. 消除TypeScript类型警告

在项目根目录创建resources/js/types/tw-elements.d.ts文件,添加如下内容:

declare module 'tw-elements' {
  const te: any;
  export default te;
}

然后在项目的tsconfig.json中更新include字段,确保类型文件被识别:

"include": [
  "resources/js/**/*",
  "resources/js/types/**/*"
]

4. 页面组件内确保初始化

在使用TW Elements组件的Vue页面的mounted钩子中,再次调用初始化方法,确保当前页面的组件被正确渲染:

mounted() {
  te.default.init();
}

修改后完整代码

app.js

import './bootstrap';
import '../css/app.css';
// 导入TW Elements样式文件
import 'tw-elements/dist/css/tw-elements.min.css';

import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m';
import { autoAnimatePlugin } from '@formkit/auto-animate/vue';
import VueClickAway from "vue3-click-away";
import * as te from 'tw-elements';

const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';

createInertiaApp({
  title: (title) => `${title} - ${appName}`,
  resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
  setup({ el, app, props, plugin }) {
    const vueApp = createApp({ render: () => h(app, props) })
      .use(plugin)
      .use(autoAnimatePlugin)
      .use(VueClickAway)
      .use(ZiggyVue, Ziggy)
      .mount(el);

    // 全局初始化TW Elements
    te.default.init();

    // Inertia页面切换后重新初始化
    document.addEventListener('inertia:page:finish', () => {
      te.default.init();
    });

    return vueApp;
  },
});

InertiaProgress.init({ color: '#4B5563' });

Vue页面组件

<template>
  <div class="flex justify-center">
    <div class="mb-3 xl:w-96">
      <select data-te-select-init data-te-select-filter="true">
        <option value="1">One</option>
        <option value="2">Two</option>
        <option value="3">Three</option>
      </select>
    </div>
  </div>
</template>
<script>
import AppLayout from "@/Layouts/AppLayout.vue";
import { defineComponent } from "vue";
import { directive } from "vue3-click-away";
import { Inertia } from "@inertiajs/inertia";
import JetInputError from "@/Components/InputError.vue";
import { Link } from "@inertiajs/inertia-vue3";
import { reactive } from "vue";
import { useAutoAnimate } from '@formkit/auto-animate/vue';
import * as te from 'tw-elements';

export default defineComponent({
  directives: {
    ClickAway: directive
  },
  props: {
    plans: Array,
  },
  components: {
    AppLayout,
    JetInputError,
    Link,
  },
  data() {
    return {}
  },
  setup() {
    const form = reactive({});

    function submit() {
      Inertia.post(route("reservas.store"), form, {
        onSuccess: () => {
          this.openForm = false;
        }
      });
    }
    return {
      form,
      submit
    };
  },
  mounted() {
    // 初始化当前页面的TW Elements组件
    te.default.init();
  },
  methods: {

  }
});
</script>

内容的提问来源于stack exchange,提问作者Andrés Felipe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 10:17:57