我正在尝试使用 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;
}