vue全家桶Echarts百度地图搭建数据可视化系统续接口篇

39次阅读

共计 5506 个字符,预计需要花费 14 分钟才能阅读完成。

接上篇

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 部分。

????????

主要内容是 <font color=red>对数据的处理方式 </font> 和 <font color=red> 整体的数据逻辑</font>。

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

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

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 后 记

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

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

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

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

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

正文完
 0