Code Monkey home page Code Monkey logo

ktools's Introduction

Ktools

GitHub last commit GitHub stars GitHub issues Badge

  • 后续 blog marks project 文件夹中内容 将存放于 Knotes 项目中,本项目中文章将不再进行更新

记录工作、生活中使用到的各种工具,如JS、软件、文章等等。。。

主要记录 工具类 JS + Demo 展示 + CSS

目录

JS

  • 001.Date
  • 002.Excel
  • 003.Utils
  • 004.Num
  • 005.Canvas
  • 006.Animation
  • 007.window
  • 008.Array
  • 009.markdown
  • 010.git

Demo

  • camera-cut.html
  • WebSocket.html

CSS

  • csshake.css

Shell

  • git-history.sh

求赞😎

欢迎 Star 欢迎 Fork

欢迎关注:

欢迎关注 我的: GitHub juejin jianshu

ktools's People

Contributors

xrkffgg avatar zoo-js-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ktools's Issues

003.Vue+Element前端导入导出Excel

1 前言

1.1 业务场景

由前台导入Excel表格,获取批量数据。

根据一个数组导出Excel表格。

2 实现原理

2.1 引入工具库

file-saver、xlsx、script-loader

npm install -S file-saver xlsx

npm install -D script-loader

2.2 导入Excel

2.2.1 Element 上传控件

<el-upload
    class="upload-demo"
    action=""
    :on-change="handleChange"
    :on-exceed="handleExceed"
    :on-remove="handleRemove"
    :file-list="fileListUpload"
    :limit="limitUpload"
    accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"
    :auto-upload="false">
    <el-button size="small" type="primary">点击上传</el-button>
    <div slot="tip" class="el-upload__tip">只 能 上 传 xlsx / xls 文 件</div>
</el-upload>

limitUpload = 1限制只能上传1个文件

accept为默认打开的可上传的文件格式

handleChange(file, fileList){
    this.fileTemp = file.raw
},

handleRemove(file,fileList){
    this.fileTemp = null
},

fileTemp这里定义了一下变量,指向最新上传的附件,起始定义为null。

这里发现控件file.raw是我们要用的File类型。

2.2.2 导入判断

if(this.fileTemp){
    if((this.fileTemp.type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') || (this.fileTemp.type == 'application/vnd.ms-excel')){
        this.importfxx(this.fileTemp)
    } else {
        this.$message({
            type:'warning',
            message:'附件格式错误,请删除后重新上传!'
        })
    }
} else {
    this.$message({
        type:'warning',
        message:'请上传附件!'
    })
}

2.2.3 导入函数

importfxx(obj) {
    let _this = this;
    // 通过DOM取文件数据
    this.file = obj
    var rABS = false; //是否将文件读取为二进制字符串
    var f = this.file;
    var reader = new FileReader();
    //if (!FileReader.prototype.readAsBinaryString) {
    FileReader.prototype.readAsBinaryString = function(f) {
        var binary = "";
        var rABS = false; //是否将文件读取为二进制字符串
        var pt = this;
        var wb; //读取完成的数据
        var outdata;
        var reader = new FileReader();
        reader.onload = function(e) {
        var bytes = new Uint8Array(reader.result);
        var length = bytes.byteLength;
        for(var i = 0; i < length; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        var XLSX = require('xlsx');
        if(rABS) {
            wb = XLSX.read(btoa(fixdata(binary)), { //手动转化
                type: 'base64'
            });
        } else {
            wb = XLSX.read(binary, {
                type: 'binary'
            });
        }
        outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);//outdata就是你想要的东西
            this.da = [...outdata]
            let arr = []
            this.da.map(v => {
                let obj = {}
                obj.code = v['设备ID']
                obj.type = v['设备型号']
                arr.push(obj)
            })
            return arr
        }
        reader.readAsArrayBuffer(f);
    }
    
    if(rABS) {
        reader.readAsArrayBuffer(f);
    } else {
        reader.readAsBinaryString(f);
    }
},

arr就是我们要的结果,是一个数组。每一个值是个对象,包含了code type两个属性。

excel中格式为横向 设备ID 和 设备型号。

2.3 导出Excel

2.3.1 引入JS文件

可参考下载地址:- github

将其中的2个JS文件放入到自己的工程中。

2.3.2 修改JS文件中地址


打开Export2Excel.js,会出现如上图所示。由于本人将Blob.jsExport2Excel.js放到了同一级,这里引入是这样的。

这几个文件不支持import引入,所以需要script-loader来将他们挂载到全局环境下。

2.3.3 导出函数

getExcel(res) {
    require.ensure([], () => {
        const { export_json_to_excel } = require('../../introduce/Export2Excel.js')
        const tHeader = ['姓名', '年龄']
        const filterVal = ['name', 'age']
        const list = res
        const data = this.formatJson(filterVal, list)
        export_json_to_excel(tHeader, data, '导出列表名称')
    })
},

formatJson(filterVal, jsonData) {
    return jsonData.map(v => filterVal.map(j => v[j]))
},

这里的引用请根据自己的层级关系和文件夹命名require('../../introduce/Export2Excel.js')

res为传入的数组,格式如:res =[{name:'小白',age:'18'},{name:'小黑',age:'16'}]

tHeader为导出Excel表头名称,导出列表名称即为导出Excel名称

下载的Excel位置根据浏览器设置的下载位置而定

3 后记

感谢支持。若不足之处,欢迎大家指出,共勉。

如果觉得不错,记得 点赞,谢谢大家 😂

欢迎关注 我的: 【Github】【掘金】【简书】【CSDN】【OSCHINA】【SF】

3.1 参考资料

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

出处为:https://github.com/xrkffgg/Tools

004.Vue监听键盘鼠标事件

1 前言

1.1 业务场景

vue页面监听键盘鼠标等事件。

官方给的例子是在input标签中的,我们想要的效果是不使用固定标签。

2 实现原理

2.1 增加监听

mounted () {
    window.addEventListener('keyup',this.handleKeyup)
    window.addEventListener('scroll',this.handleScroll)
},

这里定义了,键盘按出的时候的事件 和 鼠标滑轮滚动的事件。

这里可以自行查询下有哪些事件,

关键字:

HTML DOM Event

可参考:W3school 菜鸟教程

这里根据addEventListener(event,function)的用法。

event,必参,字符串,注意要把DOM事件的名称去掉on

2.2 方法调用

methods:{
    // 键盘事件
    handleKeyup(event){
        const e = event || window.event || arguments.callee.caller.arguments[0]
        if(!e) return
        const {key,keyCode} = e
        console.log(keyCode)
        console.log(key)
    },
    //  滑轮事件
    handleScroll(){
        var e = document.body.scrollTop||document.documentElement.scrollTop
        if(!e) return
        console.log(e)
    },
}

2.3 移除监控

destroyed () {
    window.removeEventListener('keyup',this.handleKeyup)
    window.removeEventListener('scroll',this.handleScroll)
},

3 后记

感谢支持。若不足之处,欢迎大家指出,共勉。

如果觉得不错,记得 点赞 ,谢谢大家 😂

欢迎关注 我的: 【Github】【掘金】【简书】【CSDN】【OSCHINA】【SF】

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

出处为:https://github.com/xrkffgg/Tools

008.前端引用字体@font-face的若干优化方法

1 前 言

1.1 场 景

我们在页面展示时,为了更好的效果,一般使用了自定义的字体 @fant-face

之前在开发的时候使用了一些自定义字体,这里总结下自己寻找的的一些处理办法。

本文只列出了引入本地字体,网络的字体由于实践不多,这里介绍就少一些。

😂 献丑了 😂

2 正 文

2.1 本地字体

2.1.1 版 权

首先一定要注意这个问题

2.1.2 字体定义

一般情况定义如下:

@font-face {
    font-family:"Regular";
    src:url('../font/Regular.otf');
}

在某个我们要使用的该字体的classA上定义:

.classA {
    font-family:"Regular";
}

2.1.3 字体压缩

一般的中文字体都要8-10M,相对于整个工程来说太巨大,这里提供自己实践过的2种压缩方法。

两种都需要列举出你使用过的字。

1 font-spider

官网:http://font-spider.org/

支持 gulp 构建插件

我在使用时,刚开始一直没压缩成功

之后发现是由于自己下载的字体版本有点低

这里列出一个找到的字体下载网址,觉得不错:https://www.fontke.com/font/

2 Fontmin

官网:http://ecomfe.github.io/fontmin/

这个比较方便的是有一个客户端可以操作

2.1.4 字体加载

虽然有压缩的功能,但必须提供出所有使用过的字体,而且我想的是我的项目中就默认一个好看的字体。

这样就遇到一个问题,在第一次加载的时候,浏览器就会用一些时间来加载这个字体文件。

而在加载完成之前,页面就会空白,也就是FOIT(Flash of Invisible Text)

1 FOUT

FOUT(Flash of Unstyled Text)大意就是在字体加载完成前,浏览器会显示font-family的顺序字体

当加载完成后,才会替换成定义的字体,设置如下:

@font-face {
    ...
    font-display: swap;
    ...
}

这样的效果,就是会在页面中看到的一个字体替换的效果😂

2 FontFaceObserver

然后我想的是,有没有什么办法可以判断字体加载完成了呢?

安装:

npm i fontfaceobserver

页面中:

// css 中 @font-face 已定义好
import FontFaceObserver from 'fontfaceobserver'

loadfont(){
    console.time("字体加载用时")
    var ooo = new FontFaceObserver('Regular')
    ooo.load().then(() =>{
        document.getElementById('index').style.fontFamily = 'Regular'
        console.timeEnd("字体加载用时")
    })
},

同时可以加上一个loading的动画,这样效果就比较好了😎

2.2 网络字体

2.2.1 引入

webfont:https://www.webfont.com/

找到的一个方式,没有实际用过,不知道效果咋样,有兴趣的可以试试。

3 后 记

感谢支持。若不足之处,欢迎大家指出,共勉。

如果觉得不错,记得 点赞,谢谢大家 😂

欢迎关注 我的: 【Github】 【掘 金】 【简 书】

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

出处为:https://github.com/xrkffgg/Tools

001.JS计算两个时间间隔

1 前言

1.1 业务场景

JavaScript计算两个时间相隔了 多少年多少月多少日。时分秒这里不作考虑。

2 实现原理

2.1 获取当前时间

若需要和当前时间比较,这里提供当前时间的获取格式化方法。我这里是根据传入类型输出日期或者日期+时间,可以明显看出typeday时,输出日期。

getNowDate(type){
    let now = new Date()
    let year = now.getFullYear()
    let month = now.getMonth() + 1
    let day = now.getDate()
    let hh = now.getHours()
    let mm = now.getMinutes()
    let ss = now.getSeconds()

    month = month < 10 ? '0'+ month : month
    day = day < 10 ? '0'+ day : day

    if(type == 'day'){
      return year +'-'+ month +'-'+ day
    } else {
      return year +'-'+ month +'-'+ day + ' '+ hh + ':' + mm + ':' + ss
    }
},

2.2比较时间

传入两个参数,格式如:2008-08-08

getDiffYmdBetweenDate(sDate1,sDate2){
    var fixDate = function(sDate){
        var aD = sDate.split('-');
        for(var i = 0; i < aD.length; i++){
            aD[i] = fixZero(parseInt(aD[i]));
        }
        return aD.join('-');
    };
      
    var fixZero = function(n){
        return n < 10 ? '0'+n : n;
    };
      
    var fixInt = function(a){
        for(var i = 0; i < a.length; i++){
            a[i] = parseInt(a[i]);
        }
        return a;
    };
      
    var getMonthDays = function(y,m){
        var aMonthDays = [0,31,28,31,30,31,30,31,31,30,31,30,31];
        if((y%400 == 0) || (y%4==0 && y%100!=0)){
            aMonthDays[2] = 29;
        }
        return aMonthDays[m];
    };
      
    var checkDate = function(sDate){
    };
    var y = 0;
    var m = 0;
    var d = 0;
    var sTmp;
    var aTmp;
    sDate1 = fixDate(sDate1);
    sDate2 = fixDate(sDate2);
    if(sDate1 > sDate2){
        return 'past'
    }
    var aDate1 = sDate1.split('-');
    aDate1 = fixInt(aDate1);
    var aDate2 = sDate2.split('-');
    aDate2 = fixInt(aDate2);
    //计算相差的年份
    /*aTmp = [aDate1[0]+1,fixZero(aDate1[1]),fixZero(aDate1[2])];
    while(aTmp.join('-') <= sDate2){
        y++;
        aTmp[0]++;
    }*/
    y = aDate2[0] - aDate1[0];
    if( sDate2.replace(aDate2[0],'') < sDate1.replace(aDate1[0],'')){
        y = y - 1;
    }
    //计算月份
    aTmp = [aDate1[0]+y,aDate1[1],fixZero(aDate1[2])];
    while(true){
        if(aTmp[1] == 12){
            aTmp[0]++;
            aTmp[1] = 1;
        }else{
            aTmp[1]++;
        }
        if(([aTmp[0],fixZero(aTmp[1]),aTmp[2]]).join('-') <= sDate2){
            m++;
        } else {
            break;
        }
    }
    //计算天数
    aTmp = [aDate1[0]+y,aDate1[1]+m,aDate1[2]];
    if(aTmp[1] > 12){
        aTmp[0]++;
        aTmp[1] -= 12;
    }
    while(true){
        if(aTmp[2] == getMonthDays(aTmp[0],aTmp[1])){
            aTmp[1]++;
            aTmp[2] = 1;
        } else {
            aTmp[2]++;
        }
        sTmp = ([aTmp[0],fixZero(aTmp[1]),fixZero(aTmp[2])]).join('-');
        if(sTmp <= sDate2){
            d++;
        } else {
            break;
        }
    }
    return {y:y,m:m,d:d}
},

返回的结果是一个对象,包含了y m d三个属性,可根据业务进行取用展示。

比较时间的时候,若sDate1为小的时间,这里直接返回past

2.3 页面展示

这里根据业务不同可以作不同的展示。这里列出自己的Vue展示处理展示。

其中this.dataForm.hasdata为页面的v-model。这样的处理的效果是观看直观。

let now = this.getNowDate('day')
let diffDate = this.getDiffYmdBetweenDate(now,this.data)
let hasdata = ''

if(diffDate == 'past'){
    this.dataForm.hasdata = '已过期'
} else {
    if(diffDate.y > 0){
        hasdata += diffDate.y + '年' + diffDate.m + '月'
    } else if (diffDate.y == 0) {
        if(diffDate.m > 0){
            hasdata += diffDate.m + '月'
        }
    }
    this.dataForm.hasdata = hasdata + diffDate.d + '日'
}

2.4 页面效果



3 后记

感谢支持。若不足之处,欢迎大家指出,共勉。

如果觉得不错,记得 点赞 ,谢谢大家 😂

欢迎关注 我的: 【Github】【掘金】【简书】【CSDN】【OSCHINA】【SF】

3.1 参考资料

3.2 时间处理js库

这里列举几个js库备查找使用,排序无意义。

  • moment
  • day
  • date-fns
  • miment

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

出处为:https://github.com/xrkffgg/Tools

006.vue全家桶+Echarts+百度地图,搭建数据可视化系统

本文章篇幅略长,内容有点多 大佬可根据目录选择性查阅 新人可一步步来阅读

1 前言

1.1 业务场景

突然接到产品说要做一个数据监控的系统。有线图、柱状图、地图,类似于数据可视化的方式。

本人之前从未接触过Echarts,然后需要2周拿出成果,有点慌😂😂

1.2 业务分析

拿到需求看了一下

支持用户名、密码登录,默认显示一个维度数据,然后点击可钻取进入第二维度数据,再点击进入第三维度数据展示。

大致估摸着。。。

  1. 系统搭建vue-cli
  2. vuex记录登录信息
  3. vue-router路由跳转
  4. 3个维度的页面,提取出共用的组件
  5. 各个组件开发
  6. 调节样式,增加UI
  7. 加入后台接口数据
  8. 优化显示
  9. 测试
  10. 上线

当然这不是要2周内,全做完。应该是完成步骤6。

相对于公司就我一个前端,没接触过Echarts,有问题都没人讨论的情况下。。。

心里还是忍不住想吐槽一下😒😒😒

1.3 效果展示

这里列出了第一维度页面的样式。文字请无视,哈哈。

2 系统安装

吐槽归吐槽,活还是要干的。😎

因为本人最熟悉的还是vue,所以还是选择了用vue全家桶来做。这部分可参考 vue build

2.1 安装node环境

  • 下载安装node环境,直接去官网下载即可 node.js

安装完后可在命令行运行node -v npm -v 查看是否安装成功以及版本

2.2 安装Vue项目

2.2.1 安装vue

官方文档:vuejs

这里我们使用npm的方式

  • npm i vue

2.2.2 安装Vue CLI

官方文档:vue CLI

  • npm i -g @vue/cli

安装之后,你就可以在命令行中访问 vue 命令。你可以用这个命令来查看其版本。vue -V

2.2.3 创建项目

这里安装的时候,注意将我们要使用的安装上。vuexvue-router,其他可根据需要添加。

  1. 方法一
  • vue create hello-world

这里参照官方网站,有很详细的介绍。参照:vue create

  1. 方法二

使用图形化界面

  • vue ui

界面含中文,很好操作。参照:vue ui

2.2.4 安装插件

  1. 方法一

最直接也是推荐的 npm i xxx

这里介绍一下 -S -D -g 的区别

  • npm i -S xxx 文件写入dependencies,用于工程中开发时使用到的插件,会发布到生产环境如UI,JS等。
  • npm i -D xxx 文件写入devDependencies,用于工程支持类插件,不会发布到生产环境,如gulp等压缩打包工具。
  • npm i -g xxx 全局安装,如vue、ncu等。安装目录为:C:\Users\用户\AppData\Roaming\npm
  1. 方法二

vue ui图像化界面中包含了若干插件,可点击安装,但不一定是最新版本。

同时会在hello中引入。其他和方法一没区别。

2.3 安装Echarts

这里我们为了方便,使用了npm全量引用,后期为了精简项目可单个引用。

  • npm i echarts -S

然后在main.js中添加

这里建议提前自定义echarts的样式,并引入到项目中。官方自定义地址:theme-builder

在页面中我们可以如下引用:
var myChart = this.$echarts.init(document.getElementById("myid"),'temp')

myid是我们要展示的echartsid

temp是我们的自定义的样式,同时官方提供了几个样式例子,可以node_modules\echarts\theme中找到。

2.4 安装element-ui

这里我们为了方便,使用了npm全量引用,后期为了精简项目可单个引用。

  • npm i element-ui -S

然后在main.js中添加

2.5 安装百度地图

一般vue使用百度地图有2种方式,

  • 一种是像官网那样去应用。如:BMap

  • 第二种是使用 vue-baidu-map

不管是哪一种都要去申请账号和密钥。申请地址为:百度地图密钥(ak)

这里我使用了第二种。vue-baidu-map文档

  • npm i vue-baidu-map -S

然后在main.js中添加

xxxxxxxx这里填写自己申请的密钥。

在页面中,参照文档,可使用标签<baidu-map/>来调用。

2.6 初始化样式

css样式初始化,简单来说就是为了各个浏览器能统一什么的。

这里我使用的是 normalize.css

下载下来后,在main.js中添加

基本上的准备工作都做好了,接下来就是具体的代码了。

3 项目搭建

3.1 router、vuex

我这里新建了一个router.jsstore.js,大致如下:

哦哈,这里路由定义是为了方便看哈,具体还是根据业务来定义。

这里的router.beforeEach 路由卫士用于是否登录校验。

然后我们在main.js中来引用。

更多请参考官方文档:Vue Router Vuex

3.2 Login页面

登录页面没啥,就是个form提交,由于路由中判断user.id。所以我们储存一下,然后跳转到Index页面就行。

这里只是一种方式,也可以使用CookieSession

3.3 Index页面

分析页面分成了2个大部分

  • 第一部分是 头部
  • 第二部门是 主体

我们将头部当做一个组件进行复用。

组件的复用可参考官方文档:https://cn.vuejs.org/v2/guide/components.html

3.4 header页面

头部比较简单,除了一些显示外,还有一个显示当前时间。

这里我们使用了setInterval,每隔1秒去获取一下当前时间赋值给你定义的v-model就行。

同时在离开页面时,我们清理掉定时器。

这里需要我们对Vue生命周期有一定的了解。

获取当前时间的方法可参考:data-module.js

3.5 主体页面

这里分析一下页面,主要分成了3块。

  1. 左边,包含了2个折线图。
  2. 中间,包含了数字和地图。
  3. 右边,包含了柱状图和表格。

接下来主要介绍一下,自己这2周摸索出来的一些Echarts配置,适合新手,大佬轻喷。

这里需要经常翻阅 Echarts配置项API

3.5.1 Echarts基本

这里列出基本的渲染写法,具体的图形和数据只要修改option就可以了。

<template>
    <div id="myecharts" class="myecharts">
</template>

<script>
    export default {
        mounted(){
            this.drawECharts()
        },
        
        methods:{
            drawECharts(){
                // temp 是我们的自定义样式,上面安装Echarts时有介绍
                var myChart = this.$echarts.init(document.getElementById("myecharts"),'temp')
                var option = {}
                option = {
                    // 吧啦吧啦 一堆配置
                }
                // 执行渲染图形和数据的操作
                if (option && typeof option === "object") {
                    myChart.setOption(option, true)
                }
            }
        }
    }
</script>

<style>
    //  一定要设置大小,不然不出来,这玩意和canvas一样
    .myecharts{
        width : 500px;
        height : 300px;
    }
</style>

3.5.2 线形图

多多实践,就会发现每个配置和其参数的作用了。

option = {
    // 提示框(就是鼠标放上去后出现的框)
    tooltip : {
        trigger: 'axis',
        axisPointer: {
            type: 'cross',
            label: {
                backgroundColor: '#6a7985'
            }
        }
    },
    
    //  右上角的组件,用于说明,也可进行点击筛选
    legend: {
        align : 'right',
        x : 'right',
        top : 25,
        selectedMode : 'single',    //  我这里设置的单选模式
        data:['好','坏']            //  显示的第一项和第二项,这里的颜色是根据自定义主题的颜色顺序来定的
    },
    
    //  x、y轴显示一些设置,比如刻度颜色显示什么的,可在自定义主题设置一部分
    xAxis: {
        type: 'category',
        boundaryGap: false,
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },
    yAxis: {
        type: 'value'
    },
    // 具体配置项,根据具体项目查看官网配置项说明
    series: [
        {
            name : '好',
            data: [150, 132, 201, 534, 290, 530, 820],
            type: 'line',
            smooth: true,   //  是否平滑曲线
            areaStyle: {},
        },
        { 
            name : '坏',
            data: [82, 93, 90, 93, 129, 333, 432],
            type: 'line',
            smooth: true,
            areaStyle: {},
        }
    ]
}

// 查看Echarts的API,我们需要显示默认的一些数据,配置如下
// 默认显示坏的数据
myChart.dispatchAction({
    type: 'legendSelect',
    name: '坏',
})
//  默认显示第7个数据
myChart.dispatchAction({
    type: 'showTip',
    seriesIndex: 1,
    dataIndex: 6,
})

预览:

3.5.3 柱状图

这里我们直接用双柱状图来演示。

因为名字和数字需要提示和点击的功能,所以没有使用echartsy轴。

不然formatter又要写一堆,虽然用了自定义的,但最开始是用的formatter

可以实现相同展示,但无法操作,如鼠标提示和鼠标点击。

<div class="left">
    <div v-for="it in its1" :key="it.id">
        <el-tooltip class="item"  effect="light" placement="bottom-start">
            <div slot="content">名称:{{it.name}}<br/>个数:{{it.num}}</div>
            <div class="name" @click="go"> {{ it.name.substring(0,4)+'...' }}</div>
        </el-tooltip>
        <div class="num">{{ it.num }}</div>
    </div>
</div>

<div class="right">
    <div v-for="it in its2" :key="it.id">
        <el-tooltip class="item"  effect="light" placement="bottom-start">
            <div slot="content">名称:{{it.name}}<br/>个数:{{it.num}}</div>
            <div class="name" @click="go"> {{ it.name.substring(0,4)+'...' }}</div>
        </el-tooltip>
        <div class="num">{{ it.num }}</div>
    </div>
</div>

<div id="myecharts" class="myecharts">

css这里就不贴了,效果就是这2行文字刚好贴在2行柱状图前面。

接下来是echarts配置。

option = {
    // 鼠标提示框
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'shadow'
        }
    },
    
    // 右边显示
    legend: {
        selectedMode:false,
        data: ['好', '坏'],
        top:5,
        right:8,
    },
    
    // 两个图坐标的位置
    grid: [
        {left: '16%', top:'10%', width: '22%', height: '86%'},
        {left: '65%', top:'10%', width: '22%', height: '86%'}
    ],
    
    // 两个图x轴的设置,这里的gridIndex就是个序号,用于区分
    xAxis: [
        {gridIndex : 0, show : false},
        {gridIndex : 1, show : false},
    ],
    
    // 两个图y轴的设置,注释的部分是用echarts本身的y轴来显示名称和数量的
    yAxis: [
        {
            gridIndex: 0,
            type: 'category',
            show : false,
            data : ['广东/12','杭州/13','北京北京/14','天津/16'],
            // axisLabel: {
            //   formatter : function(value){
            //     let arr = value.split('/')
            //     return '{a|'+arr[0]+'}\n{b|'+ arr[1]+'}';
            //   },
            //   rich: {
            //     a: {
            //       color : '#ffffff',
            //       lineHeight : 19,
            //       fontSize : 14,
            //       align: 'right',
            //     },
            //     b:{
            //       fontSize : 18,
            //       lineHeight : 19,
            //       fontWeight : 'bold',
            //       align: 'right',
            //       fontFamily : 'Digital',
            //     }
            //   }
            // }
        },
        {
            gridIndex: 1,
            show : false,
            type: 'category',
            data : ['海南/12','三亚/13','哈尔滨/14','西双版纳/16'],
            // axisLabel: {
            //   formatter : function(value){
            //     let arr = value.split('/')
            //     return '{a|'+arr[0]+'}\n{b|'+ arr[1]+'}';
            //   },
            //   rich: {
            //     a: {
            //       color : '#ffffff',
            //       lineHeight : 19,
            //       fontSize : 14,
            //       align: 'right',
            //     },
            //     b:{
            //       fontSize : 18,
            //       lineHeight : 19,
            //       fontWeight : 'bold',
            //       align: 'right',
            //       fontFamily : 'Digital',
            //     }
            //   }
            // }
        },
    ],
    
    //  渲染图形和数据,bar是柱状图
    //  barWidth 柱状的宽度
    //  两类两套,所以有4组数据,使用xAxisIndex、yAxisIndex来区分。
    series: [
        {
            name: '好',
            type: 'bar',
            barWidth  : 5,
            barMinHeight : 5,
            barGap : '100%',
            xAxisIndex: 0,
            yAxisIndex: 0,
            data: [0, 3489, 9022234, 922228],
            label: {
                normal: {
                    position: 'right',
                    show: true
                }
            },
        },
        
        {
            name: '坏',
            type: 'bar',
            barWidth  : 5,
            barMinHeight : 5,
            xAxisIndex: 0,
            yAxisIndex: 0,
            data: [0, 2438, 3300, 1594],
            label: {
                normal: {
                    position: 'right',
                    show: true
                }
             },
        },
        {
            name: '好',
            type: 'bar',
            barWidth  : 5,
            barMinHeight : 10,
            barGap : '100%',
            xAxisIndex: 1,
            yAxisIndex: 1,
            data: [8203, 3489, 9034, 222],
            label: {
                normal: {
                    position: 'right',
                    show: true
                }
            },
        },
        {
            name: '坏',
            type: 'bar',
            barWidth  : 5,
            barMinHeight : 5,
            xAxisIndex: 1,
            yAxisIndex: 1,
            data: [445, 2438, 3300, 555],
            label: {
                normal: {
                    position: 'right',
                    show: true
                }
            },
        },
    ]
}

预览:

3.5.4 表格

table我这里使用了element-ui加上修改 UI 默认css 和 滚动条的 css

这里列出一项,其他写法相似。

<el-table
    :data="tableData"
    height="252"
    style="min-width: 100%;">
    <el-table-column
        prop="date"
        min-width="12"
        header-align="center"
        label="时间">
        <template slot-scope="scope">
            <template v-if="scope.row.if == '1'">
                <img src="../../assets/img/new.png"/>
                <div style="color:#E63136;margin-top:-27px;margin-left:35px;">
                    {{scope.row.date}}
                </div>
            </template>
            <template v-else>
                <div style="margin-left:35px;">
                    {{ scope.row.date }}
                </div>
            </template>
        </template>
    </el-table-column>
</el-table>
  • UI 样式

UI css的修改,这里我使用了自定义字体哦,完全copy是不起作用的。

其他的设置项不做说明,F12打开,随便玩。

.el-table thead {
    color: #FFFFFF;
}

.el-table {
    color: #00A5F6;
    font-family: 'Regular';
    background-color: rgba(0, 0, 0, 0.03);
    th {
        padding: 2px 0;
        background-color: #003260; 
    }
    th.is-leaf {
        border-bottom: 0px solid #EBEEF5;
    }
    tr {
        background-color: rgba(0, 0, 0, 0.03);
    }
    td {
        border-bottom: 1px solid #2c3547;
        padding: 2px 0;
    }
    
    .el-table::before {
        height: 0px;
        z-index: 0;
        background-color: #2c3547;
    }
}
  • 滚动条的样式

随意改变看看效果就懂了,谷歌浏览器 😅

/* scrollbar */

::-webkit-scrollbar {
  width: 8px;
  height: 1px;
  background-color:transparent;
}
::-webkit-scrollbar-thumb {
  border-radius: 10px;
  background: #adabab;
}
::-webkit-scrollbar-track {
  border-radius: 10px;
  background:#394d63;
}

预览:

3.5.5 百度地图

vue-baidu-map 文档

<baidu-map 
    :center="map.center"        //  地图中心经纬 {lng: 114.023598, lat: 33.589299}
    :scroll-wheel-zoom="true"   //  地图是否滚轮缩放
    :zoom="map.zoom"            //  默认地图尺寸
    :mapStyle="mapStyle"        //  地图样式
    class="baidumap">           //  地图宽高
    <template v-for="(it,index) in ms">     //  标点
        <bm-marker 
            :key="it.id" 
            :position="it.position"         //  标点位置
            @click="markclick(it,index)"    //  标点点击事件
            @mouseover="markover(it,index)" //  鼠标移动到标点上的事件
            :icon="it.if? iocn:newincon"    //  标点的样式
            @mouseout="markout(it,index)">  //  鼠标从标点移走的事件
            <bm-info-window
                :show="it.show"             //  标点提示框的显示true/false
                :position="it.position">    //  提示框坐标
                <p v-text="it.mess"></p>    //  提示框内容
            </bm-info-window>
        </bm-marker>
    </template>
</baidu-map>

预览:

3.5.6 矢量地图

Echarts矢量地图的类型有

  • type:'scatter' 散点气泡图,可在地图中显示不用颜色程度的点
  • type:'effectScatter' 有涟漪特效动画的散点图
  • type:'map' 地理区域的数据可视化
  • type:'lines' 地图航线、路线的可视化

引入地图

require('echarts/map/js/china.js')
require('echarts/map/js/province/beijing.js')

这里我有问题,我要引入全国的省份,就要多写30多个require,有没有大佬能给出更好的办法?

找到一个全量引用的方法

const rjs = require.context('echarts/map/js/province')
rjs.keys().forEach(rjs)

可以替代

require('echarts/map/js/province/beijing.js')
require('echarts/map/js/province/shanxi.js')
require('echarts/map/js/province/neimenggu.js')
等等等。。。

地图配置:

option = {
    //  鼠标提示
    tooltip : {
        trigger: 'item',
        formatter : function(params){
            var val = params.data
            return '名称:'+val.name+',个数:'+val.value[2]+'<br/>'+'总数:'+val.tol+',个数:'+val.un
        },
    },
    
    //  不同颜色的点
    visualMap: [
        {
            min: 0,
            max: 1,
            show : false,
            inRange: {
                color: ['#01cae2', '#e63136',]
            },
            dimension : 3,
        },
    ],

    // 地图样式
    geo: {
        map: 'china',   // 地图样式,当为‘北京’时,会显示北京地图   
        roam : true,    
        label: {
            emphasis: {
                show: true
            }
        },
        zoom : 1.2,     //  初始大小
        scaleLimit : {
            min : 1.2,  //  最小缩放
            max : 6     //  最大缩放
        },
        regions : regions(data)     // 省份样式方法
    },

    series : [
        {
            name: '分布',
            type: 'scatter',
            coordinateSystem: 'geo',    //  地图配置
            data: convertData(data.sort(function (a, b) {   //  数据方法
                return b.value - a.value;
            })),
            encode: {
                value : 2
            },
            hoverAnimation: true,
            itemStyle: {
                normal: {
                    // color: '#FF3030',
                    shadowBlur: 1,
                }
            },
        }
    ]
};

当点击省份地图时,我们可以进入省份地图的矢量图

myChart.on('click',function(params){
    option.geo.map =  '北京'
    myChart.setOption(option, true);
})

预览:


4 后记

目前还没有接入后端数据,就是全前台的一个展示。很多都是全量引入,后续待成熟后,可慢慢精简。

总结一下:Vue入门 + Echarts入门 ,希望能对你有用!!!😜😜😜

感谢支持。若不足之处,欢迎大家指出,共勉。

如果觉得不错,记得 点赞,谢谢大家 😂

欢迎关注 我的: 【Github】【掘金】【简书】【CSDN】【OSCHINA】【SF】

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

出处为:https://github.com/xrkffgg/Tools

010.Vue项目引入CreateJS的方法(亲测)

1 前 言

1.1 CreateJS介绍

CreateJS是基于HTML5开发的一套模块化的库和工具。
基于这些库,可以非常快捷地开发出基于HTML5的游戏、动画和交互应用。

A suite of modular libraries and tools which work together or independently to enable rich interactive content on open web technologies via HTML5.

包含4类工具库

  1. EaselJS 提供了一套完整的,层次化的显示列表的互动方式 来更简单的处理HTML5画布。
  2. TweenJS 类库主要用来调整和动画HTML5和Javascript属性。提供了简单并且强大的tweening接口。
  3. SoundJS 提供了简单而强大的API来处理音频。通过插件来执行实际的音频实现,无需学习平台相关的知识,简单直接的处理声音。
  4. PreloadJS 是一个用来管理和协调相关资源加载的类库,它可以方便的帮助你预先加载相关资源,例如:图片、文件、音频、数据等等。

1.2 CreateJS版本

1.2.1 GitHub

地址:https://github.com/CreateJS

EaselJS 为例,js 文件存放在 lib 文件中

  • easeljs.js v0.8.2 带注释版本
  • easeljs.min.js v0.8.2 不带注释压缩版本,功能不受影响
  • easeljs-NEXT.js v1.0.0
  • easeljs-NEXT.min.js v1.0.0

1.2.2 英文

1.2.3 中文

2 正 文

由于 createjs 各个库中代码都使用了:

this.createjs = this.createjs || {}

因为这里的 this 并不是挂载在 window 对象上,所以无法直接从 import 中引用。

2.1 方法一

2.1.1 安装yuki-createjs

GitHub : https://github.com/yuki-torii/yuki-createjs

npm i -S yuki-createjs

注意这里下载的版本不是官网最新版本。

2.1.2 使用yuki-createjs

// include all
import 'yuki-createjs' 
// or 
require('yuki-createjs')
// include one
import 'yuki-createjs/lib/preloadjs-0.6.2.combined'
// or
require('yuki-createjs/lib/preloadjs-0.6.2.combined')

2.1.3 例 子

// helloworld.vue

<template>
...
    <canvas id="idd11" width="500" height="400"/>
...
</template>

<script>
    require('yuki-createjs/lib/easeljs-0.8.2.combined')
    export default {
        //  这里主要不能放在 created() 里
        mounted(){
            this.init()
        },
        methods: {
            init(){
                var canvas = document.getElementById('idd11')
                var stage = new createjs.Stage(canvas)
                var text = new createjs.Text("Hello World!", "36px Arial", "#777")
                text.textAlign = "center"
                text.x = 100
                text.y = 0
                stage.addChild(text)
                stage.update()
            },
        }
    }
</script>

我是直接在 Vue 新建的项目里,HelloWorld.vue 来进行修改, 效果图如下:

2.2 方法二

2.2.1 createjs-cmd

npm i -S createjs-cmd

GitHub:https://github.com/yedaodao/createjs-cmd

同方法一,下载的不是最新版本。

2.2.2 使 用

import createjs from 'createjs-cmd'

2.3 方法三

2.3.1 script-loader

npm i -S script-loader
npm i -S createjs

下载的各个版本都有,可以来引用 1.0.0 版本,但是包含4个库

npm i easeljs 下载的只包含旧版

2.3.2 使 用

import 'script-loader!createjs/builds/1.0.0/createjs.min.js';

2.4 方法四

2.4.1 @createjs/easeljs

npm i @createjs/easeljs

2.4.2 使 用

import * as createjs from '@createjs/easeljs'

2.0 BETA版(当前是这样的,由于文章时效性,以后不清楚 😂😂😂)

2.5 方法五

2.5.1 vue-easeljs

GitHub:https://github.com/dankuck/vue-easeljs

具体可参考GitHub,没有其他参考API,封装成了标签,感兴趣的可以尝试下

3 总结

列了一个表格将5种方法比较一下

序号 方法 版本 推荐
yuki-createjs 旧版 ✰✰★★★
createjs-cmd 旧版 ✰✰★★★
script-loader 新旧 ★★★★★
@createjs/easeljs Beta ✰✰★★★
vue-easeljs 旧版 ✰✰✰★★
  • 类似于 script-loader 还可以使用 imports-loader ,但试了几次没成功😂😂,原谅我太菜了
  • 2.0 Beta 版已支持 ES6,相信等正式版出的时候,这个问题就完全不用担心了。

4 后 记

感谢支持。若不足之处,欢迎大家指出,共勉。

如果觉得不错,记得 点赞,谢谢大家 😂

欢迎关注 我的:

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

出处为:https://github.com/xrkffgg/Tools

002.JS实现页面查看zip文件中的内容

1 前言

1.1 业务场景

附件zip上传到服务器后,在页面中可直接查看zip中的文件内容,如:readme.txt。

2 实现原理

2.1 引入工具库

jszip、jszip-utils

npm i jszip -S

npm i jszip-utils -S

2.2 查看txt中内容

// 查看
view(row){
    var JSZip = require("jszip")
    var JSZipUtils = require("jszip-utils")
    let that = this

    JSZipUtils.getBinaryContent(row.downloadPath, function(err, data) {
        if(err) {
            throw err; 
        }
        JSZip.loadAsync(data).then(function (files) {
            files.files['readme.txt'].async("string").then(function(con){
            that.content = con
            that.dialog = true
            })
        })
    })
},

在vue中引入,其中在JSZipUtils使用中this的指向进行了重定向。

row.downloadPath是附件的下载地址,con是txt中内容。

readme.txt是要查看的文件名+后缀。

这里使用了input定义的v-model="content"来展示。

3 后记

感谢支持。若不足之处,欢迎大家指出,共勉。

如果觉得不错,记得 点赞 ,谢谢大家 😂

欢迎关注 我的: 【Github】【掘金】【简书】【CSDN】【OSCHINA】【SF】

这两个库都是关于JS处理压缩文件的,功能很多,目前只学到了一小点,更多功能还需再研究。

3.1 参考资料

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

出处为:https://github.com/xrkffgg/Tools

005.Vue使用Canvas绘制图片、矩形、线条、文字,下载图片

1 前言

1.1 业务场景

图片储存在后台中,根据图片的地址,在vue页面中,查看图片,并根据坐标标注指定区域。

由于浏览器的机制,使用window.location.href下载图片时,并不会保存到本地,会在浏览器打开。

2 实现原理

2.1 绘制画布

<el-dialog
    title="查看图片"
    :visible.sync="dialogJPG"
    append-to-body>
    <canvas id="mycanvas" width="940" height="570"></canvas>
</el-dialog>

这里为了交互体验,使用了element-ui的弹窗方式。将canvas画布放到了弹窗中。

为了突出画布效果可以在css中设置一个边框。

#mycanvas {
    border: 1px solid rgb(199, 198, 198);
}

2.2 绘制图片

//  imageUrl为后台提供图片地址
doDraw(imageUrl){
    //  获取canvas
    var canvas = document.getElementById("mycanvas")
    //  由于弹窗,确保已获取到
    var a = setInterval(() =>{
        //  重复获取
        canvas = document.getElementById("mycanvas")
        if(!canvas){
          return false
        } else {
            clearInterval(a)
            //  可以理解为一个画笔,可画路径、矩形、文字、图像
            var context = canvas.getContext('2d')
            var img = new Image()
            img.src = imageUrl
            //  加载图片
            img.onload = function(){
                if(img.complete){
                    //  根据图像重新设定了canvas的长宽
                    canvas.setAttribute("width",img.width)
                    canvas.setAttribute("height",img.height)
                    //  绘制图片
                    context.drawImage(img,0,0,img.width,img.height)
                }
            }
        }
    },1)
},

context.drawImage()方法的参数介绍,可参照 W3school

2.3 绘制矩形

context.strokeStyle = "red"
context.lineWidth = 3;
context.strokeRect(x, y, width, height)

context 同上面的定义

strokeStyle 矩形颜色

lineWidth 矩形边框宽度

x,y,width,height 矩形位置加长宽

2.4 绘制线条

context.moveTo(x1,y1) 
context.lineTo(x2,y2)
context.strokeStyle = "red"
context.lineWidth = 3;
context.stroke()

(x1,y1) (x2,y2) 线条的起点和终点坐标

strokeStyle lineWidth 线条的样式

2.5 绘制文字

context.font = "26px Arial bolder"
context.fillStyle = 'red'
context.fillText(text,x,y)

font fillStyle 文字样式

text 文字内容

x,y 文字显示坐标

2.6 下载图片

// 图片地址和图片名称
downIamge (imgsrc, name) { 
    let image = new Image()
    image.setAttribute('crossOrigin', 'anonymous')
    image.onload = function () {
        let canvas = document.createElement('canvas')
        canvas.width = image.width
        canvas.height = image.height
        let context = canvas.getContext('2d')
        context.drawImage(image, 0, 0, image.width, image.height)
        let url = canvas.toDataURL('image/jpg') 
        let a = document.createElement('a')
        let event = new MouseEvent('click')
        a.download = name
        a.href = url
        a.dispatchEvent(event)
    }
    image.src = imgsrc
},

3 后记

这里只是列出canvas的基础使用,具体的交互和展示还需要更多的设计。

感谢支持。若不足之处,欢迎大家指出,共勉。

如果觉得不错,记得 点赞,谢谢大家 😂

欢迎关注 我的: 【Github】【掘金】【简书】【CSDN】【OSCHINA】【SF】

3.1 参考资料

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

出处为:https://github.com/xrkffgg/Tools

009.vue全家桶+Echarts+百度地图,搭建数据可视化系统(【续】接口篇)

接上篇

vue全家桶+Echarts+百度地图,搭建数据可视化系统

1 前 言

1.1 业务场景

实现数据监控的系统。有线图、柱状图、地图,并具有定时刷新的功能。

1.2 业务分析

上一篇分析的步骤大致有:

  1. 系统搭建vue-cli
  2. vuex记录登录信息
  3. vue-router路由跳转
  4. 3个维度的页面,提取出共用的组件
  5. 各个组件开发
  6. 调节样式,增加UI
  7. 加入后台接口数据
  8. 优化显示
  9. 测试
  10. 上线

上一篇介绍了 1-6 部分。本篇将介绍一下剩下的 7-10 部分。

😂😂

主要内容是 对数据的处理方式整体的数据逻辑

望各位看官多提 建议和不足 哈,也希望能本篇能给需要人带来 启发。

成品效果图不方便发,还是用上一篇,纯前端的效果图吧。

2 正 文

2.1 请求处理数据

Vue 中 与后台交互通常使用的是 axios

2.1.1 安 装

npm i axios

也可通过cdn引用

2.1.2 定 义

新建一个api.js

//  api.js
import axios from 'axios'
const http = axios.create ({
    baseURL : apiurl,       // 连接后端地址
    timeout : 1000 * 30,    // 超时时间,单位为毫秒
    headers : {},          // 请求头,可添加'Authorization'、'X-Requested-With'、'Accept-Language'、'token'等
})

// 请求拦截
http.interceptors.request.use(config =>{
    // 可添加自己的设置,如修改参数、增加参数、修改headers
    return config
},error =>{
    // 可添加报错处理
    return Promise.reject(error)
})

// 响应拦截
http.interceptors.response.use(response =>{
    // 可添加处理逻辑
    return response
},error =>{
    return Promise.reject(error)
})

export default http

同时可在main.js中添加一个自定义全局对象,或者可在单独页面中引用

// main.js
import http from './api.js'

Vue.prototype.$http = http

2.1.3 使 用

a. get请求

在页面中处理时

query(){
    this.$http.get('/xxx/xxx?id='+id).then(res =>{
        // 返回的处理
        console.log(res)
        // res 一般包含code data
    },rej =>{
        // 报错的处理
        console.log(rej)
    })
}

b. post请求

new(){
    this.$http.post('/xxx/xxx',{
        id : '123',
    }).then(res =>{
        // 返回的处理
        console.log(res)
        // res 一般包含code data
    },rej =>{
        // 报错的处理
        console.log(rej)
    })
}

c. 其他请求

经常使用到的还有

put 多用于更新操作

delete 多用于删除操作

具体要看后台提供的功能接口方式

d. 多个请求

比如,我在进来页面后,要同时获取要2个线形图、数字、地图、柱状图、表格的数据

一般情况下,各个数据都是单独的接口来提供的。这样我们就需要至少6个接口。

async query(){
    let that = this
    await axios.all([that.get1(), that.get2(), that.get3()]).then(axios.spread((res1, res2, res3) =>{
        // res1 为 get1 的返回
        // res2 为 get2 的返回
        // res3 为 get3 的返回
    }))
}

get1(){
    return this.$http.get('/xxx/xxx')
}

get2(){
    return this.$http.get('/xxx/xxx')
}

get3(){
    return this.$http.get('/xxx/xxx')
}

2.2 登 录

功能很简单,用户输入用户名、密码、验证码,点击登录。

2.2.1 获取uuid

出于对登录时效以及安全性的考虑。在登录验证时,后台根据 uuid 和通过 uuid 获取到的验证码进行校验。

这里列出一些获取 uuid 的方法。来源于:网络。

方法一:

getUUID () {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
        return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
    })
},

方法二:

generateUUID() { 
    var d = new Date().getTime()
    if (window.performance && typeof window.performance.now === "function") { 
        d += performance.now()
    }
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 
        var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16) 
        return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16)
    })
    return uuid
}

方法三:

guid() { 
    function S4() { 
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    } 
    return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4())
}

方法四:

/*
    指定长度和基数
*/
function uuid2(len, radix) {
    var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
    var uuid = [],
        i;
    radix = radix || chars.length;

    if (len) {
        for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
    } else {
        var r;
        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
        uuid[14] = '4';
        for (i = 0; i < 36; i++) {
            if (!uuid[i]) {
                r = 0 | Math.random() * 16;
                uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
            }
        }
    }
    return uuid.join('');
}

2.2.2 密码加密

--input 
type="password" 可使输入框中内容隐藏

传输时,我使用了md5加密

npm i -S js-md5
import md5 from 'js-md5'

let enCode = md(code)

然后就是调用后台接口将你的用户名、密码、验证码发送进行验证登录。

2.2.3 存储登录信息

使用过 Vue 的童鞋都清楚,使用vuex的时候,进行刷新页面,store中的数据就会重置。

会防止用户在刷新页面后数据无法获取的情况,一般会将数据同时储存到 sessionStoragelocalStorage

两者区别这里就不介绍了。

// 储存session,具体放在哪个位置根据实际业务
// 我这里放在了登录验证通过之后,当然有很多参数,可使用对象类型转成json ----JSON.stringify(info)
sessionStorage.setItem('info', '123')
// store.js

store = {
    state : JSON.parse(sessionStorage.getItem('info')) || {}
}

这样页面刷新后,store 会从 sessionStorage 拿到我们的数据

2.3 业务页面

业务页面分了3个维度。

这里介绍2个维度的实现。

2.3.1 整体逻辑

单独的组件只处理数据的展示

如线形图单独写在一个组件中

我在需要的页面中进行引用,传入数据进行显示。

  1. 用户登录验证后,储存业务 IDsession 中,从登录页面跳转到 层级1 页面。
  2. 进入 层级1 后,created 中增加初始化方法。就是使用了上面介绍的 axios.all
  3. 拿到各数据后,分别渲染到各个组件中。
  4. 初始化完成后,触发定时刷新开发。
  5. 根据定时器的时间,触发需要刷新的功能,同上 axios.all 和处理结果。
  6. 点击层级1中某个数据,记录层级2需要的 ID2session中,关闭定时刷新,跳转到 层级2 页面。
  7. 进入 层级2 后,同层级1,先进行初始化,再进行定时刷新。
  8. 层级3 以及 返回 的逻辑都基本和上面一样。

下面介绍一些可能会有 疑问 的地方

2.3.2 层级页面举例

相当于介绍了一些父子组件的一些处理。

// 层级1.vue
<template>
    <div id="xxx">
        <a-com ref="aRef" :args="argA"/>
        <b-com ref="bRef" :args="argB"/>
    </div>
</template>

<script>
    import Acom from './a.vue'
    import Bcom from './b.vue'
    import store from './store.js'
    
    export default {
        components : {
            'a-com':Acom,
            'b-com':Bcom,
        },
        
        created(){
            //  初始化方法
            this.init()
        },
        
        mounted(){
            //  定时查询方法
            this.timeq()
        },
        
        data() {
            return {
                //  传入子组件的数据,可可以使用store
                argA : {},
                argB : {},
                
                // 定时开关
                timimg : false,
            }
        },
        
        methods: {
            async init(){
                let id1 = store.state.info.id1
                await this.query(id1)
                this.timimg = true
            },
            
            timeq(){
                //  这里定义了 5S 刷新一次
                let that = this
                this.timequery = setInterval(() =>{
                    if(timimg){
                        that.querytime(store.state.info.id1)
                    }
                },5000)
            },
            
            async query(id){
                let that = this
                await axios.all([that.get1(id), that.get2(id)]).then(axios.spread((res1, res2) =>{
                    // 数据传入组件a,触发组件a的初始化方法
                    that.argA = res1.data
                    that.$refs.aRef.init();
                    
                    // 数据传入组件b,触发组件b的初始化方法
                    that.argB = res2.data
                    that.$refs.bRef.init();
                }))
            },
            
            querytime(id){
                //  同 query()  
            },
            
            get1(id){
                return this.$http.get('xxx')    
            },
            
            get2(id){
                return this.$http.get('xxx')
            },
            
            //  跳转第二层级
            goto2(){
                this.timing = false
                if(this.timequery){
                    clearInterval(this.timequery)
                }
                // replace、push, 也可以使用name 
                this.$router.replace('./path2')
            },
        }
    }
</script>

2.3.3 组件页面举例

// 如果使用了父组件向子组件传值的方式,需在子组件的 data 中 定义 props 用于接收

// echarts 初始化
init(){
    // 和上篇介绍 echarts 中定义差不多
    var myChart = this.$echarts.init(document.getElementById("id"),'temp')
    let option = {}
    option = {
        // 吧啦吧啦 一顿操作和配置
        // 可参考上一篇文章,更多参考 官网配置页面
        myChart.setOption(option, true)
    }
}

这里有一个需要注意的地方就是

横向柱状图,最下方 是第一条,我们自定义标题的时候,就要颠倒过来使用。

同时会根据条数自动切换位置,我们的表头也需要根据数量进行位置调整。

2.4 测 试

说实话,这方面一直都没认真写过。。。

一般业务变动的情况下,逻辑也会变动频繁。

但编写测试代码还是很重要的。

Vue 官方推荐的是使用 karmamochachai 等。

感兴趣的 可以 专门去了解学习下

这一大块不亚于 编写 业务代码 😅😅😅

这里不多介绍了哈。

2.5 打 包

npm run build

可在根目录中 新建 vue.config.js

官方文档: https://cli.vuejs.org/zh/config/

//  官方文档: https://cli.vuejs.org/zh/config/
module.exports = {
    baseUrl: process.env.NODE_ENV === 'production' ? './' : '/',
}

3 后 记

感谢支持。若不足之处,欢迎大家指出,共勉。

如果觉得不错,记得 点赞,谢谢大家 😂

欢迎关注 我的:

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

出处为:https://github.com/xrkffgg/Tools

007.Vue项目打包后动态获取自定义变量

1 前言

1.1 业务场景

一般使用 Vue 项目连接后端请求,使用的 axios

import axios from 'axios'

export const CMSAPI = axios.create({
  baseURL: "http://localhost:8080",
  timeout: 30000,
});

axios 中的 baseURL 一般是访问地址

Vue 项目打包后,如果我们需要修改这个 baseURL 就需要修改代码重新 build

这样就比较麻烦了

有没有什么办法可以在Vue项目打包后再自定义变量呢?

2 实现原理

2.1 文件

目前使用新版 @vue/cli 创建的项目目录如上

我们发现这个图标文件 favicon.ico 在打包文件中会单独存在

类似,我们在这个文件夹中新建一个 index.js 文件

2.2 代码

index.js 文件中,我们直接定义一个变量

//  index.js
const apiURL = 'http://localhost:8080'
//  index.html
<script type="text/javascript" src="<%= BASE_URL %>index.js"></script>
//  然后使用window对象
window.apiURL = apiURL
// axios中引用
import axios from 'axios'

export const CMSAPI = axios.create({
  baseURL: window.apiURL,
  timeout: 30000,
});

2.3 打包

npm run build 后,会发现根目录中有我们定义的 index.js

这样我们就可以直接修改 index.js 中变量的值就可以啦

3 后记

感谢支持。若不足之处,欢迎大家指出,共勉。

如果觉得不错,记得 点赞,谢谢大家 😂

欢迎关注 我的: 【Github】 【掘金】 【简书】

知识共享许可协议
本文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

出处为:https://github.com/xrkffgg/Tools

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.