Search code examples
laravelnpmmaterializevuejs2

Materialize-css+Laravel+VueJS - where to initialize modals, side-nav etc


I'm trying to build a website with Laravel 5.4, Laravel Mix, VueJS and Materialize-css.

VueJS and jQuery are shipped with Laravel, so nothing to do there. All created components work as they should work.

I installed Materialize-css via npm following the instructions on the website.

But now I get an error when I try to implement a sidenav which should fly in on button-click. Other materilizecss-components (like Toasts, Collapsibles) work fine.

Here is my bootstrap.js which loads jQuery, Materialize-css etc:

window._ = require('lodash');

window.$ = window.jQuery = require('jquery');
require('bootstrap-sass');

require('materialize-css');
import 'materialize-css/js/materialize.js';
import 'materialize-css/bin/materialize.js';

window.Vue = require('vue');

window.axios = require('axios');

window.axios.defaults.headers.common = {
    'X-CSRF-TOKEN': window.Laravel.csrfToken,
    'X-Requested-With': 'XMLHttpRequest'
};

And this is my adminarea.js, which contains all the stuff I need for my admin-area:

require('./bootstrap');

Vue.component('example', require('./Vue/components/Example.vue'));
Vue.component('admindashboard', require('./Vue/components/Admindashboard.vue'));
Vue.component('test', require('./Vue/components/Test.vue'));
Vue.component('adminnav', require('./Vue/components/Adminnav.vue'));

const app = new Vue({
    el: '#app',
    data: {
        title: 'Admindashboard'
    },
    methods: {},
    mounted() {
        console.log('Da bin ich!');
        Materialize.toast('I am a toast!', 4000);
    }
});

My Adminnav-component:

<template>
    <div>
        <ul id="slide-out" class="side-nav">
            <li><div class="userView">
                <div class="background">
                    <img src="">
                </div>
                <a href="#!user"><img class="circle" src=""></a>
                <a href="#!name"><span class="white-text name">John Doe</span></a>
                <a href="#!email"><span class="white-text email">[email protected]</span></a>
            </div></li>
            <li><a href="#!"><i class="material-icons">cloud</i>First Link With Icon</a></li>
            <li><a href="#!">Second Link</a></li>
            <li><div class="divider"></div></li>
            <li><a class="subheader">Subheader</a></li>
            <li><a class="waves-effect" href="#!">Third Link With Waves</a></li>
        </ul>
        <a href="#" data-activates="slide-out" class="btn" v-on:click="openSidenav">Sidenav</a>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Mainnav mounted');
        },
        methods: {
            openSidenav(){
                $('.button-collapse').sideNav('show');
            }
        }
    }
</script>

And the html-file:

<body>
    <div id="app">
        <adminnav></adminnav>

        @yield('content')
    </div>

    <script src="{{ asset('assets/js/adminarea.js') }}"></script>
</body>

jQuery itself works, too. I don't know where to initialize the materilizecss-components. Any ideas?

Thanks!


Solution

  • Take a look at https://vuematerial.github.io/#/getting-started You have a lot of custom components which are pretty easy to use. If you want to stick to your implementation you have 2 options

    import Materialize from 'materialize-css/js/materialize.js';
    const app = new Vue({
     el: '#app',
     data: {
        title: 'Admindashboard'
     },
     methods: {},
     mounted() {
        console.log('Da bin ich!');
        Materialize.toast('I am a toast!', 4000);
     }
    });
    

    or

    import Materialize from 'materialize-css/js/materialize.js'; window.Materialize = Materialize;

    I suggest not setting Vue to window because there is no need to do so. Same with axios. You can bind axios to the vue instance instead. Vue.prototype.$http = axios. You can make calls via this.$http.get.... after that. Also stick with imports only rather than combining require and imports.