"!taskStore.tasks?.length"и подобных строках.
<script setup>
<script setup>
import { ref } from 'vue'
import { useTaskStore } from '@/stores/taskStore'
import TaskItem from './TaskItem.vue'
const taskStore = useTaskStore()
const selectedTask = ref(null)
const detailsLoading = ref(false)
const detailsError = ref(null)
const getCSRFToken = () => {
return document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || ''
}
const showTaskDetails = async (task) => {
detailsLoading.value = true
detailsError.value = null
try {
selectedTask.value = await taskStore.fetchTask(task.id, getCSRFToken())
} catch (error) {
detailsError.value = error.response?.data?.message || 'Ошибка при загрузке задачи'
console.error('Ошибка при загрузке задачи:', error)
} finally {
detailsLoading.value = false
}
}
const closeTaskDetails = () => {
selectedTask.value = null
}
</script>
<template>
<div class="space-y-4">
<!-- Сообщения об ошибках -->
<div v-if="taskStore.error" class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative">
<span class="block sm:inline">{{ taskStore.error }}</span>
</div>
<div v-if="detailsError" class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative">
<span class="block sm:inline">{{ detailsError }}</span>
</div>
<!-- Индикаторы загрузки -->
<div v-if="taskStore.loading" class="flex justify-center items-center py-8">
<div class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500"></div>
</div>
<div v-if="detailsLoading" class="flex justify-center items-center py-4">
<div class="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-blue-500"></div>
</div>
<!-- Детали задачи -->
<div v-if="selectedTask">
<TaskItem
:task="selectedTask"
@delete="$emit('delete', $event)"
@update="$emit('update', $event)"
@close="closeTaskDetails"
/>
</div>
<!-- Список задач -->
<div v-if="!selectedTask && taskStore.tasks && !!taskStore.tasks?.length">
<div class="space-y-4">
<div
v-for="task in taskStore.tasks"
:key="task.id"
class="bg-white shadow overflow-hidden rounded-lg hover:shadow-md transition-shadow"
>
<div class="px-4 py-5 sm:px-6 flex justify-between items-center">
<div>
<h3 class="text-lg leading-6 font-medium text-gray-900 flex items-center">
<span :class="{ 'line-through text-gray-500': task.completed }">{{ task.title }}</span>
<span
v-if="task.completed"
class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800"
>
Выполнено
</span>
</h3>
<p v-if="task.description" class="mt-1 text-sm text-gray-500 truncate">
{{ task.description }}
</p>
</div>
<button
@click="showTaskDetails(task)"
class="text-blue-600 hover:text-blue-900 font-medium"
>
Подробнее
</button>
</div>
</div>
</div>
</div>
<div v-if="!taskStore.loading && (!taskStore.tasks || !taskStore.tasks?.length)" class="text-center py-8 text-gray-500">
Нет задач. Создайте первую задачу!
</div>
</div>
</template>
Route::prefix('tasks')->group(function () {
Route::get('/', [TaskController::class, 'index']); // GET /api/tasks - список задач
Route::post('/', [TaskController::class, 'store']); // POST /api/tasks - создание задачи
Route::put('/{id}', [TaskController::class, 'update']); // PUT /api/tasks/{id} - обновление
Route::delete('/{id}', [TaskController::class, 'destroy']); // DELETE /api/tasks/{id} - удаление
});
php artisan route:list --path task
import { defineStore } from 'pinia'
import axios from 'axios'
const api = axios.create({
baseURL: '/api',
})
export const useTaskStore = defineStore('task', {
state: () => ({
tasks: [],
loading: false,
error: null
}),
actions: {
async fetchTasks() {
this.loading = true
this.error = null
try {
const response = await api.get('/tasks')
this.tasks = response.data
} catch (err) {
this.error = err.response?.data?.message || 'Ошибка при загрузке задач'
throw err
} finally {
this.loading = false
}
},
async fetchTask(id) {
try {
const response = await api.get(`/tasks/${id}`)
return response.data
} catch (err) {
throw err
}
},
async createTask(taskData) {
this.loading = true
try {
const response = await api.post('/tasks', taskData)
this.tasks.push(response.data)
return response.data
} catch (err) {
this.error = err.response?.data?.message || 'Ошибка при создании задачи'
throw err
} finally {
this.loading = false
}
},
async updateTask(id, taskData) {
this.loading = true
try {
const response = await api.put(`/tasks/${id}`, taskData)
const index = this.tasks.findIndex(task => task.id === id)
if (index !== -1) {
this.tasks[index] = response.data
}
return response.data
} catch (err) {
this.error = err.response?.data?.message || 'Ошибка при обновлении задачи'
throw err
} finally {
this.loading = false
}
},
async deleteTask(id) {
this.loading = true
try {
await api.delete(`/tasks/${id}`)
this.tasks = this.tasks.filter(task => task.id !== id)
} catch (err) {
this.error = err.response?.data?.message || 'Ошибка при удалении задачи'
throw err
} finally {
this.loading = false
}
}
}
})
Если ссылка не видна, то я про эту - https://forumd.ru/viewtopic.php?id=71