Vue разрабатывает решения для визуализации для крупноэкранного проекта

внешний интерфейс Vue.js
Vue разрабатывает решения для визуализации для крупноэкранного проекта

Эта статья участвовала в третьем этапе тренировочного лагеря для создателей Nuggets. Подробнее см.:Dig Li Project | Идет третий этап тренировочного лагеря создателя, «написание» личного влияния.

предисловие

В эпоху больших данных мы часто слышим «говорить с данными«Это предложение. Но сами данные — это просто холодное число, нам трудно прямо сказать, какие данные являются ценной информацией. Только отображая и выражая данные с помощью соответствующих инструментов визуализации, ценность данных может быть более интуитивно понятной для пользователей.

Теперь все сферы жизни постепенно популяризируют визуализацию на большом экране.Благодаря этой статье вы получите полное представление о том, как проекты визуализации на большом экране могут перейти от нуля к единице, чтобы вас больше не беспокоила визуализация данных.

Поскольку в последнее время я работаю над проектом визуализации для большого экрана в сочетании с функциями, необходимыми для большинства проектов с большим экраном, я просто написал шаблон проекта для большого экрана, который можно загрузить и использовать.Постоянно совершенствуемся... Я с нетерпением жду вашего присоединения k-LargeScreen

Начало работы — как адаптироваться

Схема адаптации

Недавно, когда я начал работать над проектом визуализации для большого экрана, я ознакомился с большим количеством информации об адаптации для большого экрана. Есть много вариантов, чтобы назвать несколько:

  1. Которые установили телефонный адаптер(Ранее я писал статью о смешанной разработке H5, нажмите, чтобы просмотреть краткий обзор.)
    • px в бэр
    • запросы средств массовой информации
    • обзорная площадка
  2. масштабная схема

px в бэр

px 转 remОн основан на fontSize страницы, чтобы установитьrem а также pxКоэффициент конверсии, например16px=1rem , 20px=1remВ зависимости от дизайна экрана размер шрифта страницы очень часто используется при разработке мобильных терминалов.

html { /* 普通状态 */
	font-size: 20px
}
html { /* 1.5倍分辨率 */
	font-size: 30px
}
html { /* 2倍分辨率 */
	font-size: 40px
}
.div-box {
	width: 5rem; /* 5倍的font-size 普通状态下 = 100px */
}

Но текущий проект может не применяться:

  1. На странице есть и другие элементы, которые были разработаны с навигационным текстом, настройкамиfontSizeповлияет на контент, уже написанный на странице
  2. страница используетechartsДиаграмма, параметры внутри не могут быть примененыremпропорция

запросы средств массовой информации

Медиа-запрос — относительно распространенная схема экранной адаптации. Она может предоставлять различные схемы стилей в зависимости от размера экрана. Медиа-запрос вполне может удовлетворить большинство потребностей в макете веб-страницы на стороне ПК.

@media only screen and (max-width: 1000px) {
    .div-class {
        width: 720px;
    }
}

Но проблема также более очевидна:

  1. Написание большого количества кода медиа-запроса обременительно
  2. Адаптируется к различным экранам и не может гарантировать полную совместимость со всеми экранами.
  3. тоже не могу поддержатьechartsПараметры в таблице адаптированы

обзорная площадка

viewpointПо сути, это метод адаптации, который в настоящее время будет использоваться в большинстве разработок мобильных терминалов.Вы можете установить общее масштабирование интерфейса устройства мобильного терминала.Этот метод адаптации является лучшим решением.Однако недостатки очевидны и могут только использовать в мобильном терминалеviewpointАдаптация, наши текущие данные большой экран больше не могут быть использованы.

<meta name="viewport" content="target-densitydpi=high-dpi" />

О выборе плана

Я выбрал второй вариант, и я рекомендую всем выбрать второй вариант. можно написать прямоpx, что действительно удобно.
Используется в сочетании с некоторыми необходимыми местамиЕдиницы области просмотраvw、vh

Что такое окно просмотра? 

На стороне ПК область просмотра относится к стороне ПК, которая относится к видимой области браузера;

На мобильной стороне он включает 3 окна просмотра:Layout Viewport(布局视口),Visual Viewport(视觉视口),Ideal Viewport(理想视口).

«Вьюпорт» в единице области просмотра, сторона ПК относится к видимой области браузера, а мобильная сторона относится к области просмотра макета в области просмотра.

согласно сСпецификация CSS3, единица области просмотра в основном включает следующие 4 элемента:

      1.vw: 1vw равен 1% ширины области просмотра.

      2.vh: 1vh равен 1% высоты области просмотра.

      3.vmin: Выберите наименьшее из значений vw и vh.

      4.vmax: Выберите наибольшую из vw и vh.

 vh and vw: высота и ширина относительно области просмотра, а не родительского элемента (проценты CSS относятся к высоте и ширине ближайшего родителя, содержащего его). 1vh равен 1/100 высоты области просмотра, а 1vw равен 1/100 ширины области просмотра.

Например: высота браузера 950 пикселей, ширина 1920 пикселей, 1 vh = 950 пикселей/100 = 9,5 пикселей, 1vw = 1920 пикселей/100 = 19,2 пикселей.

vmaxОтносительно ширины или высоты области просмотра, в зависимости от того, что больше. Самый большой из них поровну разделен на vmax 100 единиц.

vminОтносительно ширины или высоты области просмотра, в зависимости от того, что меньше. Самый маленький из них делится поровну на 100 единиц vmin.

Краткое введение в схему шкалы

scale()

CSS-функцияscale()Используется для изменения размера элемента. Элементы могут быть увеличены или уменьшены с помощью значений масштабирования, определенных в векторной форме, и различные значения масштабирования могут быть установлены в разных направлениях.

Это преобразование использует двумерный вектор, чтобы определить, насколько масштабироваться в одном направлении. Если две координаты масштабированного вектора равны, то они равны или изотропны, и форма элементов сохраняется. В этом случае осуществляется трансформация.

Когда значение координаты находится в интервале [-1, 1]Когда он снаружи, преобразование увеличит элемент в соответствующем направлении координат, а когда оно находится в интервале, преобразование уменьшит элемент в соответствующем направлении координат. Когда значение равно 1, обработка не выполняется, когда оно отрицательное,отражение пикселейЗатем внесите изменения в размер.

scale()Применяется только к преобразованиям на евклидовой плоскости (двумерной плоскости). Если требуется масштабирование в пространстве, вы должны использоватьscale3D().

грамматика

scale(sx)

или

scale(sx, sy)

стоимость

  • sx

    <number>, Горизонтальная ось представляет вектор масштабирования.

  • sy

    <number>, представляющий ординату вектора масштабирования. Если не установлено, его значение по умолчанию установлено наsx. Это позволяет равномерно масштабировать элемент, сохраняя при этом свою первоначальную форму.

image.png

Пример

Одномерное масштабирование

HTML
<p>foo</p>
<p class="transformed">bar</p>
CSS
p {
  width: 50px;
  height: 50px;
  background-color: teal;
}

.transformed {
  /* 等同于变换: scaleX(2) scaleY(2);*/
  transform: scale(2);
  background-color: blue;
}

image.png

Увеличьте масштаб как по осям X, так и по Y и переместите центр масштабирования.

HTML

<p>foo</p>
<p class="transformed">bar</p>

CSS

p {
  width: 50px;
  height: 50px;
  background-color: teal;
}

.transformed {
  /* 等同于 scaleX(2) scaleY(0.5) */
  transform: scale(2, 0.5);
  transform-origin: left;
  background-color: blue;
}

image.png

Идеи:

1. Получите соотношение большого экрана при инициализации
2. Установите это соотношение наcssизscaleПеременная
3. Следите за размером окна браузера и назначайте новое соотношениеscaleПеременная
Таким образом, независимо от размера экрана или высокого разрешения, если соотношение сторон экрана совпадает с установленным соотношением, его можно адаптировать.

упражняться

Простая реализация:

 <div class="ScaleBox"
         ref="ScaleBox"
 >

 mounted() {
    this.setScale();
    window.addEventListener("resize", this.setScale);
  },
 methods: {
    getScale() {
      const { width, height } = this;
      let ww = window.innerWidth / width;
      let wh = window.innerHeight / height;
      return ww < wh ? ww : wh;
    },
   setScale() {
      this.scale = this.getScale();
      this.$refs.ScaleBox.style.setProperty("--scale", this.scale);
    },
}

#ScaleBox {
  --scale: 1;
}
.ScaleBox {
  transform: scale(var(--scale)) ;
}

Модернизация в компоненты

<template>
  <div class="bsd-frame" :style="{ background: bgColor }" ref="bsdFrame">
    <slot></slot>
  </div>
</template>
<script>

export default {
  name: 'frame',
  props: {
    width: Number,
    height: Number,
    bgColor: {
      default: 'rgb(11, 19, 32)'
    }
  },
  data() {
    return {
      frameWidth: 0,
      frameHeight: 0
    }
  },
  methods: {
    setSize() {
      this.frameWidth = this.width || screen.width
      this.frameHeight = this.height || screen.height
      const frame = this.$refs.bsdFrame
      frame.style.width = this.frameWidth + 'px'
      frame.style.height = this.frameHeight + 'px'
    },
    setScale() {
      this.setSize()
      const bodyWidth = document.body.clientWidth
      const bodyHeight = document.body.clientHeight
      const scaleX = bodyWidth / this.frameWidth
      const scaleY = bodyHeight / this.frameHeight
      this.$refs.bsdFrame.style.transform = `scale(${ scaleX },${ scaleY })`
    }
  },
  mounted() {
    this.setSize()
  },
  destroyed() {
    window.removeEventListener('resize', this.setScale)
  },
}
</script>
<style lang="scss">
.bsd-frame{
  position: fixed;
  transform-origin: left top;
}
</style>

Git-адрес шаблона визуального проекта для большого экрана

Существует много видов схем адаптации, но они могут не подойти для вашего проекта. Хорошее начало — полдела. Вот мои советы для INE:

  • Обязательно фильтруйте в соответствии с вашими четкими потребностями и не выбирайте вслепую.
  • Выберите хороший план и внедряйте инновации соответствующим образом.«Его сущность, отказалась от его дросса».
  • Верьте в свой выбор, нет универсального решения, есть только безупречная вы

Кратко расскажу о потребностях моего проекта

нужно

бизнес

  1. Проект большого экрана 4K (7680X2640)
  2. Разделен на три части экрана: левый, средний и правый.
  3. Небольшой модуль в левом, среднем и правом трех блоках можно щелкнуть на весь экран или на весь экран.

Например: Нажмите на блок в левом модуле, чтобы сделать левую часть полноэкранной, или три экрана в одном полноэкранном режиме.

image.png

4. Администратор может корректировать данные, а некоторые цифры можно редактировать двойным щелчком мыши.

Требования к разрешениям

Разрешения относительно просты: разделены наадминистратора такжеПользовательДва типа Администратор может изменить данные и соответствующим образом настроить некоторые модули.

Самый простой способ - напрямую сохранитьVuexИли локально, настроить его, когда вы его используете.

Краткое описание реализации функции

При построении каркаса следует учитывать следующие моменты.

  1. Создать привилегии для входа
  2. Редактируемый компонент для разрешений - модифицируемый администратором
  3. Один экран разделен на три, карта среднего экрана связана
  4. Частичный полный экран
  5. полноэкранный переключатель

Vue2.x+Echarts+百度地图Достаточно и удобно в использовании.

Упакуйте некоторые компоненты в сочетании с требованиями

система разрешений на вход

Говоря простым языком, то есть登录成功后-->调取用户信息-->存进Vuex-->部分功能判断

Эта часть очень проста, потому что мой проект на большом экране разделен на пользователей и администраторов, нет, для сложных, вы можете обратиться к статье, которую я написал ранее.

image.png
Клик по картинке недействителен

На самом деле, вы можете напрямуюVue-adminВозьмите этот кусок и измените его, и вы сможете использовать его напрямую.

Редактируемый компонент для разрешений - модифицируемый администратором

Этот компонент легко сделать, если разрешения сделаны

написать публичный компонент

<template>
  <div>
    <div id="test" class="test" :class="{ editing: isChecked }">
      <div class="view">
        <!-- 有tooltip -->
        <template v-if="value.tooltip&&userType==='admin'">
          <!-- 有tooltip可编辑 -->
          <label v-if="value.edit" class="titles isEdit" :style="fontsize">
            <el-tooltip placement="top">
              <div slot="content" class="view-content">
                <span>数据说明:</span><span>{{ value.description }}</span>
                <br />
                <span>更新时间:</span><span>{{ value.updatedOn }}</span>
                <br />
                <span>操作人:</span><span>{{ value.updatedBy }}</span>
              </div>
              <span :style="fontsize" @click.meta="dbTest()" @dblclick="dbTest()" class="view-number">{{ value.value | numberToCurrency }}</span>
            </el-tooltip>
            <i v-if="userType==='admin'" class="el-icon-deit el-icon-edit-outline"></i>
          </label>
          <!-- 有tooltip不可编辑 -->
          <label v-else class="titles">
            <el-tooltip placement="top">
              <div slot="content"  class="view-content">
                <span>数据说明:</span><span>{{ value.description }}</span>
                <br />
                <span>更新时间:</span><span>{{ value.updatedOn }}</span>
                <br />
                <span>操作人:</span><span>{{ value.updatedBy }}</span>
              </div>
              <span :style="fontsize">{{ value.value | numberToCurrency }}</span>
            </el-tooltip>
          </label>
        </template>
        <!-- 无tooltip -->
        <template v-else>
          <!-- 无tooltip可编辑 -->
          <label v-if="value.edit&&userType==='admin'" class="titles isEdit" :style="fontsize">
            <span @click.meta="dbTest()" @dblclick="dbTest()" :style="fontsize" class="view-number">{{ value.value | numberToCurrency }}</span>
            <i v-if="userType==='admin'" class="el-icon-deit el-icon-edit-outline"></i>
          </label>
          <!-- 无tooltip不可编辑 -->
          <label v-else class="titles">
            <span :style="fontsize">{{ value.value | numberToCurrency }}</span>
          </label>
        </template>
      </div>
      <input v-myfoucs="isChecked" class="edit" v-model="inputStr" @blur="blur" @keyup.13="inputStred" />
    </div>
  </div>
</template>

<script>
//可编辑组件使用---全局组件
//value:{
//   edit:false 是否可编辑
//   tooltip: true 是否可以看到更新时间(预留功能)
//   value:Number
//   id:''
//}
// v-on:click.ctrl.exact="dbTest()"
import { mapGetters } from 'vuex'
import { editSurvey } from '@/api/communal'
// import { numberToCurrency } from '@/filters/index'
export default {
  name: 'EditText',
  props: {
    value: {
      type: Object,
      default: () => { }
    },
    //数字大小,默认30px
    fontsize: {
      type: String,
    }
  },
  watch: {},
  data() {
    return {
      item: this.value.value,
      isChecked: false,
      inputStr: ''
    }
  },
  methods: {
    //ctrl+click事件
    dbTest() {
      this.item = this.value._value || this.value.value
      this.isChecked = true
      this.inputStr = this.item
    },
    //失焦事件
    blur() {
      this.item = this.inputStr
      this.isChecked = false
      this.item = this.value.value
    },
    //enter事件
    inputStred() {
      this.item = this.inputStr
      this.isChecked = false
      //修改数据
      editSurvey(this.value.id, this.inputStr).then(res => {
        if (res.success) {
          this.$emit('childMsg', { update: true, id: this.value.id, value: this.value.value })
        }
      })
    }
  },
  //   自定义指令
  directives: {
    'myfoucs': {
      update(el, binding) {
        if (binding.value) {
          el.focus()
        }
      }
    }
  },
  computed: {
    ...mapGetters({
      userType: 'userType'
    }),
  }
}
</script>
<style lang="scss" scoped>
.test.editing .edit {
  display: block;
  width: 150px;
  height: 28px;
}
.test.editing .view {
  display: none;
}
.titles {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 28px;
  font-size: 36px;
  font-weight: bold;
  color: #00ccff;
}
// .isEdit:hover {
//   cursor: pointer;
//   span{
//     color: #3a45ff
//     }
// }
.test .edit {
  display: none;
  //   background: none;
  outline: none;
  border: none;
  margin: 0 auto;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none;
}
input[type="number"] {
  -moz-appearance: textfield;
}
.el-icon-deit {
  font-size: 16px;
  margin-left: 5px;
}
.view-number {
  border: transparent solid 1px;
  cursor: cell;
}
.view-number:hover {
  border: #00ccff solid 1px;
}

</style>

Один экран разделен на три, привязка к карте среднего экрана, частичный полный экран

использоватьVue-routerИменованный вид легко добиться частичного полноэкранного режимаindex.js

<template>
  <Frame>
    <div class="platform page-index">
      <router-view :name="page_left" style="width:2212px;height:2000px;flex-shrink: 0"></router-view>
      <router-view :name="page_middle" style="width:3200px;flex-shrink: 0"></router-view>
      <router-view :name="page_right" style="width:2214px;height:2000px;flex-shrink: 0"></router-view>
    </div>
  </Frame>
</template>

<script>
import Frame from '@/components/Frame'
import { mapGetters } from 'vuex'
export default {
  components: { Frame },
  data() {
    return {

    };
  },
  computed: {
    ...mapGetters({
      page_right: 'page_right',
      page_middle: 'page_middle',
      page_left: 'page_left',
    })
  },
  watch: {},
  methods: {

  },
  created() {

  },
  mounted() {

  },
}
</script>
<style  scoped>
.platform{
  display: flex;
}
</style>

image.png
Нажмите, чтобы перейти к названию Vue-router, посмотреть подробности

Частичный полный экран

Идея частичного полноэкранного режима:
1. Создатьstore, где каждое именованное представлениеname,mutationsНапишите локальный метод переключения внутри


/** eslint disabled */
import { setSession, getSession } from '@/utils/auth'

const state = {
  page_right: getSession('right') || 'right',
  page_middle: getSession('middle') || 'middle',
  page_left: getSession('left') || 'left',
}

const mutations = {
  // 修改页面路由 并记住路由name
  SET_PAGE_TYPE(state, { type, value }) {
    state['page_' + type] = value
    setSession(type, value)
  },
  RESRT_PAGE_TYPE(state) {
    state['page_right'] = 'right'
    state['page_middle'] = 'middle'
    state['page_left'] = 'left'
    setSession('right', 'right')
    setSession('middle', 'middle')
    setSession('left', 'left')
  },
  //  修改局部全屏
  CHANGE_PAGE(state, data) {
    console.log(data);
    state[data.page] = data.name
  },
}
export default {
  namespaced: true,
  state,
  mutations,
}

2. Нажмите на частичный полноэкранный вызов

<template>
<div class='show'>
  <Title title="左侧模块" arrow borderRadius @clickArrow="handleArrow">

    </Title>
</div>
</template>

<script>

import Title from '@/components/Title'
export default {
components: {Title},
data() {
return {

};
},
computed: {},
watch: {},
methods: {
  // ...mapMutations("vuexTest", ['mutationsHello']),
handleArrow(){
  this.$store.commit("moddle/CHANGE_PAGE",{page:'page_left',name:'left_source'});
}
},
created() {

},
mounted() {

},
}
</script>
<style  scoped>
.show{
  width: 100%;
  height: 500px;
  background: lightpink;
}
</style>

3. Частичный возврат в полноэкранный режим

<template>
  <div class='full-left'>
    <Title title="左侧全屏" arrow borderRadius @clickArrow="handleArrow" direction="left"> </Title>
  </div>
</template>

<script>
import Title from '@/components/Title'
export default {
  components: { Title },
  data() {
    return {

    };
  },
  computed: {},
  watch: {},
  methods: {
    //大屏
    handleArrow() {
      this.$store.commit("moddle/CHANGE_PAGE",{page:'page_left',name:'left'});
    },
  },
  created() {

  },
  mounted() {

  },
}
</script>
<style  scoped>
</style>

полноэкранный переключатель

На самом деле, полноэкранного переключения также очень легко добиться, просто измените маршрутизацию, и все готово. Проясняйте свои мысли шаг за шагом.

this.$router.push('')

существуетrouter.jsПросто создайте новый маршрут

import Vue from 'vue'
import Router from 'vue-router'
// import { getToken } from '@/utils/auth'
// import store from '../store'

Vue.use(Router)

const routes = [
  {
    path: '/',
    component: () => import('@/views/moddle/index'),
    children: [
      {
        path: '/',
        components: {
          middle: () => import('@/views/moddle/middle/Index'),
          left: () => import('@/views/moddle/left/Index'),
          right: () => import('@/views/moddle/right/Index'),
          // 左侧全屏
          left_source:()=> import('@/views/moddle/left/full-screen'),

        },
      },
    ]
  },
  // 三屏全屏切换路由
  // {
  //   path: '/',
  //   component: () => import('@/views/Shcc/index'),
  //   children: [
  //     {
  //       path: '/shcc',
  //       components: {
  //         middle: () => import('@/views/Shcc/middle'),
  //         left: () => import('@/views/Shcc/left'),
  //         right: () => import('@/views/Shcc/right'),
  //       },
  //     },
  //   ]
  // },
]
const Rout = new Router({
  // base: process.env.BASE_URL,
  routes,
})
// 路由白名单
// const whiteList = ['/Login',]
// Rout.beforeEach(async (to, from, next) => {
//   const hasToken = getToken()
//   if (hasToken) {
//     if (to.path === '/Login') {
//       next({ path: '/' })
//     } else {
//       if (!store.getters.userType) {
//         await store.dispatch('user/whoami')
//       }
//       next()
//     }
//   } else {
//     if (whiteList.indexOf(to.path) !== -1) {
//       next()
//     } else {
//       next(`/Login?redirect=${ to.path }`)
//     }
//   }
// })
export default Rout

конец

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

Полный исходный код проекта находится по адресуgitHub, могут быть загружены и использованы напрямую, и будут постоянно обновляться в будущем.

я дал имяk-LargeScreenкkОт имени значения начала быстрого

k-LargeScreenЕсли это вам поможет, пожалуйста, зажгите свою звездочку ⭐⭐⭐ о~ (сумасшедший намек)

Надеюсь, это поможет вам, кто запутался

напиши в конце

якрутой город а, фронтенд, любит технологии и любит жизнь.

Я очень счастлив встретить тебя.

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

  • Если в статье есть ошибки, исправьте их в комментариях, если статья вам поможет, ставьте лайк и подписывайтесь 😊

  • Эта статья была впервые опубликована на Наггетс, перепечатка без разрешения запрещена 💌