0
votes

I'm setting up Vue in my Laravel project. The page and the Vue component loads the data on initial load (see the cities dropdown). After loading however, any changes to the components aren't recorded.

At first, I tried attaching a get request to the form submit but the form submits normally (i.e. through an HTTP request instead of AJAX/Vue). I added a test variable (message) and tried to update it on button click but it doesn't update too. It updates in the mounted() function though.

Vuetools detects Vue on my page but doesn't detect the actual component ("This instance has no reactive state"). Please help!

bootstrap.js

require('./bootstrap');
window.Vue = require('vue');
Vue.config.devtools = process.env.NODE_ENV === 'development';
Vue.component('alerts', require('./components/Alerts.vue').default);
Vue.component('search-result', require('./components/SearchResult.vue').default);
Vue.component('search-bar', require('./components/SearchBar.vue').default);

const app = new Vue({
    el: '.search',
});

webpack.min.js

    const mix = require('laravel-mix');

    mix.js('resources/js/app.js', 'public/js')
       .js('resources/js/main.js', 'public/js')
       .sass('resources/sass/app.scss', 'public/css')
       .version();

index.blade.php @extends('layouts.app')

@section('custom_head')
<script type="text/javascript">
    window.__CITIES_LOADED__ = {!!$cities!!}
</script>
@endsection

@section('content')
<div class="container search">
    <alerts></alerts>
    <div class="row">
        <div class="col">
            <h1 class="text-bold mb-5">Search</h1>  
        </div>
        <div class="col-md-10">
            <search-bar></search-bar>   
        </div>
    </div>
</div>
<div class="w-100 mb-5 mt-5"><hr></div>
@endsection

app.template.php

<!-- head code -->
<body>
<div class="search">
@yield('content')
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.7/js/select2.min.js"></script>
    <script type="text/javascript" src="{{ mix('js/app.js') }}" defer></script>
    <script type="text/javascript" src="{{ mix('js/main.js') }}"></script>
    @yield('custom_js')
</body>

SearchBar component file

<template>
    <div class="row p-2">
        <div class="search-bar bg-white rounded col">
            <span v-model="message">{{message}}</span>
            <form @submit.prevent="send">
                <div class="row">
                    <div class="col mb-3">
                        <select name="q[]" id="" class="form-control search-dropdown custom-select custom-select-lg" required v-model="fields.q">
                            <option selected disabled>Select a city</option>
                            <option v-for="city in cities">{{city.concatenated_name}}</option>
                        </select>
                    </div>
                </div>
                <div class="row">
                    <div class="col">
                        <input type="text" hidden style="display:none;">
                        <button type="submit" class="btn gradient-button float-right">Find professionals</button>
                    </div>
                </div>
            </form>
            <button v-on:click="warn('Form cannot be submitted yet.', $event)">Test</button>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                cities: JSON.parse(JSON.stringify(window.__CITIES_LOADED__)),
                alerts: {},
                fields: {},
                message: "HELLO",
            }
        },
        methods: {
            send() {
                window.axios.post('/search', this.fields).then(response => {

                    alert('Message sent!');
                }).catch(error => {
                    if (error.response.status === 422) {
                    this.alerts = error.response.data.errors || {};
                }
                });
            },
            test() {
                console.log("Hi");
            }
        },
        mounted() {
            console.log('Component mounted.');
            this.message="Hi";
        },
        components: {

        }
    }
    function City({concatenated_name}) {
        this.concatenated_name = concatenated_name;
    }
</script>

Vuetools screenshot Vuetools

1

1 Answers

0
votes

I found some points to fix:

1- In your select your v-model attribute is using a variable which not exist

2- You should not use selected in your select's option, instead, you should set the select's v-model variable to the wished value, as I'm doing with city: 0.

3- You forgot to set the option value.

4 - When you use v-for directive, always remember to set the :key directive

{
  data: function() {
    return {
      cities: JSON.parse(JSON.stringify(window.__CITIES_LOADED__)),
      alerts: {},
      fields: {},
      message: "HELLO",
      city: 0
    }

  }
}
<select name="q[]" class="form-control search-dropdown custom-select custom-select-lg" required v-model="city">
  <option value="0">Select a city</option>
  <option v-for="city in cities" :key="city.id" :value="city.id">{{city.concatenated_name}}</option>
</select>