Сообщество IT-специалистов
Ответы на любые вопросы об IT
Профессиональное развитие в IT
Удаленная работа для IT-специалистов
import 'es6-promise/auto' import axios from 'axios' import './bootstrap' import Vue from 'vue' import Vuetify from 'vuetify' import VueAuth from '@websanova/vue-auth' import VueAxios from 'vue-axios' import VueRouter from 'vue-router' import Index from './Index.vue' import auth from './auth' import router from './router' window.Vue = require('vue'); import store from './index.js'; import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI); Vue.component('example-component', require('./components/ExampleComponent.vue').default); Vue.component('create-post', require('./components/CreatePost.vue').default); Vue.component('all-posts', require('./components/AllPosts.vue').default); // Set Vue globallygetAllPosts window.Vue = Vue // Set Vue router Vue.router = router Vue.use(VueRouter) Vue.use(Vuetify) // Set Vue authentication Vue.use(VueAxios, axios) axios.defaults.baseURL = `${process.env.MIX_APP_URL}/api` Vue.use(VueAuth, auth) // Load Index Vue.component('index', Index) const app = new Vue({ el: '#app', router, store, vuetify: new Vuetify(), }); const VueUploadComponent = require('vue-upload-component') Vue.component('file-upload', VueUploadComponent)
Route::get('/', function () { return view('welcome'); }); // Route to handle page reload in Vue except for api routes Route::get('/{any?}', function (){ return view('welcome'); })->where('any', '^(?!api\/)[\/\w\.-]*'); Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::group(['middleware' => 'auth', 'prefix' => 'post'], function () { Route::get('get_all', 'PostController@getAllPosts')->name('fetch_all'); Route::post('create_post', 'PostController@createPost')->name('create_post'); }); Route::get('/home', 'HomeController@index')->name('home');
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); // const debug = process.env.NODE_ENV !== 'production'; export default new Vuex.Store({ state: { posts: [], }, actions: { async getAllPosts({ commit }) { return commit('setPosts', await api.get('/post/get_all')) }, }, mutations: { setPosts(state, response) { state.posts = response.data.data; }, }, // strict: debug });
<template> <div class="row"> <div class="col-md-6" v-for="(post, i) in posts" :key=i> <div class="card mt-4"> <img v-if="post.post_images.length" class="card-img-top" :src="post.post_images[0].post_image_path"> <div class="card-body"> <p class="card-text"><strong>{{ post.title }}</strong> <br> {{ truncateText(post.body) }} </p> </div> <button class="btn btn-success m-2" @click="viewPost(i)">View Post</button> </div> </div> <el-dialog v-if="currentPost" :visible.sync="postDialogVisible" width="40%"> <span> <h3>{{ currentPost.title }}</h3> <div class="row"> <div class="col-md-6" v-for="(img, i) in currentPost.post_images" :key=i> <img :src="img.post_image_path" class="img-thumbnail" alt=""> </div> </div> <hr> <p>{{ currentPost.body }}</p> </span> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="postDialogVisible = false">Okay</el-button> </span> </el-dialog> </div> </template> <script> import { mapState } from 'vuex'; export default { name: 'all-posts', data() { return { postDialogVisible: false, currentPost: '', }; }, computed: { ...mapState(['posts']) }, beforeMount() { this.$store.dispatch('getAllPosts'); }, methods: { truncateText(text) { if (text.length > 24) { return `${text.substr(0, 24)}...`; } return text; }, viewPost(postIndex) { const post = this.posts[postIndex]; this.currentPost = post; this.postDialogVisible = true; } }, } </script> <code lang="javascript"> <template> <div class="card mt-4"> <div class="card-header">New Post</div> <div class="card-body"> <div v-if="status_msg" :class="{ 'alert-success': status, 'alert-danger': !status }" class="alert" role="alert" >{{ status_msg }}</div> <form> <div class="form-group"> <label for="exampleFormControlInput1">Title</label> <input v-model="title" type="text" class="form-control" id="title" placeholder="Post Title" required /> </div> <div class="form-group"> <label for="exampleFormControlTextarea1">Post Content</label> <textarea v-model="body" class="form-control" id="post-content" rows="3" required></textarea> </div> <div class> <el-upload action="https://jsonplaceholder.typicode.com/posts/" list-type="picture-card" :on-preview="handlePictureCardPreview" :on-change="updateImageList" :auto-upload="false" > <i class="el-icon-plus"></i> </el-upload> <el-dialog :visible.sync="dialogVisible"> <img width="100%" :src="dialogImageUrl" alt /> </el-dialog> </div> </form> </div> <div class="card-footer"> <button type="button" @click="createPost" class="btn btn-success" >{{ isCreatingPost ? "Posting..." : "Create Post" }}</button> </div> </div> </template> <style> .avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; } .avatar-uploader .el-upload:hover { border-color: #409eff; } .avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 178px; height: 178px; line-height: 178px; text-align: center; } .avatar { width: 178px; height: 178px; display: block; } </style> <script> import { setTimeout } from "timers"; import { mapState, mapActions } from "vuex"; export default { name: "create-post", props: ["posts"], data() { return { dialogImageUrl: "", dialogVisible: false, imageList: [], status_msg: "", status: "", isCreatingPost: false, title: "", body: "" }; }, computed: {}, mounted() {}, methods: { ...mapActions(["getAllPosts"]), //moved it from computed properties updateImageList(file) { this.imageList.push(file.raw); }, handlePictureCardPreview(file) { this.dialogImageUrl = file.url; this.imageList.push(file); this.dialogVisible = true; }, createPost(e) { e.preventDefault(); if (!this.validateForm()) { return false; } const that = this; this.isCreatingPost = true; let formData = new FormData(); formData.append("title", this.title); formData.append("body", this.body); $.each(this.imageList, function(key, image) { formData.append(`images[${key}]`, image); }); api .post("/post/create_post", formData, { headers: { "Content-Type": "multipart/form-data" } }) .then(res => { this.title = this.body = ""; this.status = true; this.showNotification("Post Successfully Created"); //fixed spelling mistake this.isCreatingPost = false; this.imageList = []; /* this.getAllPosts() can be used here as well note: "that" has been assigned the value of "this" at the top to avoid context related issues. */ that.getAllPosts(); }); }, validateForm() { //no vaildation for images - it is needed if (!this.title) { this.status = false; this.showNotification("Post title cannot be empty"); //fixed spelling mistake return false; } if (!this.body) { this.status = false; this.showNotification("Post body cannot be empty"); return false; } return true; }, showNotification(message) { //fixed spelling mistake this.status_msg = message; setTimeout(() => { this.status_msg = ""; }, 3000); } } }; </script> </code>