如何在傳統前端項目中進行javascript模塊化編程,並引入使用vue.js、element-ui,並且不依賴nodejs和webpack?


最近接手一個Web三維項目,前后端分離,前端是傳統的前端項目,但又是模塊化的開發方式,在修改的過程中,我需要做一些增刪改查的功能,又想盡可能少的寫css、盡可能少的直接操作DOM元素,所以引入了element-ui和vue,但是又不想依賴nodejs和webpack,不想引入相關配置文件,就實現了一個方案:

如何在傳統前端項目中進行javascript模塊化編程,並引入使用vue.js、element-ui,並且不依賴nodejs和webpack?

這里有一個問題,如果前端頁面使用.vue擴展名,又沒有相關配置,vscode不識別,沒有代碼着色,一片白,所以我是直接在html文件中寫模塊的css和template。

該方案開發的項目的源代碼,直接扔到IIS就能跑,無需打包。

以 CameraRelation 這個模塊為例:

一、在index.html中引用vue.js、element-ui的css、element-ui的js

在index.html中添加:

<link type="text/css" rel="stylesheet" href="build/element-ui/index.css">
<script type="text/javascript" src="build/vue/vue.js"></script>
<script type="text/javascript" src="build/element-ui/index.js"></script>
View Code

二、編寫模塊的html

cameraRelation.html代碼:

<html>

<head>
    <style type="text/css">
        .cameraRelation-rightContainer {
            line-height: 38px;
        }
    </style>
</head>

<body>
    <div id="cameraRelation">
        <el-dialog title="攝像機設備關聯模型" :visible.sync="dialogVisible" width="1300px" :before-close="handleClose"
            :close-on-press-escape="false" :close-on-click-modal="false">

            <el-row :gutter="20">
                <el-col :span="6" class="cameraRelation-rightContainer">
                    <span>模型ID:</span>
                    <span>{{modelIds}}</span>
                </el-col>
                <el-col :span="12" class="cameraRelation-rightContainer">
                    <span>模型名稱:</span>
                    <span>{{modelNames}}</span>
                </el-col>
                <el-col :span="4">
                    <el-input placeholder="請輸入內容" v-model="input" clearable>
                    </el-input>
                </el-col>
                <el-col :span="2">
                    <el-button type="primary" @click="search()">查詢</el-button>
                </el-col>
            </el-row>

            <el-row>
                <el-table ref="singleTable" :data="tableData" highlight-current-row
                    @current-change="handleCurrentChange" style="width: 100%" height="400">
                    <el-table-column type="index" width="50">
                    </el-table-column>
                    <el-table-column property="id" label="攝像機ID" width="400">
                    </el-table-column>
                    <el-table-column property="name" label="攝像機名稱">
                    </el-table-column>
                    <el-table-column property="modelId" label="關聯模型ID集合" width="200">
                    </el-table-column>
                    <el-table-column property="modelName" label="關聯模型名稱集合" width="200">
                    </el-table-column>
                </el-table>
                <!--
                <div style="margin-top: 20px">
                    <el-button @click="setCurrent(tableData[1])">選中第二行</el-button>
                    <el-button @click="setCurrent()">取消選擇</el-button>
                </div> 
                -->
            </el-row>

            <span slot="footer" class="dialog-footer">
                <el-button type="primary" @click="deleteRelation">刪除關聯</el-button>
                <el-button type="primary" @click="ok">關 聯</el-button>
            </span>

        </el-dialog>
    </div>
</body>

</html>
View Code

三、編寫模塊的js

CameraRelation.js代碼:

/**
 * 平台攝像機關聯模型
 */

import { API } from '../js.my/API.js';
import { Msg } from '../js.my/Msg.js';
import { LoadHtml } from '../js.my/LoadHtml.js';

let api = new API();
let msg = new Msg();
let loadHtml = new LoadHtml();

loadHtml.load('./view/cameraRelation.html', 'cameraRelation-container');

let vue = new Vue({
    el: "#cameraRelation",
    created() {

    },
    data() {
        return {
            dialogVisible: false,
            input: '',
            modelIds: '',
            modelNames: '',
            tableData: [{
                id: '',
                name: '',
                modelId: '',
                modelName: ''
            }],
            currentRow: null
        };
    },
    methods: {
        handleClose(done) {
            done();
        },
        ok() {
            if (this.currentRow) {
                msg.confirm("確定關聯?", "提示", () => {
                    let data = {
                        id: this.currentRow.id,
                        name: this.currentRow.name,
                        model_id: this.modelIds,
                        model_name: this.modelNames
                    }

                    api.updatePtCameraInfo(data, () => {
                        this.search();
                        msg.show("模型關聯攝像機設備成功");
                    });
                });
            } else {
                msg.show("請點擊選擇一條數據");
            }
        },
        deleteRelation() {
            if (this.currentRow) {
                msg.confirm("確定刪除該攝像機設備的模型關聯?", "提示", () => {
                    let data = {
                        id: this.currentRow.id,
                        name: this.currentRow.name,
                        model_id: '',
                        model_name: ''
                    }

                    api.updatePtCameraInfo(data, () => {
                        this.search();
                        msg.show("攝像機設備刪除模型關聯成功");
                    });
                });
            } else {
                msg.show("請點擊選擇一條數據");
            }
        },
        show(modelIds, modelNames) {
            this.modelIds = modelIds;
            this.modelNames = modelNames;
            this.dialogVisible = true;
            this.search();
        },
        search() {
            api.getPtCameraList(this.input.trim(), data => {
                this.tableData = data;
            });
        },
        setCurrent(row) {
            this.$refs.singleTable.setCurrentRow(row);
        },
        handleCurrentChange(val) {
            this.currentRow = val;
        }
    }
});

let CameraRelation = function () {
    this.show = vue.show;
}

CameraRelation.prototype.constructor = CameraRelation;

export { CameraRelation }
View Code

CameraRelation.js代碼中使用了Vue,使用了LoadHtml.js模塊以同步的方式加載cameraRelation.html

四、同步方式加載html的工具類

該模塊使用了jquery

代碼中為什么不把請求到的html內容直接添加到body中,而是再包裹一層div?因為直接添加到body中導致其他功能報錯,即使把內容中的html、head、body標簽去除也不行。

/**
 * 同步加載html
 */

let LoadHtml = function () {

    /**
     * 同步加載html
     * @param {string} url html的url地址
     * @param {string} containerId div容器id
     */
    this.load = function (url, containerId) {
        $.ajax({
            url: url,
            type: 'GET',
            dataType: 'html',
            async: false, //同步方式請求
            success: function (data) {
                if ($('#' + containerId).length == 0) {
                    $('body').append('<div id="' + containerId + '"></div>');
                    $('#' + containerId).html(data);
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (XMLHttpRequest.responseText) {
                    console.log("網絡請求出錯:", XMLHttpRequest.responseText);
                } else {
                    console.log("網絡請求出錯:", XMLHttpRequest);
                }
            }
        });
    }

}

LoadHtml.prototype.constructor = LoadHtml;

export { LoadHtml }
View Code

五、在CameraRelation.js模塊中加載依賴的cameraRelation.html

首先導入模塊:

import { LoadHtml } from '../js.my/LoadHtml.js';
View Code

然后加載cameraRelation.html:

let loadHtml = new LoadHtml();

loadHtml.load('./view/cameraRelation.html', 'cameraRelation-container');
View Code

六、index.html中引用show.js

show.js是和index.html對應的業務功能的主模塊

<script type="module" src="./js/show.js"></script>
View Code

七、在show.js文件中引入並使用CameraRelation模塊:

Ray2.js模塊用於在三維場景中拾取三維模型,然后使用對話框模塊CameraRelation.js顯示編輯界面

import { CameraRelation } from '../js.my/CameraRelation.js';
import { Ray2 } from '../js.my/Ray2.js';


let cameraRelation;
let ray2;


//平台攝像機關聯模型
let rayCallback = function (result) {
    if (result.length > 0) {
        let modelIds = "";
        let modelNames = "";

        let pos = result[0].name.lastIndexOf('_');
        let namePre = result[0].name.substr(0, pos);

        objects.all.map(obj => {
            if (obj.name.indexOf(namePre) >= 0) {
                modelIds += obj.id + ",";
                modelNames += obj.name + ",";
            }
        });

        if (!cameraRelation) {
            cameraRelation = new CameraRelation();
        }

        cameraRelation.show(modelIds, modelNames);
    }
}
$("#ray-start").on("click", function (event) {
    if (!ray2) {
        ray2 = new Ray2();
        ray2.config(objects, camera, scene, "GV", rayCallback);
        ray2.start();
    } else {
        ray2.start();
    }
    msg.show("請點擊選擇攝像機模型");
});
$("#ray-stop").on("click", function (event) {
    if (ray2) {
        ray2.stop();
        msg.show("攝像機關聯模型操作結束");
    }
});
View Code

如何支持.vue擴展名的文件?
在LoadHtml工具類中加入如下代碼:

/**
 * 同步加載vue文件
 * @param {string} url vue文件的url地址
 * @param {string} containerId div容器id
 */
static loadVue = function (url, containerId) {
    $.ajax({
        url: url,
        type: 'GET',
        dataType: 'html',
        async: false,
        success: function (data) {
            let regTmpl = /<template[^>]*>([\s\S]*)<\/template[^>]*>/;
            let regStyle = /<style[^>]*>([\s\S]*)<\/style[^>]*>/;
            let template = regTmpl.exec(data)[1];
            let style = regStyle.exec(data)[1];

            if ($('#' + containerId).length == 0) {
                $('body').append('<div id="' + containerId + '"></div>');
                $('#' + containerId).html(template + '<style type="text/css">' + style + '</style>');
            }
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            if (XMLHttpRequest.responseText) {
                console.error("網絡請求出錯:", XMLHttpRequest.responseText);
            } else {
                console.error("網絡請求出錯:", XMLHttpRequest);
            }
        }
    });
}
View Code

使用示例:

LoadHtml.loadVue('../views/switchMapControl.vue', 'switchMapControlContainer');
View Code

效果圖:

 


免責聲明!

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



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