#javascript #php #vue.js #laravel-7
#javascript #php #vue.js #laravel-7
Вопрос:
Я создаю task crm в vue и Laravel 7, в котором есть форма для загрузки нескольких изображений. Я нахожусь на этапе тестирования, и я не могу получить свой AllTask.vue
для отображения. У меня есть CreateTask.vue
компонент формы, который отображается как ожидалось, но AllTasks.vue
компонент этого не делает. В консоли я получаю сообщение об ошибке:
Uncaught (in promise) ReferenceError: api is not defined
Будучи новичком в Laravel и Vue, мне неясно, как определить мой api. Сначала я разместил свои контроллеры в папке API в папке controllers и вызвал их в своем api.php
файле следующим образом:
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::middleware('auth:api')->get('/task', function (Request $request) {
return $request->task();
});
Route::apiResources(['user' => 'APIUserController']);
Route::apiResources(['task' => 'APITaskController']);
Это вызвало ошибку api not defined, поэтому я закомментировал часть задачи в этом вызове и переместил свои контроллеры из папки API в папку обычных контроллеров.
После очистки кэша и повторной компиляции приложения я остаюсь с той же ошибкой в консоли. Я надеюсь, что кто-нибудь сможет сориентировать меня здесь, поскольку я полностью заблудился. Вот код, который у меня есть на данный момент:
TaskController.php
public function getAllTasks()
{
$tasks = Task::with('task_images')->orderBy('created_at', 'desc')->get();
return response()->json(['error' => false, 'data' => $tasks]);
}
public function createTask(Request $request)
{
$user = Auth::user();
$task_name = $request->task_name;
$task_priority = $request->task_priority;
$task_assigned_to = $request->task_assigned_to;
$task_assigned_by = $request->task_assigned_by;
$task_description = $request->task_description;
$task_to_be_completed_date = $request->task_to_be_completed_date;
$task_status = $request->task_status;
$task_notes = $request->task_notes;
$task_finished = $request->task_finished;
$task_image_description = $request->task_image_description;
$task_image_id = $request->task_image_id;
$images = $request->images;
$task = Task::create([
'task_name' => $task_name,
'task_priority' => $task_priority,
'task_assigned_to' => $task_assigned_to,
'task_assigned_by' => $task_assigned_by,
'task_description' => $task_description,
'task_to_be_completed_date' => $task_to_be_completed_date,
'task_status' => $task_status,
'task_notes' => $task_notes,
'task_finished' => $task_finished,
'task_image_description' => $task_image_description,
'task_image_id' => $task_image_id,
'user_id' => $user->id,
]);
foreach ($images as $image) {
$imagePath = Storage::disk('uploads')->put($user->id . '/tasks', $image);
TaskImage::create([
'task_image_description' => $task_image_description,
'task_image_path' => '/uploads/' . $imagePath,
'task_id' => $task->id
]);
}
return response()->json(['error' => false, 'data' => $task]);
}
app.js
require("./bootstrap");
window.Vue = require("vue");
import store from "./store/index";
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
Vue.use(ElementUI);
import { Form, HasError, AlertError } from "vform";
import moment from "moment";
window.Form = Form;
Vue.component(HasError.name, HasError);
Vue.component(AlertError.name, AlertError);
import VueRouter from "vue-router";
Vue.use(VueRouter);
import VueProgressBar from "vue-progressbar";
Vue.use(VueProgressBar, {
color: "rgb(143, 255, 199)",
failedColor: "red",
height: "6px"
});
import Swal from "sweetalert2";
// const Swal = require('sweetalert2')
window.Swal = Swal;
const toast = Swal.mixin({
toast: true,
position: "top-end",
showConfirmButton: false,
timer: 3000,
timerProgressBar: true,
onOpen: toast => {
toast.addEventListener("mouseenter", Swal.stopTimer);
toast.addEventListener("mouseleave", Swal.resumeTimer);
}
});
window.toast = toast;
let routes = [
{
path: "/dashboard",
component: require("./components/Dashboard.vue").default
},
{
path: "/developer",
component: require("./components/Developer.vue").default
},
{
path: "/profile",
component: require("./components/Profile.vue").default
},
{
path: "/users",
component: require("./components/Users.vue").default
},
{
path: "/tasks",
component: require("./components/Tasks.vue").default
}
];
const router = new VueRouter({
mode: "history",
routes
});
Vue.filter("upText", function(text) {
return text.charAt(0).toUpperCase() text.slice(1);
});
Vue.filter("myDate", function(created_date) {
return moment(created_date).format("MMMM Do YYYY, h:mm:ss a");
});
window.Fire_event = new Vue();
Vue.component(
"example-component",
require("./components/ExampleComponent.vue").default
);
Vue.component(
"dashboard-component",
require("./components/Dashboard.vue").default
);
Vue.component(
"passport-clients",
require("./components/passport/Clients.vue").default
);
Vue.component(
"passport-authorized-clients",
require("./components/passport/AuthorizedClients.vue").default
);
Vue.component(
"passport-personal-access-tokens",
require("./components/passport/PersonalAccessTokens.vue").default
);
Vue.component("create-task", require("./components/CreateTask.vue").default);
Vue.component("all-tasks", require("./components/AllTasks.vue").default);
const app = new Vue({
el: "#app",
router,
store
});
web.php
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
Route::get('{path}', "HomeController@index")->where('path', '([A-zd//_.] )?');
Route::group(['middleware' => 'auth', 'prefix' => 'task'], function () {
Route::get('get_all', 'TaskController@getAllTasks')->name('fetch_all');
Route::post('create_task', 'TaskController@createTask')->name('create_task');
});
If I have missed anything or you would like to see more information that I may have missed, please let me know and I will gladly edit my query. Thank you in advance for your help.
EDIT
AllTasks.vue
<template>
<div class="row">
<div class="col-md-6" v-for="(task, i) in tasks" :key="i">
<div class="card mt-4">
<img
v-if="task.task_images.length"
class="card-img-top"
:src="task.task_images[0].task_image_path"
alt
/>
<div class="card-body">
<p class="card-text">
<strong>{{ task.task_name }}</strong>
</p>
<br />
{{ truncateText(task.task_description) }}
</div>
<button class="btn btn-success m-2" @click="viewTask(i)">View Task</button>
</div>
</div>
<el-dialog v-if="currentTask" :visible.sync="taskDialogVisible" width="40%">
<span>
<h3>{{ currentTask.task_name }}</h3>
<div class="row">
<div class="col-md-6" v-for="(img, i) in currentTask.task_images" :key="i">
<img :src="img.task_image_path" class="img-thumbnail" alt />
</div>
</div>
<hr />
<h5>Assigned To</h5>
<p>{{ currentTask.task_assigned_to }}</p>
<h5>Assigned By</h5>
<p>{{ currentTask.task_assigned_by }}</p>
<h5>Due</h5>
<p>{{ currentTask.task_to_be_completed_date }}</p>
<h5>Notes</h5>
<p>{{ currentTask.task_notes }}</p>
<h5>Priority</h5>
<p>{{ currentTask.task_priority }}</p>
<h5>Status</h5>
<p>{{ currentTask.task_status }}</p>
</span>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="taskDialogVisible = false">Okay</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "all-tasks",
data() {
return {
taskDialogVisible: false,
currentTask: "",
};
},
computed: {
...mapState(["tasks"]),
},
beforeMount() {
this.$store.dispatch("getAllTasks");
},
methods: {
truncateText(text) {
if (text.length > 24) {
return `${text.substr(0, 24)}...`;
}
return text;
},
viewTask(taskIndex) {
const task = this.tasks[taskIndex];
this.currentTask = task;
this.taskDialogVisible = true;
},
},
};
</script>
В Resources/js/store/index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const debug = process.env.NODE_ENV !== "production";
export default new Vuex.Store({
state: {
tasks: []
},
actions: {
async getAllTasks({ commit }) {
return commit("setTasks", await api.get("/task/get_all"));
}
},
mutations: {
setTasks(state, response) {
state.tasks = response.data.data;
}
},
strict: debug
});
ПРАВКА # 2
после добавления следующего в bootstrap.js
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.api = window.axios;
let token = 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');
}
api is not defined
Ошибка исчезла, но была заменена на:
TypeError: api.task is not a function
Я выделил, где это находится. В CrateTask.vue у меня есть эта строка:
api.task("/task/create_task", formData, {
headers: { "Content-Type": "multipart/form-data" },
})
Проблема (моя проблема) в том, что я новичок и не знаю, как ее решить. Еще раз, заранее спасибо за вашу помощь.
Комментарии:
1. Я предполагаю, что вы вызываете API из компонента AllTasks. Не могли бы вы также поделиться этой частью?
2. Привет, ненавистный. Спасибо. Я отредактировал вопрос, чтобы включить как AllTasks.vue, так и resources/js/store/index.js . Я надеюсь, что это проливает свет на то, чего мне не хватает. Приветствия.
3. Здесь: github.com/MartinsOnuoha/BlogCafe/blob/master/resources/js /… —
api
по сути, этоaxios
клиент. Пожалуйста, убедитесь, что оно есть в вашемbootstrap.js
4. В одном из комментариев к этой статье он говорит, что настраивает ее
bootstrap
следующим образом:const api = axios.create({ baseURL: 'https://some-domain.com/api/', timeout: 1000, headers: {'X-Custom-Header': 'foobar'} });
5. Я настоятельно рекомендую вам создать курс для изучения основ технологий, с которыми вы работаете. Помните, что в программировании иногда работает, но это неправильно. Незнание того, что делает ваш код, может быть очень опасным.
Ответ №1:
Задача не является методом axios. Возможно, вам нужно вызвать api.get, чтобы добраться до вашего маршрута контроллера laravel. Старайтесь всегда искать документацию, прежде чем переходить сюда.
Взгляните на документы здесь