简体   繁体   English

将 Typescript 与 Laravel 和 Vue.js 一起使用,导入后无法将其导入 Vue 组件?

[英]Using Typescript with Laravel and Vue.js, imports not making it to Vue components?

I'm trying to write a Vue SPA with a Laravel Backend, while also using Typescript instead of Raw Javascript.我正在尝试使用 Laravel 后端编写 Vue SPA,同时还使用 Typescript 而不是 Raw Javascript。 I think I'm having trouble wrapping my head around certain things, mostly surrounding typescript.我想我在某些事情上遇到了麻烦,主要是围绕打字稿。 Obviously I need Axios, so I attempted to import it and bind it to the Window in my bootstrap.ts file similar to the way it was done in Laravel's default bootstrap.js file.显然我需要 Axios,所以我尝试导入它并将它绑定到我的 bootstrap.ts 文件中的 Window,类似于在 Laravel 的默认 bootstrap.js 文件中完成的方式。

resources/js/bootstrap.ts资源/js/bootstrap.ts

import 'bootstrap';
import Axios, {AxiosStatic} from 'axios';

declare global {
    // Extending the DOM Window Interface
    interface Window {
        axios: AxiosStatic;
    }

    // Extending querySelector Element
    interface Element {
        content: string;
    }
}

declare var window: Window;
window.axios = Axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

const token: Element | null = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token')
}

That then gets imported to my app.ts file, which then sets up the Vue Router and imports the components.然后将其导入我的 app.ts 文件,然后设置 Vue Router 并导入组件。

resources/js/app.ts资源/js/app.ts

/**
 * First, we will load all of this project's Javascript utilities and other
 * dependencies. Then, we will be ready to develop a robust and powerful
 * application frontend using useful Laravel and JavaScript libraries.
 */

import './bootstrap';
import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

import App from './views/App.vue';
import Welcome from './views/Welcome.vue';
import Dashboard from './views/Dashboard.vue';
import Login from './views/Login.vue';
import Register from './views/Register.vue';

const router = new VueRouter({
    mode: 'history',
    routes: [
        {
            path: '/',
            name: 'home',
            component: Welcome
        },
        {
            path: '/login',
            name: 'login',
            component: Login
        },
        {
            path: '/register',
            name: 'register',
            component: Register
        },
        {
            path: '/dashboard',
            name: 'dashboard',
            component: Dashboard
        }
    ],
});

const app = new Vue({
    el: '#app',
    components: { App },
    router,
});

However, when I attempt to use axios in my Vue components, I get the error cannot find name 'axios' .但是,当我尝试在我的 Vue 组件中使用 axios 时,我收到错误cannot find name 'axios' Of course I also get errors related to implicit any typings but I'm aware of why I'm getting those.当然,我也会遇到与隐式任何类型相关的错误,但我知道为什么我会得到这些错误。 Of course I also did remember to install axios from npm.当然,我也记得从 npm 安装 axios。

I'll post the Register.vue file here for reference, but I'm getting similar errors in any file I want to use axios in.我将在此处发布 Register.vue 文件以供参考,但在我想在其中使用 axios 的任何文件中都会遇到类似的错误。

resources/js/views/Register.vue资源/js/views/Register.vue

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card card-default">
                    <div class="card-header">Register</div>

                    <div class="card-body">
                        <form method="POST" action="/register">
                            <div class="form-group row">
                                <label for="name" class="col-md-4 col-form-label text-md-right">Name</label>

                                <div class="col-md-6">
                                    <input id="name" type="text" class="form-control" v-model="name" required autofocus>
                                </div>
                            </div>

                            <div class="form-group row">
                                <label for="email" class="col-md-4 col-form-label text-md-right">E-Mail Address</label>

                                <div class="col-md-6">
                                    <input id="email" type="email" class="form-control" v-model="email" required>
                                </div>
                            </div>

                            <div class="form-group row">
                                <label for="password" class="col-md-4 col-form-label text-md-right">Password</label>

                                <div class="col-md-6">
                                    <input id="password" type="password" class="form-control" v-model="password" required>
                                </div>
                            </div>

                            <div class="form-group row">
                                <label for="password-confirm" class="col-md-4 col-form-label text-md-right">Confirm Password</label>

                                <div class="col-md-6">
                                    <input id="password-confirm" type="password" class="form-control" v-model="password_confirmation" required>
                                </div>
                            </div>

                            <div class="form-group row mb-0">
                                <div class="col-md-6 offset-md-4">
                                    <button type="submit" class="btn btn-primary" @click="handleSubmit">
                                        Register
                                    </button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
import { Route } from 'vue-router'

@Component
export default class Register extends Vue{
        name: string = ""
        email: string = ""
        password: string = ""
        password_confirmation: string = ""

        handleSubmit(e: UIEvent) {
            e.preventDefault()

            if (this.password === this.password_confirmation && this.password.length > 0)
            {
                axios.post('api/register', {
                    name: this.name,
                    email: this.email,
                    password: this.password,
                    c_password : this.password_confirmation
                    })
                    .then((response) => {
                    localStorage.setItem('user',response.data.success.name)
                    localStorage.setItem('jwt',response.data.success.token)

                    if (localStorage.getItem('jwt') != null){
                        this.$router.push('/dashboard', () => this.$router.go(0))
                    }
                    })
                    .catch(error => {
                    console.error(error);
                    });
            } else {
                this.password = ""
                this.password_confirmation = ""

                return alert('Passwords do not match')
            }
        }

        beforeRouteEnter (to: Route, from: Route, next: any) {
            if (localStorage.getItem('jwt')) {
                return next('dashboard');
            }

            next();
        }
}
</script>

Am I missing something obvious here?我在这里遗漏了一些明显的东西吗? Going about this the wrong way?以错误的方式解决这个问题? Here are some other miscellaneous files that may be relevant to the situation.以下是一些可能与情况相关的其他杂项文件。

webpack.mix.js webpack.mix.js

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

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.ts('resources/js/app.ts', 'public/js')
   .sass('resources/sass/app.scss', 'public/css');

tsconfig.json配置文件

{
    "compilerOptions": {
        "target": "es5",
        "strict": true,
        "module": "es2015",
        "moduleResolution": "node",
        "experimentalDecorators": true,
    },
    "include": [
        "resources/js/**/*"
    ]
}

resources/js/typings.d.ts资源/js/typings.d.ts

declare module '*.vue' {
    import Vue from 'vue';
    export default Vue;
}

I did not get this to work either, what worked for me is just importing axios in every component, whenever I use axios.我也没有让它起作用,对我有用的只是在我使用 axios 时在每个组件中导入 axios。

import axios from 'axios';
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
const token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

No everytime you use axios somewhere else, these headers will still be set.不,每次在其他地方使用 axios 时,这些标头仍将被设置。 For instance in your Register.vue, you would just import axios from 'axios';例如在您的 Register.vue 中,您只需import axios from 'axios';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM