Эта статья участвовала в третьем этапе тренировочного лагеря для создателей Nuggets. Подробнее см.:Dig Li Project | Идет третий этап тренировочного лагеря создателя, «написание» личного влияния.
предисловие
В эпоху больших данных мы часто слышим «говорить с данными«Это предложение. Но сами данные — это просто холодное число, нам трудно прямо сказать, какие данные являются ценной информацией. Только отображая и выражая данные с помощью соответствующих инструментов визуализации, ценность данных может быть более интуитивно понятной для пользователей.
Теперь все сферы жизни постепенно популяризируют визуализацию на большом экране.Благодаря этой статье вы получите полное представление о том, как проекты визуализации на большом экране могут перейти от нуля к единице, чтобы вас больше не беспокоила визуализация данных.
Поскольку в последнее время я работаю над проектом визуализации для большого экрана в сочетании с функциями, необходимыми для большинства проектов с большим экраном, я просто написал шаблон проекта для большого экрана, который можно загрузить и использовать.Постоянно совершенствуемся... Я с нетерпением жду вашего присоединения k-LargeScreen
Начало работы — как адаптироваться
Схема адаптации
Недавно, когда я начал работать над проектом визуализации для большого экрана, я ознакомился с большим количеством информации об адаптации для большого экрана. Есть много вариантов, чтобы назвать несколько:
-
Которые установили телефонный адаптер(Ранее я писал статью о смешанной разработке H5, нажмите, чтобы просмотреть краткий обзор.)
- px в бэр
- запросы средств массовой информации
- обзорная площадка
- масштабная схема
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 */
}
Но текущий проект может не применяться:
- На странице есть и другие элементы, которые были разработаны с навигационным текстом, настройками
fontSizeповлияет на контент, уже написанный на странице - страница использует
echartsДиаграмма, параметры внутри не могут быть примененыremпропорция
запросы средств массовой информации
Медиа-запрос — относительно распространенная схема экранной адаптации. Она может предоставлять различные схемы стилей в зависимости от размера экрана. Медиа-запрос вполне может удовлетворить большинство потребностей в макете веб-страницы на стороне ПК.
@media only screen and (max-width: 1000px) {
.div-class {
width: 720px;
}
}
Но проблема также более очевидна:
- Написание большого количества кода медиа-запроса обременительно
- Адаптируется к различным экранам и не может гарантировать полную совместимость со всеми экранами.
- тоже не могу поддержать
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. Это позволяет равномерно масштабировать элемент, сохраняя при этом свою первоначальную форму.
Пример
Одномерное масштабирование
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;
}
Увеличьте масштаб как по осям 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;
}
Идеи:
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:
- Обязательно фильтруйте в соответствии с вашими четкими потребностями и не выбирайте вслепую.
- Выберите хороший план и внедряйте инновации соответствующим образом.«Его сущность, отказалась от его дросса».
- Верьте в свой выбор, нет универсального решения, есть только безупречная вы
Кратко расскажу о потребностях моего проекта
нужно
бизнес
- Проект большого экрана 4K (
7680X2640) - Разделен на три части экрана: левый, средний и правый.
- Небольшой модуль в левом, среднем и правом трех блоках можно щелкнуть на весь экран или на весь экран.
Например: Нажмите на блок в левом модуле, чтобы сделать левую часть полноэкранной, или три экрана в одном полноэкранном режиме.
4. Администратор может корректировать данные, а некоторые цифры можно редактировать двойным щелчком мыши.
Требования к разрешениям
Разрешения относительно просты: разделены наадминистратора такжеПользовательДва типа Администратор может изменить данные и соответствующим образом настроить некоторые модули.
Самый простой способ - напрямую сохранитьVuexИли локально, настроить его, когда вы его используете.
Краткое описание реализации функции
При построении каркаса следует учитывать следующие моменты.
- Создать привилегии для входа
- Редактируемый компонент для разрешений - модифицируемый администратором
- Один экран разделен на три, карта среднего экрана связана
- Частичный полный экран
- полноэкранный переключатель
Vue2.x+Echarts+百度地图Достаточно и удобно в использовании.
Упакуйте некоторые компоненты в сочетании с требованиями
система разрешений на вход
Говоря простым языком, то есть登录成功后-->调取用户信息-->存进Vuex-->部分功能判断
Эта часть очень проста, потому что мой проект на большом экране разделен на пользователей и администраторов, нет, для сложных, вы можете обратиться к статье, которую я написал ранее.
Клик по картинке недействителен
На самом деле, вы можете напрямую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>
Нажмите, чтобы перейти к названию 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Если это вам поможет, пожалуйста, зажгите свою звездочку ⭐⭐⭐ о~ (сумасшедший намек)
Надеюсь, это поможет вам, кто запутался
напиши в конце
якрутой город а, фронтенд, любит технологии и любит жизнь.
Я очень счастлив встретить тебя.
Если вы хотите узнать больше, пожалуйста, нажмите здесь, с нетерпением жду вашего маленького ⭐⭐
-
Если в статье есть ошибки, исправьте их в комментариях, если статья вам поможет, ставьте лайк и подписывайтесь 😊
-
Эта статья была впервые опубликована на Наггетс, перепечатка без разрешения запрещена 💌