page doesn't change when using paginator (Laravel, Inertia.js) - laravel

I am using Laravel Jetstream and InertiaJS. I tried to make a pagination according to the manual.
web.php
use App\Models\Post;
use Illuminate\Foundation\Application;
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
Route::get('/posts', function () {
return Inertia::render('Posts', [
'posts' => Post::paginate(2)->through(fn($post) => [
'id' => $post->id,
'title' => $post->title,
'body' => $post->body
])
]);
})->name('pages.posts');
Posts.vue
<script setup>
import { Link } from '#inertiajs/inertia-vue3';
import NewLayout from '#/Layouts/NewLayout.vue';
defineProps({posts: Object});
</script>
<template>
<NewLayout title="posts">
<div>
<div class="m-10 border w-400" v-for="post in posts.data" :key="post.id">
<div>{{ post.title }}</div>
<div>{{ post.body }}</div>
</div>
</div>
<div class="inline-flex -space-x-px">
<a class="bg-white border border-gray-300 text-gray-500 hover:bg-gray-100 hover:text-gray-700 ml-0 rounded-l-lg leading-tight py-2 px-3 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
v-for="link in posts.links" :href="link.url" v-html="link.label"></a>
</div>
</NewLayout>
</template>
'posts' => Post::paginate(4)
when I change the pagination value to 4 in the web.php file, it shows 4 posts
'posts' => Post::paginate(2)
and when I enter the value 2, it displays the first two posts (and so far everything works as it should)
but when i click on the second page nothing changes. the same first two posts are displayed
I don't know what I did wrong. please, help.
I use laravel 9, docker, nginx, mysql
package.json
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"#inertiajs/inertia": "^0.11.0",
"#inertiajs/inertia-vue3": "^0.6.0",
"#inertiajs/progress": "^0.2.7",
"#tailwindcss/forms": "^0.5.2",
"#tailwindcss/typography": "^0.5.2",
"#vitejs/plugin-vue": "^4.0.0",
"autoprefixer": "^10.4.7",
"axios": "^1.1.2",
"laravel-vite-plugin": "^0.7.2",
"lodash": "^4.17.19",
"postcss": "^8.4.14",
"tailwindcss": "^3.1.0",
"vite": "^4.0.0",
"vue": "^3.2.31"
}
}

Laravel paginator takes GET parameter page from the request object. You don't provide that object to function that's why it doesn't work. Try this
Route::get('/posts', function (Request $request) {...})->name('pages.posts');
Or you may specify the page manually:
Route::get('/posts', function (Request $request) {
return Inertia::render('Posts', [
'posts' => Post::paginate(2, page: $request->page ?? 1)->through(fn($post) => [
'id' => $post->id,
'title' => $post->title,
'body' => $post->body
])
]);
})->name('pages.posts');

I specified in the nginx.conf file like this
location / {
try_files $uri /index.php;
}
and it was necessary like this
location / {
try_files $uri /index.php?$query_string;
}

Related

livewire and vite not playing together well; livewire produces a blank screen when data coming from function updated($property)

I have just created a new laravel project, using sail / docker. Installed tailwind, laravel-livewire, alpine. my package.json looks like this:
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"autoprefixer": "^10.4.13",
"axios": "^1.1.2",
"laravel-vite-plugin": "^0.6.0",
"lodash": "^4.17.19",
"postcss": "^8.4.18",
"tailwindcss": "^3.2.2",
"vite": "^3.0.0"
},
"dependencies": {
"#alpinejs/focus": "^3.10.5",
"#defstudio/vite-livewire-plugin": "^0.2.6",
"#tailwindcss/forms": "^0.5.3",
"alpinejs": "^3.10.5"
}
}
I have a livewire component, a form, that you choose your Property that you live in, then choose the unit on that property. People are making maintenance requests for their apartment to their apartment manager.
So when the user / tenant identifies their property, function updated($property) does the validation only for the field that changed, then if passes, runs a query to find the list of apartments available for that property. I dd() at the end of the function and I know it is returning the proper list of apartments and their id's for the property chosen in the form.
However, as soon as livewire tries to send the data back to the form, I get a totally blank screen. In fact, I don't think the data is making it out of the back end because in the console, I do not see the apartment unit request being returned, but again, on the back end, if I dd($units), they are all their.
I think it is a Vite / livewire issue going on. I cannot identify it.
Here is the code in the livewire component. I include the dd(), and it does return the appropriate values to the screen, so the app is getting to the end of the updated() function:
public function updated($propertyname)
{
$this->validateOnly($propertyname, $this->rules(), $this->customMessages());
switch ($propertyname) {
case 'submittedby':
$this->submittedby = ucWordsSpace($this->submittedby);
break;
case 'phonenumber':
if (strlen($this->phonenumber) > 0)
$this->phonenumber = formatphone($this->phonenumber, false);
break;
case 'property':
$this->unit_options = array();
$this->unit_values = array();
$this->unit_values[0] = -1;
$units = Unit::where('property_id',4)->select('id','abbrev')->orderBy('abbrev')->get();
$this->unit_options[0] = (count($units) == 0) ? 'Choose Your Property First' : 'Choose Your Unit';
foreach ($units as $unit) {
$this->unit_values[] = $unit->id;
$this->unit_options[] = $unit->abbrev;
}
dd($this->unit_values, $this->unit_options);
break;
}
}
I have the following in layout.app.blade.php in the :
#vite('resources/css/app.css', 'resources/js/app.js')
the following is in my tailwind.config.js
module.exports = {
content: [
"./resources/**/*.blade.php",
"./resources/**/*.js",
"./resources/**/*.vue",
],
resources/css/app.css contains:
#tailwind base;
#tailwind components;
#tailwind utilities;
resources/js/app.js contains:
import './bootstrap';
import '../css/app.css';
bootstrap.js contains:
window._ = _;
/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
import Alpine from 'alpinejs'
import focus from '#alpinejs/focus'
window.Alpine = Alpine
Alpine.plugin(focus)
Alpine.start()
vite.config.js contains:
import {defineConfig} from 'vite';
import laravel from 'laravel-vite-plugin';
import livewire from '#defstudio/vite-livewire-plugin'; // <-- import
export default defineConfig({
//...
plugins: [
laravel([
'resources/css/app.css',
'resources/js/app.js',
]),
livewire({ // <-- add livewire plugin
refresh: ['resources/css/app.css'], // <-- will refresh css (tailwind ) as well
}),
],
});
Signed Dazed and Confused!
Hope someone has some insite.
okay, i have something to add. here is a component that I am using
#props([
'label' => '',
'model' => '',
'pholder' => '',
'speed' => '',
])
<div>
<div class="rounded-md border border-gray-300 px-3 py-2 mb-3 shadow-sm focus-within:border-indigo-600 focus-within:ring-1 focus-within:ring-indigo-600">
<label for="{{$model}}" class="block text-xs font-medium text-gray-900">{{$label}}</label>
<input type="text"
wire:model{{$speed}}="{{$model}}"
id="{{$model}}"
class="block w-full border-0 p-0 text-gray-900 placeholder-gray-400 focus:ring-0 sm:text-sm"
placeholder="{{$pholder}}">
</div>
#error($model)<span class="text-red-800 text-xs underline">{{ $message }}</span> #enderror
</div>
the livewire component 'calls' this component thus:
<x-hab-input label="Phone Number"
model="phonenumber"
pholder="(999) 999-9999"
speed=".lazy" />
I have this rule defined in the livewire component:
'phonenumber' => ['regex:/^([0-9\s\-\+\(\)]*)$/', 'min:10', 'max:14', 'required'],
i have the following code running after the field is updated
public function updated($propertyname)
{
$this->validateOnly($propertyname, $this->rules(), $this->customMessages());
switch ($propertyname) {
case 'submittedby':
$this->submittedby = ucWordsSpace($this->submittedby);
break;
case 'phonenumber':
if (strlen($this->phonenumber) > 0)
$this->phonenumber = formatphone($this->phonenumber, false);
break;
the formatphone() function is a helper function that resides in App/helpers.php. the function turns a phone number typed like "4045551212" into "(404) 555-1212". This function works. It updates the formatting of the phone number.
However, if user types, e.g., less than 10 numbers it will fail the validation, which is supposed to flash the error to the screen. But, this is another situation where the screen goes blank. gone. only the background is there. The {{$slot}} in app.blade.php is left empty.
well, I am both angry at myself and embarassed. Here is the culprit. There was a comment at the top of the livewire component. Damn. I took it out, and no problems!
<!--
This example requires some changes to your config:
// tailwind.config.js
module.exports = {
// ...
plugins: [
// ...
require('#tailwindcss/forms'),
],
}
-->
<div>
<div class="w-3/4 mt-5 mx-auto rounded-2xl p-5 bg-slate-100">
<p class="text-3xl font-serif text-red-900 text-center">Habersham Properties - Maintenance Request</p>
<div class="hidden sm:block" aria-hidden="true">

"Could not authenticate you" when getting temporary credentials

I'm working on simple laravel9 project on my localhost where you can login via Facebook or Twitter.
I added custom domain to my localhost with verified ssl.
composer require laravel/socialite
already installed.
Facebook login works fine but twitter shows Erorr:
League\OAuth1\Client\Credentials\CredentialsException Received HTTP status code [401] with message "{"errors":[{"code":32,"message":"Could not authenticate you."}]}" when getting temporary credentials.
Here is my TwitterController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Laravel\Socialite\Facades\Socialite;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use Exception;
class TwitterController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function redirectToTwitter()
{
return Socialite::driver('twitter')->redirect();
}
/**
* Create a new controller instance.
*
* #return void
*/
public function handleTwitterCallback()
{
try {
$user = Socialite::driver('twitter')->user();
$finduser = User::where('twitter_id', $user->id)->first();
if($finduser){
Auth::login($finduser);
return redirect()->intended('/home');
}else{
$newUser = User::updateOrCreate(['email' => $user->email],[
'name' => $user->name,
'twitter_id'=> $user->id,
'username'=> $user->id,
'uid' => rand(9,999999999)+time(),
'password' => encrypt('123456dummy')
]);
Auth::login($newUser);
return redirect()->intended('/home');
}
} catch (Exception $e) {
dd($e->getMessage());
}
}
}
config/services.php
'twitter' => [
'client_id' => env('TWITTER_CLIENT_ID'),
'client_secret' => env('TWITTER_CLIENT_SECRET'),
'redirect' => 'https://testsite.com/auth/twitter/callback',
],
login.blade.php
{{-- Login with Twitter --}}
<div class="mt-4 p-3 d-flex justify-content-center">
<a class="btn mr-1" href="{{ route('auth.twitter') }}"
style="background: #1D9BF9; color: #ffffff; padding: 10px; width: 30%; text-align: center; border-radius:3px;">
Twitter
</a>
</div>
routes/web.php
Route::controller(TwitterController::class)->group(function(){
Route::get('auth/twitter', 'redirectToTwitter')->name('auth.twitter');
Route::get('auth/twitter/callback', 'handleTwitterCallback');
});
.env
TWITTER_CLIENT_ID=xxxxxxxxxxxxxxxx
TWITTER_CLIENT_SECRET=xxxxxxxxxxxxxxx
composer.json
"require": {
"php": "^7.3|^8.0",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"laravel/framework": "^8.75",
"laravel/sanctum": "^2.11",
"laravel/socialite": "^5.5",
"laravel/tinker": "^2.5",
"laravel/ui": "^3.4",
"socialiteproviders/twitter": "^4.1"
},
I know that my thread is duplicated but I searched alot and found that there are many people didn't find a clean solution yet.
I also tried this:
composer require socialiteproviders/twitter
as provided by laravel docs for other login providers using this https://socialiteproviders.com/Twitter/#installation-basic-usage
tried also to add providers to config/app which are not needed as I know
'providers' => [ Laravel\Socialite\SocialiteServiceProvider::class,],
'aliases' => [ 'Socialite' => Laravel\Socialite\Facades\Socialite::class,],
here is my twitter application screenshot:
Environment:staging
Solved !
App keys where somehow broken so I regenerate them.
and the other issue was misspilling in call back URL on Twitter app

Inertia mounted hook with search resets pagination on every action

My vue file:
data() {
return {
search: '',
}
},
mounted() {
this.search = this.filters.search ?? '';
},
watch: {
search(value) {
Inertia.get('/contacts', { search: value }, {
preserveState: true,
replace: true,
})
}
The Laravel Controller:
$contacts = Model::query()
->paginate(10)
->withQueryString();
return Inertia::render('Contacts/List', [
'contacts' => $contacts,
'filters' => request()->only(['search']),
'currentPage' => request()->page,
]);
It all works perfectly if the mounted block is missing.
With it, on every Inertia reload a "new search" is registered (since it's changed in the mounted hook) and it returns to page 1, so basically, every time you change the page it returns you to page 1.
It should be working perfectly with the Composition API's setup, but not sure why can't I get it to work here.
I use axios instead of Inertia.js in pagination
<template>
<div class="row mt-4">
<div class="col-md-5">
<span
>showing {{ data.from }}-{{ data.to }} of
{{ data.total }} items</span
>
</div>
<div class="col-lg-7">
<nav aria-label="...">
<ul class="pagination float-end">
<template v-for="link in data.links" :key="link.id">
<li v-if="!link.url" class="page-item">
<a #click.prevent="paginate(link.label)" class="page-link">
<span
aria-hidden="true"
v-html="link.label"
></span>
</a>
</li>
<li
v-else
:class="{ active: link.active }"
class="page-item"
>
<a
#click.prevent="paginate(link.label)"
v-html="link.label"
class="page-link"
></a>
</li>
</template>
</ul>
</nav>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
props: ["data", "url"],
methods: {
paginate(label) {
console.log(`${route(this.url)}?page=${label}`);
axios.get(`${route(this.url)}?page=${label}`).then((res) => {
this.$emit('paginate', res.data)
});
}
}
}
</script>
I ran into the same issue, and after some digging I found this answer. The gist is that you should set your search parameter directly in the data attribute instead of using mounted():
data() {
return {
search: this.filters.search ?? '',
}
},
watch: {
search(value) {
Inertia.get('/contacts', { search: value }, {
preserveState: true,
replace: true,
})
}

CSRF token mismatch in NUXT Axios requests but the NUXT Auth is working perfectly fine

I have implemented an authentication system with NUXT framework and using laravel 9 Sanctum as the backend.
While logging in it works fine it update the store and everything is fine but while registering a user it gives a "Request failed with status code 419" "message": "CSRF token mismatch." errors:
this is my api.php file in laravel
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\TopicController;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
//public routes
Route::post('register', [AuthController::class, 'reg']);
Route::post('login', [AuthController::class, 'login']);
Route::post('logout', [AuthController::class, 'logout']);
//protected routes by sanctum
Route::group(['middleware' => ['auth:sanctum']], function() {
Route::get('/user', function (Request $request) {
return $request->user();
});
});
This is my AuthController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Requests\UserRegisterRequest;
use Illuminate\Support\Facades\Hash;
use App\Models\User;
use Illuminate\Http\Respose;
use Illuminate\Auth\AuthenticationException;
use App\Http\Resources\User as UserResource;
class AuthController extends Controller
{
//register a user
public function reg(Request $request) {
$user_data = $request->validate([
'name' => 'required|string',
'email' => 'required|string|unique:users,email',
'password' => 'required|string|confirmed'
]);
$user = User::create([
'name' => $user_data['name'],
'email' => $user_data['email'],
'password' => bcrypt($user_data['password'])
]);
}
public function login(Request $request){
if($user = !auth()->attempt($request->only('email','password'))){
throw new AuthenticationException();
}
$token = auth()->user()->createToken('myapptoke')->plainTextToken;
return (new UserResource($request->user()))->additional([
'meta' => [
'token' => $token,
],
]);
}
//logout a user
public function logout(Request $request){
auth()->user()->tokens()->delete();
auth()->logout();
$response = [
'message' => 'logged out'
];
return $response;
}
}
Laravel .env file
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:D2F/NZpkDyj1hyCCzTKe3i/5khtp/WX1k17udQjv9R8=
APP_DEBUG=true
APP_URL=
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=backend-laravel-nine
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
SANCTUM_STATEFUL_DOMAINS=localhost:3000
SESSION_DOMAIN=localhost
This is my nuxt.config.js
export default {
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'NUXTfreshInstallation',
htmlAttrs: {
lang: 'en',
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' },
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{rel:'stylesheet', href:'/css/bootstrap.min.css'}
],
scripts: [
{type:'text/javascript', serc:'/js/bootstrap.min.js'},
{type:'text/javascript', serc:'/js/bootstrap.bundle.min.js'},
]
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [ "./plugins/mixins/user.js", "./plugins/mixins/validation.js","./plugins/setErrorsPlugin.js"],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/axios
'#nuxtjs/axios',
'#nuxtjs/auth-next',
],
// router: {
// middleware: ["clearValidationErrors"]
// },
auth: {
strategies: {
laravelSanctum: {
provider: 'laravel/sanctum',
url: 'http://localhost:8000',
endpoints: {
login: {
url: '/api/login',
method: 'post',
//propertyName: 'meta.token'
},
user: {
url: '/api/user',
//method: 'get',
//propertyName: 'data'
},
logout: {
url: '/api/logout',
//method: 'post',
},
},
}
},
redirect: {
login: '/login',
logout: '/login',
home: '/'
}
},
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
// Workaround to avoid enforcing hard-coded localhost:3000: https://github.com/nuxt-community/axios-module/issues/308
baseURL: 'http://localhost:8000',
},
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {},
}
This is the user register .vue page:
<template>
<div>
<div class="container col-md-6 mt-5">
<h2>Register</h2>
<hr>
<form #submit.prevent="register" method="post">
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" placeholder="Enter Name" v-model="form.name" autofocus/>
<small class="form-text text-danger">Show errors</small>
</div>
<div class="form-group">
<label>Email address</label>
<input type="email" class="form-control" placeholder="Enter Email" v-model.trim="form.email" />
<small class="form-text text-danger">Show errors</small>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" v-model.trim="form.password" placeholder="Enter Password" />
<small class="form-text text-danger">Show errors</small>
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" class="form-control" v-model.trim="form.password_confirmation" placeholder="Enter Password Again" />
<small class="form-text text-danger">Show errors</small>
</div>
<button type="submit" class="btn btn-primary" >Register</button>
<p> Already have an account <nuxt-link to="/Login">Login </nuxt-link></p>
</form>
</div>
</div>
</template>
<script>
export default {
data () {
return {
form: {
name: '',
email: '',
password: '',
password_confirmation: '',
},
}
},
methods: {
async register (){
await this.$axios.post('/api/register', this.form);
await this.$auth.loginWith('laravelSanctum', {
data: {
email: this.form.email,
password: this.form.password
}
});
}
}
}
</script>
I have tried may troubleshooting techniques, I understood a little that the problem is in my .env file in "SANCTUM_STATEFUL_DOMAINS=localhost:3000 SESSION_DOMAIN=localhost "
if i add write it like this SANCTUM_STATEFUL_DOMAINS=localhost:3000,.localhost then the login does not work.
Is there any solutions I will appreciate your help Thanks
This is the error i get from the register request
Try to add csrf token into your registration view like this:
<form #submit.prevent="register" method="post">
#csrf
<div class="form-group">
<label>Name</label>
...
Try to change
SANCTUM_STATEFUL_DOMAINS=localhost:3000
to
SANCTUM_STATEFUL_DOMAINS=http://localhost:3000

Laravel vue js integration - No values in blade file

I try to integrate vue.js with laravel 5.3. I call "gulp" which creates the main.js file in the public folder. I can see in the browser that the js file is loaded but the value of "message" is not shown. It is only written {{message}}. Any ideas why?
<body>
<div class="container">
<div class="content">
<div class="title">
<p>#{{ message }}</p>
</div>
</div>
</div>
<script src="js/main.js"></script>
</body>
gulpfile:
var elixir = require('laravel-elixir');
require('laravel-elixir-browserify-official');
require('laravel-elixir-vueify');
elixir(mix => {
mix.sass('app.scss').browserify('main.js');
});
main.js:
import Vue from 'vue';
var app = new Vue({
el: 'body',
data: {
message: 'Hello Vue!'
}
})
package.json:
"dependencies": {
"bootstrap-sass": "^3.3.7",
"gulp": "^3.9.1",
"jquery": "^3.1.0",
"laravel-elixir": "^6.0.0-9",
"laravel-elixir-browserify-official": "^0.1.3",
"laravel-elixir-vue-2": "^0.2.0",
"laravel-elixir-vueify": "^1.0.0",
"laravel-elixir-webpack-official": "^1.0.2",
"lodash": "^4.16.2",
"vue": "^2.0.1",
"vue-resource": "^1.0.3"
}
EDIT
package.json
{
"private": true,
"scripts": {
"prod": "gulp --production",
"dev": "gulp watch",
"slate": "rimraf node_modules && npm install",
"clean": "rimraf public/css/app.css public/css/app.css.map public/js/app.js && npm run dev"
},
"devDependencies": {
"bootstrap-sass": "^3.3.7",
"gulp": "^3.9.1",
"jquery": "^3.1.1",
"laravel-elixir": "^6.0.0-15",
"laravel-elixir-browsersync-official": "^1.0.0",
"laravel-elixir-vue-2": "^0.3.0",
"laravel-elixir-webpack-official": "^1.0.10",
"lodash": "^4.17.2",
"moment": "^2.17.1",
"vue": "^2.1.6",
"vue-resource": "^1.0.3",
"vuex": "^2.1.1"
}
}
gulpfile.js
const elixir = require('laravel-elixir');
require('laravel-elixir-vue-2');
/*
|--------------------------------------------------------------------------
| Elixir Asset Management
|--------------------------------------------------------------------------
|
| Elixir provides a clean, fluent API for defining some basic Gulp tasks
| for your Laravel application. By default, we are compiling the Sass
| file for our application, as well as publishing vendor resources.
|
*/
elixir(mix => {
mix
.sass('app.scss')
.webpack('main.js');
});
Your code is fine except one thing. Vue JS Doesn't recommend use of body element as vue js root.
The provided element merely serves as a mounting point. Unlike in Vue
1.x, the mounted element will be replaced with Vue-generated DOM in all cases. It is therefore not recommended to mount the root instance to or
https://v2.vuejs.org/v2/api/#el
Code
<body>
<div class="container" id="app"> <!-- Mind the id attached -->
<div class="content">
<div class="title">
<p>#{{ message }}</p>
</div>
</div>
</div>
<script src="js/main.js"></script>
</body>
and main.js
import Vue from 'vue';
var app = new Vue({
el: '#app', // mind the root element is changed to app.
data: {
return { // mind the return in data
message: 'Hello Vue!'
}
}
});

Resources