FranckFreiburger / http-vue-loader

load .vue files from your html/js
MIT License
1.49k stars 275 forks source link

[Solution] ES6+ dynamic imports, no babel #94

Closed gaby64 closed 4 years ago

gaby64 commented 4 years ago

Here is the solution I found for using imports within .vue files, through http-vue-loader The biggest issue is that HTML case is lost, so use kebab case in html. Also, html tags require closing tags.

main.js

import Vue from "./lib/vue.esm.browser";
import router from "./router";
import store from "./store";
import { ValidationObserver, ValidationProvider, extend, Rules } from "./lib/vee-validate.full.esm";

Vue.use(httpVueLoader);
httpVueLoader.register(Vue, 'App.vue');

new Vue({
    router,
    store,
    render: h => h(Vue.component('App'))
}).$mount("#app");

App.vue

<template>
    <div id="app">
        <nav-bar :route="$route.fullPath"></nav-bar>
        <router-view :key="$route.fullPath"></router-view>
    </div>
</template>

<script>
    module.exports = Promise.all([import("./vue.esm.browser"), import("./vuex.esm.browser"), import("./vee-validate.full.esm"), httpVueLoader('./components/NavBar.vue')]).then(([mVue, mVuex, mVee, NavBar])  => {
        const Vue = mVue.default;
        const {mapState, mapMutations, mapActions, mapGetters} = mVuex;
        const {ValidationObserver,  ValidationProvider} = mVee;

        return Promise.resolve({
            name: 'App',
            components: {
                NavBar,
                ValidationProvider,
                ValidationObserver
            },
            props: {

            },
            data() {
                return {
                    cool: true
                }
            }
        });
    });
</script>

NavBar.vue

<template>
    <span>
        <div id="nav" class="nav">
            <div id="header_wrapper">
                <nav id="header">
                    <router-link to="/" id="logo" aria-label="home"></router-link> 
                    <div id="nav_wrapper"></div>
                    <ul v-show="$usr.uid" active-menu="selected">
                        <li v-show="$usr.admin">
                            <router-link to="/invite">Invite</router-link>
                        </li>
                        <li v-show="$usr.admin">
                            <router-link to="/dash">Dashboard</router-link>
                        </li>
                        <li>
                            <router-link to="/logout">Logout</router-link>
                        </li>
                    </ul>
                    <span v-show="$usr.user">Welcome {{$usr.user}}</span>
                </nav>
            </div>
        </div>
    </span>
</template>

<script>
    module.exports = {
        name: "NavBar",
        props:{
            route: String
        }
    }
</script>
akauppi commented 4 years ago

A bit more explanation would be useful in the issue.

I came to this because using ES modules import and export default does not work, within The .vue script section, and I would like them to, while loading with httpVueLoader. Is this the problem you are suggesting a solution to?

Do you have a code base I could check that exhibits this solution? I'm interested in the larger setup.

What I really am looking for is a way to code .vue normally, yet have httpVueLoader read this in. Has anyone worked on this, i.e. a branch of the code that is ES module compatible?

Have you seen #84 - looks like a duplicate, but with async/await syntax.

gaby64 commented 4 years ago

that is what my code above does

the key bit is to chain your imports in a Promise.all and resolve that promise with your component object. I show library imports and a component import. I have examples for using this in routes aswell, but I would need to get on my work computer to find it. Altho I have ceased developement this way as webpack offers many optimizations that cannot be done this way.

module.exports = Promise.all([import("./vue.esm.browser"), import("./vuex.esm.browser"), import("./vee-validate.full.esm"), httpVueLoader('./components/NavBar.vue')]).then(([mVue, mVuex, mVee, NavBar]) => {

module.exports replaces export default as this is what httpVueLoader understands.

module.exports = {
        name: "NavBar",
        props:{
            route: String
        }
    }
vuhanguyen commented 4 years ago

Thanks your way helps me a lot