zoukankan      html  css  js  c++  java
  • requirejs、vue、vuex、vue-route的结合使用,您认为可行吗?

         在五一节之前和一网友讨论前端技术时,对方提到vue、vue-route如果配合requirejs应用。当时的我没有想得很明白,也没能这位网友一个准确的回复,但我许诺于他五一研究后给他一个回复。本是一天的研究却被我搞成了研究了一周,这拖延症。。。

    闲话少数,进入正题

    一、示例代码说明

    代码结构说明:

    1. modules(存放的为组件,主要是模板与Js对象分成两个文件来写)
      1. route:测试子路由的组件
      2. title:就是一个简单的显示文字的组件
    2. app.js:核心类,提供vue的创建、以前modules组件加载的方法等
    3. chart.js:模拟的一个业务模块
    4. index.html:页面文件
    5. layout.css:整体样式文件(测试require加入样式文件)
    6. main.js:requirejs的配置文件(也是入口文件)
      丑陋的效果图:

    此示例没有样式,只是为了验证require如何加载一个vue组件,以子路由的动态注入的能力,示例代码下载

    二、从.vue文件入手

          一个.vue文件可以包含模板、Js类、样式(可以不要)等三块。但我们通过vue的官网可以知道,vue提供了compile对象方法,可以把模板编译成VNode。并且我们通过webpack打包后生成的文件可以看出模板与Js类是混淆在一起了。这也就说明vue的组件就是一个Js对象。如下图所示:

    三、requirejs对vue、vuex和vue-route的引入

         引入这三个都很容易,并将这三个注入到Vue对象也是相对简单的,难道的是需要解决动态注入向vue-route实例注入路由,以及vuex的动态加入一个数据模块的能力。好在这两点官网都给出了解决方案:

    • vue-route如何动态注入路由
      根据官网帮助文档说明,存在addRoutes方法,向路由实体动态注入路由
    • vuex模块动态注入
      也是根据官网帮助文档提示有registerModule方法实现。
    • 实现的部分代码:
      初始化Vue对象
    apt.init = function(){
        this.store = Object.create({
            modules:{}
        });        
        this.Vue.use(VueRouter);
        this.Vue.use(Vuex);
        this.router = new VueRouter(); 
        this.store = new this.Vuex.Store(this.store);
    }

    首先提供一个init方法,对Vue对象进行一些初始化,也就是把Vuex、vue-route都注入到Vue对象中。在这里我把创建的vuex和vue-route的实例都放到this对象,方便后面提供给组件注册实使用。
    创建Vue实例:

    apt.createVue = function(){
        this.vue = new this.Vue({
            store: this.store,
            router: this.router,
            computed: {
                childs: function(){
                    if(!this.$store.state.router) return null;
                    return this.$store.state.router.childs;
                }
            }
        });
        return this.vue;
    }

    只创建vue对象,没有进行mount。
    为其他模块提供的上下文:

    apt.createContext = function(){
        return {
            Vue: this.Vue,
            router: this.router,
            $vue: this.vue
        };
    }

    四、如何通过require加载html和js方式的组件

    从项目结构图中可以看出在modules文件夹中定义了两个组件,分别是:routet和title,而他们的模板则是一个html文件。以下是这类组件如何加载的代码:

    apt.acquire = function(path){
        var arrayPath;
        if(!this.isArray(path)){
            arrayPath = [path];
        }else{
            arrayPath = path;
        }
        var promise = this.dfd(function(dfd){
            require(arrayPath,function(){
                dfd.resolve(Array.prototype.slice.call(arguments));
            },function(error){
                dfd.reject(error);
            });
        }).promise();
        return promise;
    }
    
    apt.createComponent = function(componentName){
        //可以重载,读取.vue的文件
        var path = this.$modulePrefix + componentName,
        html = 'text!' + path + '/index.html',
        js = path + '/index.js',
        self = this;
        var promise = this.acquire([html,js]);
        promise.done(function(result){
            var obj = result[1], content = result[0];
            obj.template = content;
            obj.__path__ = path;
            self.$components.push(obj);
        });
        return promise;
    }

    说明: acquire:提供通过require加载JS或者是html等文件的方法,并返回一个promise,这样就方便调用者使用。 createComponet:会根据调用传入的名称在modules文件夹中找出对应的js和html文件,然后调用acquire加载组件。

    五、main.js是这样引用的

    提供注册全局组件方法

    apt.registerGlobalComponents = function(componentNames){
        var gloadComponet = componentNames, self = this;
        var promises = gloadComponet.map(function(data,index){
            return self.createComponent(data);
        });
        var dfd = this.dfd();
        $.when.apply(null, promises).done(function(){
            var _router = [];
            self.$components.forEach(function(data,index){
                self.Vue.component(data.name, data);
                _router.push({
                    path: '/' + data.name,
                    component: data
                });
            });
            self.router.addRoutes(_router); //全局注册都注册为路由
            dfd.resolve(_router);
        });
        return dfd.promise();
    }

    main.js中的引用

    var _app = app.createApp();
    _app.registerGlobalComponents(['title', 'route']).done(function(){
        var vue = _app.createVue();
        var cxt = app.getVue().createContext();
        var r = {
            state: {
                childs: []
            },
            mutations: {
                childs: function(state, data){
                    state.childs = data;
                }
            },
            actions: {
                childs: function(state, data){
                    state.commit('childs', data);
                }
            }
        }
        vue.$store.registerModule('router', r);
        vue.$mount('#app');
    });

    说明:

    1. 创建App的一个实例;
    2. 注册全局的组件:title、route;
    3. 注册完成后创建vue实例,并且向实例的vuex注入二级路由展示的模块
  • 相关阅读:
    SQL 强化练习 (七)
    SQL 强化练习 (六)
    SQL 强化练习 (五)
    SQL 强化练习 (四)
    典型相关分析 CCA
    SQL 强化练习(三)
    双向 和 多重 RNN
    SQL 强化练习 (二)
    SQL 强化练习 (一)
    SQL 查询强化
  • 原文地址:https://www.cnblogs.com/cqhaibin/p/6823286.html
Copyright © 2011-2022 走看看