利用requirejs實現vue的模塊化開發


通常vue都是搭配webpack+vue-cli使用的

如果不在nodejs環境下開發web應用呢?

這里提出一個解決方案:

1、加載requirejs,並且指定main函數

<script data-main="js/main" src="https://cdn.bootcss.com/require.js/2.3.5/require.min.js"></script>

2、定義main函數

require.config({
    paths: {
        "text": 'https://cdn.bootcss.com/require-text/2.0.12/text.min',
        'vueLoader': 'componentLoader',
        'article': '../components/article',
        'color': '../components/dialog/color',
        'util': './common/util',
        'app': './workspace/vueSet',
    },
    waitSeconds: 3
});


require(['vueLoader', 'componentConfig', 'app'], (CptLoader, commCpt, app) => {
    CptLoader.config(commCpt,()=>{
        setTimeout(()=>{
            app.$mount(app.$el);
        })
    })
});

可以注意到,這提供了一個CptLoader

3、組件loader源碼如下所示:

/**
 * 組件加載器
 */

//緩存Vue對象
var pool = {};


define([], () => {
    //根據path獲取名稱
    function cal(path) {
        let r = path.split('/');
        return r[r.length - 1];
    }

    return {
        /**
         * 加載全局配置單
         * @param configs
         */
        config(configs, res){
            return new Promise(() => {
                configs.forEach((path, index) => {
                    require(['text!../components/' + path + '.html', '../components/' + path], (html, js) => {
                        let v = {
                            template: html,
                            mixins: [
                                js
                            ]
                        };
                        pool[path] = v;
                        let name = cal(path);
                        Vue.component('v-' + name, pool[path]);
                        if (res && index == configs.length - 1)
                            res();
                    });
                });
            });
        },
        /**
         * 加載指定path的組件,返回Promise
         * @param path
         * @returns {function(*)}
         */
        load(path){
            return res => {
                let t;
                if (t = pool[path])
                    res(t);
                else
                    require(['text!../components/' + path + '.html', '../components/' + path], (html, js) => {
                        let v = {
                            template: html,
                            mixins: [
                                js
                            ]
                        };
                        pool[path] = v;
                        res(v);
                    });
            }
        }
    };
});
View Code

它提供了兩個函數:

a、config,用於加載一個數組作為配置單,該數組內的字符串都會被當作vue全局組件加載

b、load,加載單個vue組件

需要注意的是,它默認組件會全部存放在./components下

 

4、編寫組件html和js

html即是標准的template寫法,不再贅述

js示例如下所示:

 

define(['app','vueLoader'], (app,loader) => {
    return {
        props: ['module', 'toggleIcon', 'thisModule', 'moduleList', 'addModuleListIndex', 'moduleCategoryList', 'iconName'],
        data(){
            return {
                showElement: false,
                type: 'tplList',
                moduleConfig: [
                    {
                        name: '文字',
                        type: 'wordage',
                        flag: 0,
                    },
                    {
                        name: '圖片',
                        type: 'groupArea',
                        flag: 0,
                    },
                    {
                        name: '地圖',
                        type: 'map',
                        flag: 1,
                    },
                    {
                        name: '地圖2',
                        type: 'map',
                        flag: 1,
                    }
                ],
            }
        },
        created(){
            console.log('module-list create');
        },
        mounted(){
            console.log('module-list mounted');
        },
        methods: {
            //添加模板切換功能加顯示對應的模塊列表
            showModuleList: function (index, moduleName) {
                app.showModuleList(index, moduleName);
            },
            toggleIcon(){
                this.iconName = this.iconName == this.type ? "" : this.type;
                //加載內容的代碼轉移到此處
            }
        },
        components:{
            'palette-item':loader.load('palette-item'),
            test:{
                template:'<div>123</div>'
            }
        }
    }
});

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM