• 如何在传统前端项目中进行javascript模块化编程,并引入使用vue.js、elementui,并且不依赖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=" 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

    效果图:

  • 相关阅读:
    XGBoost算法--学习笔记
    机器学习--学习书籍
    一天搞懂深度学习-深度学习新浪潮
    如何在 Office 365 环境中设置联机 Exchange 邮箱大小和限制
    玩转Office 365中的Exchange Online服务 之十一 怎样在Exchange Online中配置邮件传递限制《转》
    玩转Office 365中的Exchange Online服务 之六 了解Exchange Online对于邮箱使用的限制《转》
    Hyper-V Ubuntu修改分辨率
    k8s 集群基本概念<转>
    Azure 中 Linux VM 的 SSH 公钥和私钥对
    docker学习笔记(k8s) 《转》
  • 原文地址:https://www.cnblogs.com/s0611163/p/15511728.html
Copyright © 2020-2023  润新知