1

我正在尝试使用 Laravel 后端编写 Vue SPA,同时还使用 Typescript 而不是 Raw Javascript。我想我很难把头绕在某些事情上,主要是围绕打字稿。显然我需要 Axios,所以我尝试导入它并将其绑定到我的 bootstrap.ts 文件中的窗口,类似于在 Laravel 的默认 bootstrap.js 文件中完成的方式。

资源/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')
}

然后将其导入我的 app.ts 文件,然后设置 Vue 路由器并导入组件。

资源/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,
});

但是,当我尝试在我的 Vue 组件中使用 axios 时,我得到了错误cannot find name 'axios'。当然,我也会收到与隐式任何类型相关的错误,但我知道我为什么会得到这些错误。当然,我也确实记得从 npm 安装 axios。

我将在此处发布 Register.vue 文件以供参考,但是在我想在其中使用 axios 的任何文件中都会遇到类似的错误。

资源/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>

我在这里遗漏了一些明显的东西吗?以错误的方式解决这个问题?以下是一些可能与情况相关的其他杂项文件。

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/**/*"
    ]
}

资源/js/typings.d.ts

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

1 回答 1

0

我也没有让它工作,对我有用的只是在每个组件中导入 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');
}

不,每次您在其他地方使用 axios 时,仍会设置这些标头。例如在您的 Register.vue 中,您只需import axios from 'axios';

于 2021-08-13T09:13:02.197 回答