Laravel 7 Vue — api не определен — Невозможно отобразить сообщение о задаче в vue

#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. Старайтесь всегда искать документацию, прежде чем переходить сюда.

Взгляните на документы здесь