Vue Element 使用整理笔记

js执行     (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]]
有惊喜!!!

  1. 未初始化的数据,例如设置对象不存在的属性,用this.$set(object, attribute, value)方法设置,否则不是响应式数据,组件不根据数据的改变重新渲染页面;
  2. 如果组件绑定的数据初始化后,组件还在工作,可用v-if来销毁组件;
  3. 为组件设置key,key改变组件会重新创建加载;
  4. Dialog 对话框 使用 ueditor富文本 时,关闭时要调用 $('#ueditor_textarea_editorValue').remove() 方法清除富文本缓存,否则二次以后加载失败;
  5. ueditor富文本 使用:
        1) 下载ueditor富文本文件夹放到/public路径下,在/public/index.html中引入
                   
    <script src='<%= BASE_URL %>neditor/neditor.config.js'></script>
    <script src='<%= BASE_URL %>neditor/neditor.all.js'></script>
    <script src='<%= BASE_URL %>neditor/neditor.service.js'></script>
    <script src='<%= BASE_URL %>neditor/neditor.parse.js'></script>
    <script src='<%= BASE_URL %>neditor/i18n/zh-cn/zh-cn.js'></script>
        2) /src/components/editor路径下创建组件index.vue
    <template>
        <div>
            <div :id="this.id"></div>
        </div>
    </template>
    
    <script>
        export default {
            name: 'editor',
            props: {
                id: {
                    type: String
                },
                defaultMsg: {
                    type: String,
                    default: ''
                },
                attach: {
                    type: String,
                    default: ''
                },
                config: {
                    type: Object,
                    default: {
                        initialFrameWidth: '100%',
                        initialFrameHeight: '350'
                    }
                }
            },
            data() {
                return {
                    ue: null
                }
            },
            mounted() {
                this.ue = UE.getEditor(this.id, this.config)
                this.ue.addListener('ready', () => {
                    this.ue.setContent(this.defaultMsg)
                })
                this.ue.addListener('contentChange', this.contentChange);
            },
            methods: {
                contentChange() {
                    this.$emit('editorContentChange', this.ue.getContent(), this.attach);
                    this.$emit('editorContentTxtChange', this.ue.getContentTxt(), this.attach);// 获取编辑器中的纯文本内容,没有段落格式
                    this.$emit('editorPlainTxtChange', this.ue.getPlainTxt(), this.attach);// 得到编辑器的纯文本内容,但会保留段落格式
                },
                getUeContent() {
                    return this.ue.getContent()
                },
                setUeContent(v) {
                    return this.ue.setContent(v)
                }
            },
            beforeDestroy() {
                this.ue.destroy()
                this.ue = null
            }
        }
    </script>
    

        3) 上传文件修改neditor.service.js文件及neditor.config.js文件
        4) 开启表情本地化 emotionLocalization:true,下载表情图片文件,放到 /public/neditor/dialogs/emotion/images/ 路径下
        5) 使用:
    <editor ref="resourceContent" :id="'editor'"
        :default-msg="template.resourceContent" 
        :config="editorConfig">
    </editor>
    
    import editor from '@/components/editor/index.vue'
    
    export default {
        components: {
            editor
        },
        data() {
            return {
                editorConfig: {
                    initialFrameWidth: '100%',
                    initialFrameHeight: 350,
                    zIndex: 3000
                },
            }
        }
    }
    
    

  6. Dialog 对话框 可使用 Tabs 标签页 或 Steps 步骤条 来分页签,校验时可用v-if来设置显示,也可以在点击下一步时,调用验证当前页表单项方法来完成校验;
  7. 设置 Tree 树结构 树节点选中状态高亮色的设置,
    .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
        background-color: #a6d1ff;
    }
    /deep/ .el-tree-node > .el-tree-node__children {
        overflow: visible !important;
    }
  8. 缩略图,用上传照片墙方式,但是只显示一张图片
    <el-form-item label="缩略图" prop="thumbnail">
        <el-upload class="avatar-uploader"
                   :class="{hide: template.thumbnailUrl}"
                   :action="uploadUrlCms"
                   :data="{'path': siteUploadPath, 'siteId': template.siteId}"
                   :accept="$store.state.common.imageAccepts"
                   :file-list="thumbnailList"
                   list-type="picture-card"
                   :on-success="handleAvatarSuccess"
                   :on-error="handleAvatarError"
                   :before-upload="beforeAvatarUpload"
                   :on-preview="handlePictureCardPreview"
                   :on-remove="handleAvatarRemove">
            <i class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
        <el-dialog :visible.sync="dialogVisiblePicture" :append-to-body="true">
            <img width="100%" :src="dialogImageUrl" alt="">
        </el-dialog>
    </el-form-item>
    /*缩略图*/
    .avatar-uploader .el-upload {
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
        width: 178px;
        height: 178px;
    }
    .avatar-uploader .el-upload:hover {
        border-color: #409EFF;
    }
    .avatar-uploader-icon {
        font-size: 28px;
        color: #8c939d;
        width: 178px;
        height: 178px;
        line-height: 178px;
        text-align: center;
    }
    .avatar {
        width: 178px;
        height: 178px;
        display: block;
    }
    .avatar-uploader .el-upload-list__item {
        width: 178px;
        height: 178px;
    }
    .avatar-uploader .el-upload-list__item .el-upload-list__item-status-label {
        display: none;
    }
    .hide .el-upload--picture-card {
        display: none;
    }
  9. element 使用竖向表格
      <table class="mailTable">
        <tr>
          <td class="column"></td>
          <td></td>
          <td class="column"></td>
          <td></td>
        </tr>
      </table>
    .mailTable, .mailTable tr, .mailTable tr td { 
        border:1px solid #E6EAEE; 
    }
    .mailTable { 
        font-size: 12px; 
        color: #71787E; 
    }
    .mailTable tr td { 
        border:1px solid #E6EAEE; 
        width: 150px; height: 35px; 
        line-height: 35px; 
        box-sizing: border-box;         
        padding: 0 10px; 
    }
    .mailTable tr td.column { 
        background-color: #EFF3F6; 
        color: #393C3E; 
    }

  10. 替换element图标
    <i class="not-evaluated"></i> 
    
    .not-evaluated{
        background: url(../img/notEvaluated.jpg) center no-repeat; // 要替换的图片
        background-size: cover;
    }
    .not-evaluated:before{
        content: "替"; // 占位文字,必须!
        font-size: 14px;
        line-height: 14px;
        visibility: hidden; // 隐藏占位文字
    }

  11. 移动端H5页面注意
    // 在<head>标签插入
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
    
    // width=device-width    应用程序的宽度和屏幕的宽度是一样的
    // height=device-height  应用程序的高度和屏幕的高是一样的
    // initial-scale=1.0     应用程序启动时候的缩放尺度(1.0表示不缩放)
    // minimum-scale=1.0     用户可以缩放到的最小尺度(1.0表示不缩放)
    // maximum-scale=1.0     用户可以放大到的最大尺度(1.0表示不缩放)
    // user-scalable=no      用户是否可以通过他的手势来缩放整个应用程序,使应用程序的尺度发生一个改变(yes/no)

  12. el-date-picker时间选择范围控制
    <el-form-item>
        <el-date-picker
            :size="searchSize"
            v-model.trim="listQuery.addTime"
            type="date"
            placeholder="选择时间"
            value-format="yyyy-MM-dd"
            @change="dateChange"
            :picker-options="pickerOptions">
        </el-date-picker>
    </el-form-item>
    
    pickerOptions: {
        // disabledDate是一个函数,参数是当前选中的日期值,这个函数需要返回一个Boolean值,
        disabledDate: (time) => {
            // 如果函数处理比较简单,可以直接在这里写逻辑方法
            // return time.getTime() < Date.now() - 8.64e7
    
            // 如果函数里处理的数据比较麻烦,也可以单独放在一个函数里,避免data数据太臃肿
            return this.dealDisabledDate(time)
        }
    },
    
    dealDisabledDate (time) {
        // time.getTime是把选中的时间转化成自1970年1月1日 00:00:00 UTC到当前时间的毫秒数
        // Date.now()是把今天的时间转化成自1970年1月1日 00:00:00 UTC到当前时间的毫秒数,这样比较好比较
        // return的值,true是不可以操作选择,false可以操作选择,比如下面这个判断就只能选择今天之后的时间
        return time.getTime() > Date.now()
    
        // 这里减8.64e7的作用是,让今天的日期可以选择,如果不减的话,今天的日期就不可以选择,判断中写<= 也是没用的,一天的毫秒数就是8.64e7
        // return time.getTime() <= Date.now()
        // return time.getTime() < Date.now() - 8.64e7
    },

  13. el-table自定义表头/表尾及列合并/行合并
    <el-table :data="dailyPriceSurveyData" v-loading.body="listLoading" border 
    highlight-current-row :span-method="spanMethod" :summary-method="getAvgMOM" show-summary>
        <el-table-column label="日价格调查表" align="center">
        <el-table-column  :label="'农业信息网络中心&' + tableAddTime + '(单位: 元/公斤 元/升)'" 
        :render-header="renderHeader">
            <el-table-column
                align="center"
                prop="typeName"
                label="类别">
            </el-table-column>
            <el-table-column
                align="center"
                prop="productName"
                label="名称">
            </el-table-column>
            <el-table-column align="center" label="批发价格">
                <el-table-column
                    align="center"
                    prop="yesterdayWholesalePrice"
                    label="昨天"
                    :formatter="rounding">
                </el-table-column>
                <el-table-column
                    align="center"
                    prop="todayWholesalePrice"
                    label="今天"
                    :formatter="rounding">
                </el-table-column>
            </el-table-column>
            <el-table-column align="center" label="零售价格">
                <el-table-column
                    align="center"
                    prop="yesterdayRetailPrice"
                    label="昨天"
                    :formatter="rounding">
                </el-table-column>
                <el-table-column
                    align="center"
                    prop="todayRetailPrice"
                    label="今天"
                    :formatter="rounding">
                </el-table-column>
            </el-table-column>
            <el-table-column
                align="center"
            label="备注">
            </el-table-column>
        </el-table-column>
        </el-table-column>
    </el-table>
    
                reloadList(){
                    this.listLoading = true;
                    this.dailyPriceSurveyData = [];
                    this.spanArr = [];
                    getDailyPriceSurveyData(this.listQuery).then(response => {
                        this.listLoading = false;
                        this.dailyPriceSurveyData = response.data;
    
                        this.initSpanArr();
                    })
                },
    
                initSpanArr() {
                    // 定义一个空数组:[]
                    // 定义一个变量:0
                    // 遍历数据如果有相同数据 在空数组添加一个0(相同数据的起始位加1),不相同在数据push 一个1(变量改成当前索引)
                    let contactDot = 0;
                    this.dailyPriceSurveyData.forEach((item, index) => {
                        if(index === 0){
                            this.spanArr.push(1)
                        }else{
                            if(item.typeName === this.dailyPriceSurveyData[index-1].typeName){
                                this.spanArr[contactDot] += 1;
                                this.spanArr.push(0)
                            }else{
                                contactDot = index
                                this.spanArr.push(1)
                            }
                        }
                    })
                },
    
                spanMethod({ row, column, rowIndex, columnIndex }) {
                    if(columnIndex ===0){
                        if(this.spanArr[rowIndex]){
                            return {
                                rowspan:this.spanArr[rowIndex],
                                colspan:1
                            }
                        }else{
                            return {
                                rowspan: 0,
                                colspan: 0
                            }
                        }
                    }
                },
    
                // render 事件
                renderHeader (h,{column}) { // h即为cerateElement的简写,具体可看vue官方文档
                    let header = column.label.split('&');
                    return h(
                        'p', {style: 'margin: 0'},
                        [
                            h('p', {style: 'float: left; margin: 0'}, header[0]),
                            h('p', {style: 'float: right; margin: 0'}, header[1])
                        ],
                    );
                },
    
    
                rounding(row, column, cellValue, index) {
                    if (typeof cellValue == 'number') {
                        return cellValue.toFixed(2);
                    } else {
                        return cellValue;
                    }
                },
    
                // 自定义表尾
                getAvgMOM(param) {
                    const { columns, data } = param;
                    const sums = [];
                    columns.forEach((column, index) => {
                        if (index === 0) {
                            sums[index] = '平均值';
                            return;
                        }
                        if(column.property.toLowerCase() == 'mom') {
                            const values = data.map(item => Number(item[column.property]));
                            var mom = values.filter((value,index)=>{return !isNaN(value)});
                            if (mom.length > 0) {
                                sums[index] = (mom.reduce((a, b) => a + b) / mom.length).toFixed(2);
                            } else {
                                sums[index] = '-';
                            }
                            this.avgMOM = sums[index];
                        }
                    });
    
                    return sums;
                },

  14. Blob.js及Export2excel.js导出excel文件,行/列合并等
                export2Excel() {
                    if (!this.dailyPriceSurveyData || this.dailyPriceSurveyData.length == 0) {
                        this.$message.error('无导出数据');
                        return;
                    }
                    require.ensure([], () => {
                        const Export2excel = require('@/excel/Export2excel');
                        //对应表格输出的title
                        const tHeader1 = ['日价格调查表'];
                        const tHeader2 = ['农业信息网络中心' + this.tableAddTime + '(单位: 元/公斤 元/升)'];
                        const tHeader3 = ['类别', '名称', '批发价格', '', '零售价格', '', '备注'];
                        const tHeader4 = ['', '', '昨天', '今天', '昨天', '今天', ''];
                        // 对应表格输出的数据
                        const filterVal = ['typeName', 'productName', 'yesterdayWholesalePrice', 'todayWholesalePrice', 'yesterdayRetailPrice', 'todayRetailPrice', 'remark'];
                        const excelData = this.formatJson(filterVal, this.dailyPriceSurveyData);
                        // 添加表头
                        excelData.unshift(tHeader4);
                        excelData.unshift(tHeader3);
                        excelData.unshift(tHeader2);
                        excelData.unshift(tHeader1);
                        //对应下载文件的名字
                        Export2excel.exportDailyPriceSurveyData2Excel(excelData, '农产品日价格调查表excel' + new Date().toLocaleDateString().replace(/\//g,'-'));
                    })
                },
                formatJson(filterVal, jsonData) {
                    return jsonData.map(v => filterVal.map(j => v[j]))
                },
    
    
    
    // Export2excel.js
    /****************************************修改源码,添加方法start****************************************/
    export function exportDailyPriceSurveyData2Excel(jsonData, defaultTitle) {
    
        /* original data */
        var ws = sheet_from_array_of_arrays(jsonData);
    
        // 合并单元格
        mergeDailyCell(ws);
    
        /* add worksheet to workbook */
        writeExcel(ws, defaultTitle);
    }
    
    export function mergeDailyCell(ws) {
        // 合并单元格 - 表头
        ws["!merges"] = [
            {
                s: {    // s为开始
                    c: 0,   // col
                    r: 0    // row
                },
                e: {    // e为结束
                    c: 6,
                    r: 0
                }
            },
            {
                s: {
                    c: 0,
                    r: 1
                },
                e: {
                    c: 6,
                    r: 1
                }
            },
            {
                s: {
                    c: 0,
                    r: 2
                },
                e: {
                    c: 0,
                    r: 3
                }
            },
            {
                s: {
                    c: 1,
                    r: 2
                },
                e: {
                    c: 1,
                    r: 3
                }
            },
            {
                s: {
                    c: 2,
                    r: 2
                },
                e: {
                    c: 3,
                    r: 2
                }
            },
            {
                s: {
                    c: 4,
                    r: 2
                },
                e: {
                    c: 5,
                    r: 2
                }
            },
            {
                s: {
                    c: 6,
                    r: 2
                },
                e: {
                    c: 6,
                    r: 3
                }
            }
        ]
    
        mergeDataCell(ws, 5);
    }
    
    /**
     * 合并单元格 - 数据
     * @param ws excel对象
     * @param rowNumber 数据取值开始行数
     */
    export function mergeDataCell(ws, rowStart) {
        let mergeObj = {};
        Object.keys(ws).forEach(key => {
            // 第rowNumber行取数据
            if (key.indexOf('A') != -1 && key.slice(1) >= rowStart) {
                if(mergeObj.hasOwnProperty(ws[key].v)){
                    mergeObj[ws[key].v] += 1;
                    ws[key].v = '';
                }else{
                    Vue.set(mergeObj, ws[key].v, 0);
                }
            }
        })
        Object.keys(ws).forEach(key => {
            if (key.indexOf('A') != -1 && key.slice(1) >= rowStart) {
                if (mergeObj.hasOwnProperty(ws[key].v) && mergeObj[ws[key].v]) {
                    let merge = {
                        s: {
                            c: 0,
                            r: key.slice(1) - 1
                        },
                        e: {
                            c: 0,
                            r: key.slice(1) - 1 + mergeObj[ws[key].v]
                        }
                    }
                    ws["!merges"].push(merge);
                }
            }
        })
    }
    
    /**
     * 输出Excel
     * @param ws excel对象
     * @param defaultTitle 输出Excel名称
     */
    export function writeExcel(ws, defaultTitle) {
        var wb = new Workbook();
        var ws_name = "SheetJS";
        wb.SheetNames.push(ws_name);
        wb.Sheets[ws_name] = ws;
        var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
        var title = defaultTitle || '列表'
        saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx")
    }
    
    export function exportTenDayPriceSurveyData2Excel(jsonData, defaultTitle) {
    
        /* original data */
        var ws = sheet_from_array_of_arrays(jsonData);
    
        // 合并单元格
        mergeTenDayCell(ws);
    
        /* add worksheet to workbook */
        writeExcel(ws, defaultTitle);
    }
    
    export function mergeTenDayCell(ws) {
        // 合并单元格 - 表头
        ws["!merges"] = [
            {
                s: {    // s为开始
                    c: 0,   // col
                    r: 0    // row
                },
                e: {    // e为结束
                    c: 11,
                    r: 0
                }
            },
            {
                s: {
                    c: 0,
                    r: 1
                },
                e: {
                    c: 11,
                    r: 1
                }
            },
            {
                s: {
                    c: 0,
                    r: 2
                },
                e: {
                    c: 0,
                    r: 3
                }
            },
            {
                s: {
                    c: 1,
                    r: 2
                },
                e: {
                    c: 1,
                    r: 3
                }
            },
            {
                s: {
                    c: 2,
                    r: 2
                },
                e: {
                    c: 6,
                    r: 2
                }
            },
            {
                s: {
                    c: 7,
                    r: 2
                },
                e: {
                    c: 11,
                    r: 2
                }
            }
        ]
    
        mergeDataCell(ws, 5);
    }
    
    
    export function exportWeeklyPriceSurveyData2Excel(jsonData, defaultTitle) {
    
        /* original data */
        var ws = sheet_from_array_of_arrays(jsonData);
    
        // 合并单元格
        mergeWeeklyCell(ws);
    
        /* add worksheet to workbook */
        writeExcel(ws, defaultTitle);
    }
    
    export function mergeWeeklyCell(ws) {
        // 合并单元格 - 表头
        ws["!merges"] = [
            {
                s: {    // s为开始
                    c: 0,   // col
                    r: 0    // row
                },
                e: {    // e为结束
                    c: 5,
                    r: 0
                }
            },
            {
                s: {
                    c: 0,
                    r: 1
                },
                e: {
                    c: 5,
                    r: 1
                }
            }
        ]
    
        mergeDataCell(ws, 4);
    }
    /****************************************修改源码,添加方法end****************************************/

  15. js原生打印
    默认打印整个页面,需新打开一个页面写入需打印内容
    // 打印方法    
    printContent(content) {
        // console.log(content)
        // const oldHtml = document.body.innerHTML;
        // window.document.body.innerHTML = content;
        // window.print();
        // window.document.body.innerHTML = oldHtml;
        // 重新加载页面,以刷新数据
        // window.location.reload()
    
        var t = window.open("","打印");
        t.document.open();
        t.document.write(content);
        // 延迟打印,防止页面没有加载完成
        setTimeout(() => {
            t.window.print();
            t.close()
        }, 500);
    },

  16. element dialog弹窗高度根据内容而改变
    /* 弹框既能在视窗居中,又能在内容过多时防止弹框大小超出视窗,还能把滚动限制在body内部从而使得头和尾始终可见 */
        /deep/ .el-dialog{
            display: flex;
            flex-direction: column;
            margin:0 !important;
            position:absolute;
            top:50%;
            left:50%;
            transform:translate(-50%,-50%);
            /*height:600px;*/
            max-height:calc(100% - 30px);
            max-width:calc(100% - 30px);
        }
        /deep/ .el-dialog .el-dialog__header {
            padding: 10px 20px;
        }
        /deep/ .el-dialog .el-dialog__body{
            flex:1;
            overflow: auto;
            padding: 10px 20px;
        }
        /* 弹窗底部按钮居中 */
        /deep/ .el-dialog .el-dialog__footer {
            padding: 10px 20px;
            text-align: center;
            box-sizing: border-box;
        }
  17. 使用拼音插件
    // 安装
    npm install --save pinyin
    // 使用
    <script>
        import pinyin from 'pinyin';
    </script>

    使用方法查询文档

  18. echarts堆叠图总数计算显示
    <template>
        <basic-container>
            <div class="deyatech-container pull-auto">
                <div class="deyatech-header">
                    <el-form :inline="true" ref="searchForm">
                        <el-form-item>
                            <el-date-picker
                                :size="searchSize"
                                v-model.trim="dateRange"
                                type="daterange"
                                range-separator="至"
                                start-placeholder="开始时间"
                                end-placeholder="结束时间"
                                value-format="yyyy-MM-dd">
                            </el-date-picker>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" icon="el-icon-search" :size="searchSize" @click="searchGetStatisticsInfo">{{$t('table.search')}}</el-button>
                            <el-button icon="el-icon-delete" :size="searchSize" @click="resetSearch">{{$t('table.clear')}}</el-button>
                        </el-form-item>
                    </el-form>
                </div>
                <div class="splitBar"></div>
                <div class="row">
                    <div class="filter-container">
                    </div>
                    <div class="className" id="informationStatistics"></div>
                </div>
            </div>
        </basic-container>
    </template>
    
    <script>
        const echarts = require('echarts/lib/echarts');
        require('echarts/lib/chart/bar');
        require('echarts/lib/chart/pie');
        require('echarts/lib/chart/line');
        require('echarts/lib/component/tooltip');
        require('echarts/lib/component/legend');
        require('echarts/lib/component/toolbox');
        require('echarts/lib/component/title');
        require('echarts/lib/component/visualMap');
        require('echarts/lib/component/dataZoom');
        import {mapGetters} from 'vuex';
        import {
            getStatisticsInfo
        } from '@/api/market/information';
    
        export default {
            name: 'informationStatistics',
            data() {
                return {
                    dateRange: undefined,
                    listQuery: {
                        startDate: undefined,
                        endDate: undefined
                    },
                    statisticsInfo: undefined,
                    categoryName: [],
                    memberCategoryName: [],
                    seriesData: [],
                }
            },
            computed: {
                ...mapGetters([
                    'textMap',
                    'enums',
                    'closeOnClickModal',
                    'permission',
                    'titleMap',
                    'enums',
                    'searchSize',
                    'btnSize'
                ])
            },
            created() {
                this.getStatisticsInfo();
            },
            methods: {
                resetSearch() {
                    this.listQuery.startDate = undefined;
                    this.listQuery.endDate = undefined;
                },
                searchGetStatisticsInfo() {
                    if (this.dateRange) {
                        this.listQuery.startDate = this.dateRange[0];
                        this.listQuery.endDate = this.dateRange[1];
                    }
                    this.getStatisticsInfo();
                },
                getStatisticsInfo() {
                    this.categoryName = [];
                    this.memberCategoryName = [];
                    this.seriesData = [];
                    getStatisticsInfo(this.listQuery).then(response => {
                        if (response.status === 200) {
                            this.statisticsInfo = response.data;
                            // 获取echarts series数据
                            this.getSeriesData();
                            for (let info of this.statisticsInfo) {
                                // 设置堆叠条分类legend
                                if (this.categoryName.indexOf(info.categoryName) == -1) {
                                    this.categoryName.push(info.categoryName);
                                }
                                // 设置X轴xAxis
                                if (this.memberCategoryName.indexOf(info.memberCategoryName) == -1) {
                                    this.memberCategoryName.push(info.memberCategoryName);
                                }
                            }
                            // 初始化echarts
                            var e = echarts.init(document.getElementById('informationStatistics'));
                            e.setOption({
                                title: {
                                    text: '市场供求信息统计'
                                },
                                legend: {
                                    data: this.categoryName
                                },
                                tooltip: {
                                    trigger: 'axis'
                                },
                                toolbox: {
                                    show: true,
                                    feature: {
                                        mark: {show: true},
                                        dataView: {show: true, readOnly: false},
                                        magicType: {show: true, type: ['line', 'bar']},
                                        restore: {show: true},
                                        saveAsImage: {show: true}
                                    }
                                },
                                // calculable: true,
    /*                            dataZoom: [
                                    {
                                        show: true,
                                        start: 0,
                                        end: 100
                                    },
                                    {
                                        type: 'inside',
                                        start: 0,
                                        end: 100
                                    },
                                    {
                                        show: true,
                                        yAxisIndex: 0,
                                        filterMode: 'empty',
                                        width: 30,
                                        showDataShadow: false,
                                        left: '6%'
                                    }
                                ],*/
                                xAxis: [
                                    {
                                        type: 'category',
                                        axisLabel: {
                                            interval: 0,
                                            rotate: 45
                                        },
                                        data: this.memberCategoryName
                                    }
                                ],
                                yAxis: [
                                    {
                                        type: 'value'
                                    }
                                ],
                                series: this.seriesData
                            })
                            // 添加点击监听事件,重新计算总数
                            e.on("legendselectchanged", function (obj) {
                                const option = e._model.option;
                                const series = option.series;
                                const b = obj.selected, d = [];
                                for (let key in b) {
                                    if (b[key]) {
                                        for (let i = 0; i < series.length; i++) {
                                            const changeName = series[i].name;
                                            if (changeName == key) {
                                                d.push(i);
                                            }
                                        }
                                    }
                                }
                                var fun = function (params) {
                                    var value = 0;
                                    for (let i = 0; i < d.length; i++) {
                                        for (let j = 0; j < series.length; j++) {
                                            if (d[i] == j) {
                                                value += series[j].data[params.dataIndex]
                                            }
                                        }
                                    }
                                    return value
                                }
                                for (let i = 0; i < series.length; i++) {
                                    series[i].label.show = false;
                                }
                                for (let i = series.length - 1; i >= 0; i--) {
                                    var name = series[i].name;
                                    if (obj["selected"][name]) {
                                        series[i].label.formatter = fun
                                        series[i].label.show = true
                                        break;
                                    }
                                }
                                e.setOption(e.getOption);
                            })
                        } else {
                            this.$message.error('数据加载失败')
                        }
                    })
                },
                getSeriesData() {
                    const groupArray = this.groupBy(this.statisticsInfo, function (item) {
                        return [item.categoryName];
                    });
                    for (let categoryArray of groupArray) {
                        const data = []
                        for (let categoryData of categoryArray) {
                            data.push(categoryData.total)
                        }
                        this.seriesData.push({
                            name: categoryArray[0].categoryName,
                            type: 'bar',
                            stack: '总数',
                            data: data
                        })
                    }
                    // 设置总数显示
                    var this_ = this;
                    this_.seriesData[this_.seriesData.length-1].label = {
                        show: true,
                        position: 'top',
                        color: 'black',
                        formatter: function (params){
                            var value = 0;
                            for (let i = 0; i < this_.seriesData.length; i++) {
                                value += this_.seriesData[i].data[params.dataIndex]
                            }
                            return value;
                        }
                    }
                },
    
                /**
                 * 按条件分组
                 * 1. 函数groupBy有两个形参,一为对象数组,二为匿名函数(该函数功能:返回对象的某个指定属性的属性值并存放在数组中);
                 * 2. groupBy函数内,先创建一个空对象;
                 * 3. 然后forEach遍历对象数组,遍历时要执行的函数中只有一个形参o(数组中的每个元素);
                 * 4. 由于下面函数调用是想用name来分组,因此let group = JSON.stringify( f(o) ),相当于先获取到对象数组list中的name属性对应的属性值并放入数组中:["John"],然后再将属性值转换为json字符串:'["John"]';
                 * 5. groups[group] = groups[group] || [],在js中对象也是关联数组,因此这里相当于做了两件事,一是把group作为groups的key,二是将对应的value初始化,第一次执行为空数组,循环执行时找到相同的name时保持不变;
                 * 6. groups[group].push( o ),这句相当于把list中每个对象压入数组中作为value;
                 * 7. 最后,Object.keys(groups)是取出groups对象中的所有key,然后遍历一个个key组成的新数组,返回分好了组的二维数组
                 */
                groupBy(array, f) {
                    const groups = {};
                    array.forEach(function (o) {
                        const group = JSON.stringify(f(o));
                        groups[group] = groups[group] || [];
                        groups[group].push(o);
                    });
                    return Object.keys(groups).map(function (group) {
                        return groups[group];
                    });
                }
            }
        }
    </script>
    <style>
        .row {
            margin-right: -15px;
            margin-left: -15px;
        }
    
        .className {
            width: 100%;
            height: 540px
        }
    
        .splitBar {
            height: 60px;
        }
    </style>
    

  19. element Cascader 级联选择器 获取label
    <el-form-item>
    	<el-cascader :options="departmentCascader" @change="handleDepartmentChange" 
                     v-model="selectedOptions"
    				 class="dialog-search-item dialog-keywords" ref="mycascader"
    				 :show-all-levels="false" expand-trigger="hover" clearable change-on-select
    				 :size="searchSize" placeholder="根据市场筛选"></el-cascader>
    </el-form-item>
    
    handleDepartmentChange(val) {
    	if (val.length > 0) {
    		const cascaderObj = this.getCascaderObj(val, this.departmentCascader);
    		this.listQuery.scName = cascaderObj.label;
    	} else {
    		this.listQuery.scName = undefined;
    	}
    },
    getCascaderObj(val, opt) {
    	const selectList = val.map(function (value, index, array) {
    		for (var itm of opt) {
    			if (itm.value == value) { opt = itm.children; return itm; }
    		}
    		return null;
    	});
    	return selectList.find((obj)=>{
    		return obj.value === val[val.length - 1];
    	});
    },
    

  20. 浏览器根据地址下载文件,而不是直接打开文件,.doc/.mp4...等格式
    运用插件file-saver
    安装  cnpm install file-saver --save
    使用  
    var FileSaver = require('file-saver');
    FileSaver.saveAs(url, filename);
  21. 行内块高度一致
    <div class="container">
        <div class="item bg1">哈哈哈</div>
        <div class="item bg2">方法发发士大夫</div>
        <div class="item bg3">fasdfffffffffffffffffffffffffffas</div>
    </div>
    .container{
        width: 330px;
        display: flex;
        justify-content: space-between;
        align-items: stretch;
    }
     .item{
       width: 50px;
       height: auto;
       word-wrap:break-word;
     }
    .bg1{
      background: red;
    }
    .bg2{
      background: green;
    }
    .bg3{
      background: blue;
    }
    
    preview
  22. moment的中文显示

    我在使用moment的时候,想要让时间戳转换的格式变成XXXX年XX月XX日 XX:XX:XX 星期X 这个格式

    但是这个默认转换是英文 所以我们要做的操作是引入一个中文的文档:

  23. vue子组件触发父组件事件,并传值
    // 子组件
    <template>
        <button @click="emitEvent">点击我</button>
    </template>
    <script>
        export default {
            data() {
                return {
                    msg: "我是子组件中的数据"
                }
            },
            methods: {
                emitEvent(){
    //通过按钮的点击事件触发方法,然后用$emit触发一个my-event的自定义方法,传递this.msg数据。
                    this.$emit('my-event', this.msg)
                }
            }
        }
    </script>
    // 父组件
    <template>
        <div id="app">
            <child-a @my-event="getMyEvent"></child-a>
            <!--父组件中通过监测my-event事件执行一个方法,然后取到子组件中传递过来的值-->
        </div>
    </template>
    <script>
        import ChildA from './components/child.vue'
        export default {
            components: {
                ChildA
            },
            methods: {
                getMyEvent(msg){
                    console.log('接收的数据--------->'+msg)
                    //接收的数据--------->我是子组件中的数据
                }
            }
        }
    </script>
  24. 前端获取后台返回文件流,如果失败获取返回错误信息
    doReportPrint() {
                this.recordMedia.printDate = moment().format('YYYY年MM月DD日');
                this.submitLoading = true;
                var _this = this;
                doReportPrint(this.recordMedia).then(res => {
                    var content = res;
                    const fileReader = new FileReader();
                    fileReader.onload = function() {
                        try {
                            // this.result  = 字符串类型的 response
                            const fileResult = JSON.parse(fileReader.result);
                            //  如果接口返回的数据,非二进制的话。可以根据response做出响应的判断。
                            if (fileResult.status == 500) {
                                //  ps:JSON.parse()是Javascript中一个常用的 JSON 转换方法,JSON.parse()可以把JSON规则的字符串转换为JSONObject 反之就会报错。
                                //  如果接口内容为二进制数据。那么JSON.parse解析失败, 抛出异常来到catch进行执行下载操作
                                _this.$message.error('打印报告单异常');
                                _this.submitLoading = false;
                            }
                        } catch (err) {
                            const blob = new Blob([content],
                                { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8' });
                            const fileName = "现场勘验报告单" + moment(_this.recordMedia.createTime, 'YYYY-MM-DD HH:mm:ss').format('YYYYMMDD') + "-" + _this.recordMedia.centerCode + ".docx";
                            if ("download" in document.createElement("a")) {
                                // 非IE下载
                                const elink = document.createElement("a");
                                elink.download = fileName;
                                elink.style.display = "none";
                                elink.href = URL.createObjectURL(blob);
                                document.body.appendChild(elink);
                                elink.click();
                                URL.revokeObjectURL(elink.href); // 释放URL 对象
                                document.body.removeChild(elink);
                            } else {
                                // IE10+下载
                                navigator.msSaveBlob(blob, fileName);
                            }
                            _this.closeReportDialog();
                            _this.reloadList();
                            _this.submitLoading = false;
                        }
                    }
                    fileReader.readAsText(content);
                }).catch(e => {
                    this.message.error('打印报告单调用后台接口失败');
                });
            }
  25. Vue定义全局变量、全局方法,在.vue文件和.js文件里使用
    在.vue后缀名的文件,和.js后缀名的文件里,使用全局变量的语法是不一样的。.vue模板文件可以直接访问挂载在Vue实例上的全局对象,而普通的.js文件访问不到。

    定义全局变量

    在任意路径下创建一个.vue文件。我这里创建在src/config路径下,取名为Global.vue

    Global.vue

    <script>
    
      /**
       * 统一认证服务器地址
       */
      // const ssoServer = "https://iamtest.by.gov.cn:8083/idp"; // 测试环境
      const ssoServer = "https://iam.by.gov.cn/idp"; // 生产环境
    
      /**
       * 统一认证登出地址
       */
      // const ssoServerLogout = "https://iamtest.by.gov.cn:8083/apphub/logout"; // 测试环境
    
      const ssoServerLogout = "https://iam.by.gov.cn/apphub/logout"; // 生产环境
    
      export default
      {
        ssoServer,
        ssoServerLogout
      }
    
    </script>

    我这里定义的是常量。变量只是把const换成let,别的都一样。

    export default后面必须把所有全局变量名又写一遍,属于boilerplate代码,没办法。

    main.js是Vue项目的入口文件,在main.js里面把全局变量挂载到Vue实例上。

    main.js

    import global_ from './config/Global' // 这个路径是相对于main.js的相对路径
    
    Vue.prototype.GLOBAL = global_

    这样挂载完了以后,我们有两个办法去访问。

    通过Vue.prototype对象访问

    import Vue from 'vue'
    
    let a = Vue.prototype.GLOBAL.ssoServer

    这种写法在.vue文件和.js文件中都可以使用。

    通过this关键字访问

    let a = this.GLOBAL.ssoServer

    这种写法只能在.vue文件中使用。.vue模板文件中,this关键字可以访问到Vue.prototype上挂载的所有对象,所以写this就相当于写Vue.prototype。

    定义全局方法

    在任意.js文件里使用export function语法,即可让这个方法变成全局方法。

    common.js

    export function 个人号码加密 (号码) {
      let length = 号码.length
      if (length < 8) return 号码
      let 开始加密位 = length / 2 - length / 5
      let 结束加密位 = 开始加密位 + length / 3
      let 加密位数 = 结束加密位 - 开始加密位 + 1
      let 加密结果 = 号码.substring(0, 开始加密位)
      for (let i = 0; i < 加密位数; i++) {
        加密结果 += '*'
      }
      加密结果 += 号码.substring(结束加密位, length)
      return 加密结果
    }

    这样定义完了,在别的.js和.vue文件里面都可以调用到。调用语法是一样的。

    import * as common from '@/utils/common' 
    // @/utils为路径, common为js文件名
    
    let 身份证号码 = "44132319960617502X"
    let 身份证号码加密 = common.个人号码加密(身份证号码)

    全局方法不需要挂载在Vue实例上,直接import JS文件就可以访问。

  26. vue 子组件和父组件加载顺序
    执行顺序如下:
        父组件 created
        子组件 created
        子组件 mounted
        父组件 mounted
    如果有多个子组件:
        父组件created钩子结束后,依次执行子组件的created钩子
        多个子组件的created执行顺序为父组件内子组件DOM顺序
        多个子组件的mounted顺序无法保证,跟子组件本身复杂程度有关
        父组件一定在所有子组件结束mounted钩子之后,才会进入mounted钩子
    问题解决方案:
        1.用watch监视props属性,将newdata赋值进data中
        2.在一个工程里,子组件总最好不要写过多逻辑和对传入数据的处理

  27.  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值