网站搜索

vue.js - 在 Inertia.js + Laravel + Typescript + Vue 3 应用中“App”变量出错


我正在尝试使用以下技术栈搭建一个新的 Laravel 8 项目:Laravel 8 + Inertia.js + Vue.js 3 + Typescript(以及 TailwindCSS,不过尚未配置)。

出于某种原因,我在 app.ts 文件中传递给 setup 函数的“App”变量上遇到了一个奇怪的错误,它在 VSCode 中被高亮显示,当我将鼠标悬停上去时,它显示

Property 'App' does not exist on type '{ el: Element; app: InertiaApp; props: InertiaAppProps; plugin: Plugin_2; }'.ts(2339)

它一定是一些愚蠢的东西,一如既往,但我就是弄不清楚那是什么。

我正在按照这个教程 https://laravel-news.com/typescript-laravel 和 Inertia.js 文档 https://inertiajs.com/client-side-setup 学习

我感激任何帮助,谢谢。

------------------------------ 资源/js/app.ts

import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/inertia-vue3'

createInertiaApp({
  resolve: name => require(`./Pages/${name}`),
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el)
  },
})

------------------------------ Index.vue

<template>
    <div>Isaac</div>
</template>

<script lang="ts">
    import { defineComponent } from 'vue'

    export default defineComponent({
        setup() {
            
        }
    })
</script>

------------------------------ tsconfig.json

{
    "compilerOptions": {
      "target": "es5",
      "module": "es2020",
      "moduleResolution": "node",
      "baseUrl": "./",
      "strict": true,                 // Enable strict type-checking options
      "skipLibCheck": true,           // Skip type checking of declaration files
      "noImplicitAny": false          // Bypass raising errors on `any` type
    },
    "include": ["resources/js/**/*"]  // Frontend paths pattern
  }

------------------------------ webpack.mix.js

const mix = require('laravel-mix');

mix.js('resources/js/app.ts', 'public/js').vue({version: 3})
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]);

------------------------------ package.json

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    },
    "devDependencies": {
        "@vue/compiler-sfc": "^3.2.20",
        "axios": "^0.21",
        "laravel-mix": "^6.0.6",
        "lodash": "^4.17.19",
        "postcss": "^8.1.14",
        "ts-loader": "^9.2.6",
        "typescript": "^4.4.4",
        "vue-loader": "^16.8.1"
    },
    "dependencies": {
        "@inertiajs/inertia": "^0.10.1",
        "@inertiajs/inertia-vue3": "^0.5.2",
        "@inertiajs/progress": "^0.2.6",
        "vue": "^3.2.20"
    }
}

------------------------------ 运行 “sail npm run watch” 后出错

ERROR in ./resources/js/Pages/Dashboard/Index.vue?vue&type=template&id=48cd2f5e&ts=true (./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/Pages/Dashboard/Index.vue?vue&type=template&id=48cd2f5e&ts=true)
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /var/www/html/resources/js/Pages/Dashboard/Index.vue: Unexpected token, expected "," (3:27)

  1 | import { openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
  2 |
> 3 | export function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {
    |                            ^
  4 |   return (_openBlock(), _createElementBlock("div", null, "Isaac"))
  5 | }
    at Parser._raise (/var/www/html/node_modules/@babel/parser/lib/index.js:541:17)
    at Parser.raiseWithData (/var/www/html/node_modules/@babel/parser/lib/index.js:534:17)
    at Parser.raise (/var/www/html/node_modules/@babel/parser/lib/index.js:495:17)
    at Parser.unexpected (/var/www/html/node_modules/@babel/parser/lib/index.js:3550:16)
    at Parser.expect (/var/www/html/node_modules/@babel/parser/lib/index.js:3524:28)
    at Parser.parseBindingList (/var/www/html/node_modules/@babel/parser/lib/index.js:10835:14)
    at Parser.parseFunctionParams (/var/www/html/node_modules/@babel/parser/lib/index.js:13881:24)
    at Parser.parseFunction (/var/www/html/node_modules/@babel/parser/lib/index.js:13859:10)
    at Parser.parseFunctionStatement (/var/www/html/node_modules/@babel/parser/lib/index.js:13496:17)
    at Parser.parseStatementContent (/var/www/html/node_modules/@babel/parser/lib/index.js:13179:21)

webpack compiled with 1 error

答案#1

我上周自己也用过这个。在 setup 函数中将 App 参数改为小写:

setup({ el, app, props, plugin }) {
        createApp({ render: () => h(app, props) })

答案#2

我知道那是件傻事

我当时告诉 mix 要把 ts 文件当作 js 处理(使用 mix.js 而不是 mix.ts)

const mix = require('laravel-mix');

mix.js('resources/js/app.ts', 'public/js').vue({version: 3})
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]);

那是正确的方式

const mix = require('laravel-mix');

mix.ts('resources/js/app.ts', 'public/js').vue({version: 3})
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]);

就这样,问题解决了