Семейная корзина Vue + Echarts + карта Baidu, создание системы визуализации данных ([продолжение] интерфейс)

Vue.js

Продолжение предыдущей статьи

Семейная корзина Vue + Echarts + карта Baidu, создание системы визуализации данных

1. Введение

1.1 Бизнес-сценарий

Система, реализующая мониторинг данных. Линейный график, гистограмма, карта и функция обновления по времени.

1.2 Бизнес-анализ

Шаги предыдущего анализа примерно следующие:

  1. Строительство системыvue-cli
  2. vuexзаписать данные для входа
  3. vue-routerпрыжок по маршруту
  4. Трехмерные страницы, извлечение общих компонентов
  5. Разработка отдельных компонентов
  6. Настройте стиль, увеличьте пользовательский интерфейс
  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 Использование

а. получить запрос

при обработке на странице

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

б. отправить запрос

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

с. Другие запросы

Также часто используется

putВ основном используется для операций обновления

deleteВ основном используется для операций удаления

В частности, это зависит от функционального интерфейса, предоставляемого фоном.

г. Несколько запросов

Например, после входа на страницу я хочу одновременно получить данные двух линейных графиков, чисел, карт, гистограмм и таблиц.

Как правило, каждые данные предоставляются отдельным интерфейсом. Итак, нам нужно как минимум 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Данные будут сброшены.

Это предотвратит возможность получения пользователем данных после обновления страницы.Как правило, данные будут храниться вsessionStorageилиlocalStorage

Разница между ними не будет здесь представлена.

// 储存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. После того, как пользователь вошел в систему и прошел проверку, бизнес сохраняетсяIDприбытьsession, перейдите со страницы входа на страницу уровня 1.
  2. После входа на уровень 1,createdДобавлен метод инициализации в . используя вышеизложенноеaxios.all
  3. После получения каждых данных визуализируйте их для каждого компонента отдельно.
  4. После завершения инициализации запустите разработку обновления синхронизации.
  5. Запустите функцию, которую необходимо обновить в соответствии со временем таймера, как указано выше.axios.allи обработки результатов.
  6. Щелкните данные уровня 1, чтобы записать данные, необходимые для уровня 2.ID2прибытьsession, отключите запланированное обновление и перейдите на страницу уровня 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Официальная рекомендация - использоватьkarma,mochaа такжеchaiЖдать.

Если вам интересно, вы можете узнать об этом

Этот кусок не меньше, чем написание бизнес-кода 😅😅😅

Не так много, чтобы представить здесь.

2.5 Упаковка

npm run build

может быть создан в корневом каталогеvue.config.js

Официальная документация:cli.vuejs.org/zh/config/

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

3 Постскриптум

Спасибо за поддержку. Если есть какие-то недостатки, пожалуйста, указывайте на них и поощряйте друг друга.

Если вы думаете, что это хорошо, не забудьте поставить лайк, спасибо😂

Добро пожаловать, чтобы следовать за мной:

知识共享许可协议
В этой статье используетсяCreative Commons Attribution-NonCommercial-ShareAlike 4.0 Международная лицензияЛицензия.

Источник:GitHub.com/подсолнух ветер пейзаж свет/тоже…