通过AJAX加载Vue组件

通过AJAX加载Vue组件,ajax,vue.js,components,Ajax,Vue.js,Components,我希望通过AJAX动态加载Vue组件并呈现其模板 主Vue实例: const router = new VueRouter({ path: '/vue/actions/', mode: 'history' }); var app = new Vue({ el: '#mainContainer', router, data: { mainContent: '' }, methods: { action: fu

我希望通过AJAX动态加载Vue组件并呈现其模板

主Vue实例:

const router = new VueRouter({
    path: '/vue/actions/',
    mode: 'history'
});

var app = new Vue({
    el: '#mainContainer',
    router,
    data: {
        mainContent: ''
    },
    methods: {
        action: function (url) {
            alert(url);
            this.$router.push({ path: '/vue/actions/?'+url});
            console.log(this.$route.query);
        },
        actions: function () {
            var action;
            if (!this.$route.query.action || this.$route.query.action == 'main') {
                action = 'index';
            } else {
                action = this.$route.query.action;
            }
            var mainContent;
            fetch('/vue/actions/?content_type=json&action='+action).then((response) => {
                if(response.ok) {
                    return response.json();
                }
                throw new Error('Network response was not ok');
            }).then((json) => {
                this.$router.push({ path: '/vue/actions/', query: { action: json.action }});
                // this.mainContent = json.template;
                console.log(json.template);
                this.dynamicComponent = json.template;
            }).catch((error) => {
                console.log(error);
            });
        }
    },
    created: function () {
        this.actions();
    }
})
const router = new VueRouter({
    path: '/vue/actions/',
    mode: 'history'
});

var app = new Vue({
    el: '#mainContainer',
    router,
    data: {
        mainContent: ''
    },
    methods: {
        action: function (url) {
            this.$router.push({ path: '/vue/actions/?'+url});
            console.log(this.$route.query);
        },
        actions: function () {
            var action;
            if (!this.$route.query.action || this.$route.query.action == 'main') {
                action = 'index';
            } else {
                action = this.$route.query.action;
            }
            Vue.component('dynamic-component', (resolve) => {
                import('/vue/actions/?content_type=javascript&action='+action).then((component) => {
                    resolve(component.default);
                });
            });
        }
    },
    created: function () {
        this.actions();
    }
})
首页:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title></title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="" />
    <meta name="author" content="" />
    <meta http-equiv='cache-control' content='no-cache'>
    <meta http-equiv='expires' content='0'>
    <meta http-equiv='pragma' content='no-cache'>
    <script type="text/javascript" src="/js/vue.min.js"></script>
    <script src="/js/vue-router.js"></script>
</head>
<body>
<template><div><component :is="dynamicComponent"></component></div></template>
<div id="mainContainer" v-html="mainContent"></div>
<script type="text/javascript" src="/js/main.js"></script>
</body>
</html>

我希望通过AJAX加载的组件:

Vue.component('dynamicComponent', {
    template: '<div>Dynamic Component!</div>'
});
Vue.component('dynamicComponent'{
模板:“动态组件!”
});

是否可以加载此类Vue组件并呈现其模板(能够在组件模板中使用Vue数据绑定)?

以下是我获得所需内容的方法:

主Vue实例:

const router = new VueRouter({
    path: '/vue/actions/',
    mode: 'history'
});

var app = new Vue({
    el: '#mainContainer',
    router,
    data: {
        mainContent: ''
    },
    methods: {
        action: function (url) {
            alert(url);
            this.$router.push({ path: '/vue/actions/?'+url});
            console.log(this.$route.query);
        },
        actions: function () {
            var action;
            if (!this.$route.query.action || this.$route.query.action == 'main') {
                action = 'index';
            } else {
                action = this.$route.query.action;
            }
            var mainContent;
            fetch('/vue/actions/?content_type=json&action='+action).then((response) => {
                if(response.ok) {
                    return response.json();
                }
                throw new Error('Network response was not ok');
            }).then((json) => {
                this.$router.push({ path: '/vue/actions/', query: { action: json.action }});
                // this.mainContent = json.template;
                console.log(json.template);
                this.dynamicComponent = json.template;
            }).catch((error) => {
                console.log(error);
            });
        }
    },
    created: function () {
        this.actions();
    }
})
const router = new VueRouter({
    path: '/vue/actions/',
    mode: 'history'
});

var app = new Vue({
    el: '#mainContainer',
    router,
    data: {
        mainContent: ''
    },
    methods: {
        action: function (url) {
            this.$router.push({ path: '/vue/actions/?'+url});
            console.log(this.$route.query);
        },
        actions: function () {
            var action;
            if (!this.$route.query.action || this.$route.query.action == 'main') {
                action = 'index';
            } else {
                action = this.$route.query.action;
            }
            Vue.component('dynamic-component', (resolve) => {
                import('/vue/actions/?content_type=javascript&action='+action).then((component) => {
                    resolve(component.default);
                });
            });
        }
    },
    created: function () {
        this.actions();
    }
})
主/首页正文:

<body>
<div id="mainContainer">
    <dynamic-component></dynamic-component>
</div>
<script type="text/javascript" src="{{.__web_root_folder}}/js/main.js"></script>
</body>

我在需要时加载的组件代码:

export default {
    template: '<div>Async Component! {{.test}}</div>',
    data () {
        return {
            test: 'Works!'
        }
    }
}
导出默认值{
模板:“异步组件!{{.test}}”,
数据(){
返回{
测试:“有效!”
}
}
}

感谢@MazinoSUkah

为什么要通过ajax加载组件?@MazinoSUkah我只想在需要的时候发送组件,而不是使用ajax加载组件,那么可能吧?相反,只需在组件中添加一个
v-if=“someTrigger”
,并在希望加载组件时将其值切换为true。在vue中,v-if加载是“延迟”的,这意味着只有当v-if的计算结果为true时,组件才实际加载。@helgi听起来像是需要网页包代码splitting@helgi没错,你很高兴,很不幸,这在Firefox中不起作用(现在),有没有替代方案?以某种方式绑定/评估通过Ajax动态加载的JS文件?我尝试将其解析为JSON,但失败了,因为在JSON中创建函数是无效的object@NelsonRodriguez关于FF你是对的,这是最遗憾的。我没有找到我提供的更好的解决方案。您可以做的一件事是使用JSTranspiler Bable或Webpack,并使此代码在FF中工作。