1. 安装 vue3
也就是安装了一下vue3,但是 dataV 和 Echarts 的学习并没有使用vue的脚手架去创建一个项目。
原因有两点:
- dataV 目前对 vue3 的支持并不是很友好,主要还是基于 vue2 框架的一个组件库。
- 脚手架创建 vue 项目确实会使开发更加的有逻辑性,方便和快捷,也有着其特定的功能(下面会将关于 vue 开发的结构)。但是,首先,我不是一个前端工程师,我只需要将我想要展示的东西搞出来就好,更专业的事情应该交给更专业的人来做;再次,实在不想装一些我不经常用的东西(纯属个人强迫症)。
当然,你们如果想用 vue 脚手架来构建项目 完全可以,和导入 vue.js 来做开发的方法大致都是差不多的,只是 vue 项目有其自己的结构和写法,自行百度或者问 chatGPT。
1.1 关于node.js版本的升级
由于我是用的是Ubuntu20.04
Ubuntu 20.04的官方仓库中提供了一个相对较旧的Node.js版本,如果需要升级Node.js到最新版本,可以进行下面的操作
注意:
在升级Node.js之前,建议备份重要的项目文件和数据,以免升级过程中出现意外情况导致数据丢失
- 确认已安装curl和gnupg2工具,如果没有安装,可以使用以下命令安装:
sudo apt update
sudo apt install curl gnupg2
- 添加Node.js官方PPA(Personal Package Archive)软件源,并更新软件包列表:
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt update
# 这里使用的是Node.js 16.x版本
# 如果需要升级到18版本,可以将上述命令中的setup_16.x替换成setup_18.x
- 安装Node.js和npm:
sudo apt install nodejs
# 安装 nodejs 会自己附带npm的安装
- 验证Node.js和npm是否安装成功:
node -v
npm -v
# 如果输出了Node.js和npm的版本号,则说明安装成功
2. dataV
简单说就是 vue 的一个组件,对 vue 组件有了解的话,应该就会对 dataV 会有一个很好的理解,当然,肯定就会用啦!
2.1 vue 组件
官方文档链接
2.1.1 vue 组件的由来
前端开发中经常会遇到代码复用,比如一个京东购物网站的导航栏(顶部)在每一个页面都存在(也有不存在的,不要杠。。。),就可以理解为是一种代码复用的结果(当然,我也不知道京东用了什么技术,也不要抬杠,就是举个例子),就是通过复用导航栏的那一部分的代码,比如 html
、css
、js
等,来达到每个页面具有相同结构的目的。
然而有时代码复用,可能由于代码很长,致使阅读代码很困难等等,是一个又耗时又费力的操作,两种解决方案:
css
和js
的模块化管理(主要是js
)- vue 组件化编程
这里可能涉及一个单页应用和多页应用的概念,目前还不怎么理解
2.1.2 vue 组件
简单理解就是:
用来实现局部(特定)功能效果的代码集合
上面的图来自 vue 官方,简单理解就是:
- 其中根节点是一个Vue实例
- 其子节点就是一个个的组件
- 子节点之间存在父子关系,也就是说vue组件也存在父子关系
2.1.3 非单页面组件
非单页面组件:一个文件中可以包含有n个组件
单文件组件:一个文件中只包含有1个组件(这种通常在使用vue脚手架创建的vue项目中使用)
…
这里我们使用非单页面来创建组件,这个懂了,单文件组件就很简单了
几个注意点:
- 关于组件名:
一个单词:
第一种写法(全小写):test
第二种写法(首字母大写):Test
多个单词组成时:
第一种写法(全小写):mytest
第二种写法(kebab-case命名):my-test
第三种写法(CamelCase命名):MyTest
(需要Vue脚手架支持)
注:可以使用 name 配置项指定组件在开发者工具中呈现的名字,一般在大项目中会使用 - 关于组件标签:
第一种写法:<test> </test>
第二种写法:<test/>
注:不使用脚手架时,test/
会导致后续组件不能渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入 vue.js -->
<script src="./js/vue@2.7.14.js"></script>
</head>
<body>
<div id="root">
<test></test>
<!-- <test inline-template>
<div>
<p>姓名:{{name}}</p>
<p>年龄:{{age}}</p>
</div>
</test> -->
</div>
</body>
<script type="text/javascript">
/*
VueComponent:
1. test组件的本质就是名为 VueComponent 的构造函数,即 test 组件是 VueComponent 的实例对象
2. Vue官方给的构建组件的方式为:
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
<div id="components-demo">
<button-counter></button-counter>
</div>
关于 this 的指向
(1) 组件配置(也就是说VueComponent的实例对象)中的 this
data函数、methods中的函数、watch中的函数、computed中的函数 它们的 this 均是【VueComponent实例对象】
(2) new Vue(options)配置中:
data函数、methods中的函数、watch中的函数、computed中的函数 它们的 this 均是【Vue实例对象】
*/
// 注册、声明一个组件
const test = Vue.extend({
// 定义组件在Vue开发者工具中的显示名称
// 但是在 html 中使用时 还是vue实例中注册的组件名称
name: 'mytest',
// 组件中的 html 模板
template: `
<div>
<p>姓名:{{name}}</p>
<p>年龄:{{age}}</p>
</div>
`,
// data必须是一个函数
// data: function () {}
data() {
return {
name: ' xiaoming',
age: 20
}
}
})
/*
组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,
例如 data、computed、watch、methods 以及生命周期钩子等。
仅有的例外是像 el 这样根实例特有的选项。
*/
// 全局注册
// Vue.component('test', test)
var vm = new Vue({
el: '#root',
// 注册组件 (局部注册)
components: {
// 组件名称: 声明的组件
// html 文件中引用组件的方式就是 <组件名称></组件名称>
// 一般情况下 组件名称和我们想绑定的组件名称是一样的
test: test
// xxx: test 可以更换 test 组件的名称
// test 组件名称也可以不写,相当与 test: test
}
})
</script>
</html>
2.1.4 组件模板的引用(或者说写法)
2.1.5 组件的嵌套
注意:在组件被嵌套前一定是要先被创建好。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入 vue.js -->
<script src="./js/vue@2.7.14.js"></script>
</head>
<body>
<div id="root">
<test></test>
</div>
</body>
<script type="text/javascript">
const test1 = Vue.extend({
template: `
<div>
<p>姓名:{{name}}</p>
<p>年龄:{{age}}</p>
</div>
`,
data() {
return {
name: ' xiaohong',
age: 20
}
}
})
// 注册、声明一个组件
const test = Vue.extend({
template: `
<div>
<p>姓名:{{name}}</p>
<p>年龄:{{age}}</p>
<test1></test1>
</div>
`,
data() {
return {
name: ' xiaoming',
age: 20
}
},
// A 嵌套 B 就在 A 的组件配置中注册 B
// 并且在 A 的 template 中使用 B
components: {
test1
}
})
var vm = new Vue({
el: '#root',
// 注册组件 (局部注册)
components: {
test
}
})
</script>
</html>
2.1.6 单文件组件
单文件组件是由
.vue
类型文件,他不是 js 文件 浏览器没办法去解析这个文件。
两种方法:
- Vue CLI,基于 webpack
- Vite 前端工具链
(1)文件结构
# 构建 vue 实例
main.js
# 组件的 leader
App.vue
# 单个组件文件
test1.vue
test2.vue
# html 文件作为容器
index.html
......
(2)文件中的内容
下面只是简单表明一下 单文件组件怎么写,没有创建 vue 工程 代码是跑不成功的
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root">
<!-- 使用App组件 -->
<App></App>
</div>
<script src="text/javascript" src="./main.js"></script>
</body>
</html>
<!-- --------------------------------------------------------------- -->
<!-- 组件1.vue -->
<template>
<div class="demo1">
<h2>姓名:{{name}}</h2>
<h2>年龄:{{age}}</h2>
<button @click="showName">点我显示姓名</button>
</div>
</template>
<script>
// 暴露
// 有三种暴露方式,下面的额是默认方式
// 不同的暴露方式导入方式也有所不同
export default ({
name: 'test1',
data() {
return {
name: ' xiaoming',
age: 20
}
},
methods: {
showName() {
alert(this.name)
}
}
})
</script>
<style>
.demo {
background-color: blueviolet;
}
</style>
<!-- --------------------------------------------------------------- -->
<!-- App.vue -->
<template>
<div class="demo1">
<test1></test1>
</div>
</template>
<script>
import test1 from './test1.vue'
export default ({
name: 'App',
components: {
test1
}
})
</script>
<!-- --------------------------------------------------------------- -->
<!-- main.js -->
import App from './App.vue'
new Vue ({
el:'#root',
components:{App}
})
2.2 Vue 大屏数据展示组件库 dataV
2.2.1 CSS
中的flex
布局
大屏可视化的一个重点就是 页面布局 ,此次基于dataV的大屏可视化项目就是采用
flex
对页面进行的整体布局
布局的传统解决方案,基于盒状模型,依赖display
属性+position
属性+float
属性。
2009年,W3C提出了一种新的方案—flex
布局,可以简便、完整、响应式地实现各种页面布局。
flex
是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。
- 任何一个容器都可以指定为
flex
布局:display: flex;
- 行内元素也可以使用Flex布局:
display: inline-flex;
参考文档
2.2.2 flex容器的6个属性
(1) flex-direction
.box {
flex-direction: row | row-reverse | column | column-reverse;
}
/* 它可能有4个值。*/
/* row(默认值):主轴为水平方向,起点在左端。 */
/* row-reverse:主轴为水平方向,起点在右端。 */
/* column:主轴为垂直方向,起点在上沿。 */
/* column-reverse:主轴为垂直方向,起点在下沿。 */
(2) flex-wrap
默认情况下,项目都排在一条线(又称”轴线”)上。
flex-wrap
属性定义,如果一条轴线排不下,如何换行。
.box {
flex-wrap: nowrap | wrap | wrap-reverse;
}
/* 它可能取三个值。 */
/* (1)nowrap(默认):不换行。 */
/* (2)wrap:换行,第一行在上方。 */
/* (3)wrap-reverse:换行,第一行在下方。 */
(3) flex-flow
.box {
flex-flow: <flex-direction> <flex-wrap>;
}
/* flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。 */
(4) justify-content
justify-content
属性定义了项目在主轴上的对齐方式。
.box {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
/* 它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。 */
/* flex-start(默认值):左对齐 */
/* flex-end:右对齐 */
/* center: 居中 */
/* space-between:两端对齐,项目之间的间隔都相等。 */
/* space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。 */
(5) align-items
align-items
属性定义项目在交叉轴上如何对齐。
.box {
align-items: flex-start | flex-end | center | baseline | stretch;
}
/* 它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。 */
/* flex-start:交叉轴的起点对齐。 */
/* flex-end:交叉轴的终点对齐。 */
/* center:交叉轴的中点对齐。 */
/* baseline: 项目的第一行文字的基线对齐。 */
/* stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。 */
(6) align-content
align-content
属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
.box {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
/* 该属性可能取6个值。 */
/* flex-start:与交叉轴的起点对齐。 */
/* flex-end:与交叉轴的终点对齐。 */
/* center:与交叉轴的中点对齐。 */
/* space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。 */
/* space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。 */
/* stretch(默认值):轴线占满整个交叉轴。 */
2.2.3 flex
项目上的6个属性
也就是说在具体应用时,有下面6个属性
order
、flex-grow
、flex-shrink
、flex-basis
、flex
、align-self
.item {
order: <integer>;
}
/* order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。 */
.item {
flex-grow: <number>; /* default 0 */
}
/* flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。 */
/* 如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。 */
/* 如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。 */
.item {
flex-shrink: <number>; /* default 1 */
}
/* flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。 */
/* 如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。 */
/* 如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。 */
/* 负值对该属性无效。 */
.item {
flex-basis: <length> | auto; /* default auto */
}
/* flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。 */
/* 浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。 */
/* 它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。 */
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
/* flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。 */
/* 该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。 */
/* 建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。 */
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
/* align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。 */
/* 默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。 */
/* 该属性可能取6个值,除了auto,其他都与align-items属性完全一致。 */
2.2.4 flex
布局在本项目中的应用
注意点:
- 使用百分比的形式设置特定参数的值
flex
容器的无法实现多层嵌套,要实现多层嵌套需要设置盒子模型为flex
容器(不太好理解,可以看下面class="middle"
中的代码)- dataV 边框样式官方参考文档
<!-- .top {
width: 100%;
height: 6%;
margin-top: 10px;
display: flex;
/* 两端对齐 */
justify-content: space-between;
} -->
<div id="root">
<dv-full-screen-container>
<div class="top">
<!--
style="flex:0 1 30%"
这是一个CSS的样式属性,表示一个元素的伸缩性,具体解释如下:
flex-grow: 0:该元素不会被拉伸。
flex-shrink: 1:该元素可以被收缩。
flex-basis: 30%:该元素的初始大小为其父容器的30%。
综合起来,这个样式属性的作用是,将该元素的初始大小设置为其父容器宽度的30%,
同时如果该元素在布局时需要被收缩,它会尽可能地收缩以适应父容器的大小。
-->
<div style="flex:0 1 30%">
<dv-decoration-8 style="width:100%;height:50%;" />
</div>
<!--
margin(外边距)是指元素周围的空白区域,用于控制元素与其他元素之间的距离。
margin的使用方式如下:
margin: 上 右 下 左;
上、右、下、左指定了元素的四个方向上的外边距,可以用长度值(如px、em等)或百分比来指定。
设置元素的上下外边距和左右外边距:
margin: 上下 左右;
分别设置元素的四个方向上的外边距:
margin-top: 上;
margin-right: 右;
margin-bottom: 下;
margin-left: 左;
-->
<div style="flex:0 1 40%; margin-top: 20px;">
<dv-decoration-5 style="width:100%;height:100%;" />
</div>
<div style="flex:0 1 30%">
<dv-decoration-8 :reverse="true" style="width:100%;height:50%;" />
</div>
<div class="center-title">
额河数据可视化平台
</div>
</div>
<!-- .middle {
width: 100%;
height: 90%;
margin-top: 10px;
display: flex;
flex-direction: row;
/* 居中对齐 */
justify-content: space-between;
} -->
<div class="middle">
<div style="flex:0 1 25%;">
<dv-border-box-3 style="width: 100%; height: 100%;">
dv-border-box-3
</dv-border-box-3>
</div>
<div style="flex:0 1 75%; display: flex; flex-direction: column;">
<div style="flex:0 1 65%; display: flex; flex-direction: row;">
<div style="flex:0 1 65%;">
<dv-border-box-3 style="width: 100%; height: 100%;">
dv-border-box-3
</dv-border-box-3>
</div>
<div style="flex:0 1 35%; display: flex; flex-direction: column;">
<div style="flex:0 1 50%">
<dv-border-box-3 style="width: 100%; height: 100%;">
dv-border-box-3
</dv-border-box-3>
</div>
<div style="flex:0 1 50%">
<dv-border-box-4 :reverse="true" style="width: 100%; height: 100%;">
dv-border-box-4
</dv-border-box-4>
</div>
</div>
</div>
<div style="flex:0 1 35%;">
<dv-border-box-4 style="width: 100%; height: 100%;">
dv-border-box-4
</dv-border-box-4>
</div>
</div>
</div>
</dv-full-screen-container>
</div>
下面是布局后的效果图:
dataV中的飞线图
原理与相关说明:
- 背景是一张图片,飞线的起点和终点是图片中的相对坐标(默认)
- 组件提供了dev模式 ,可以帮助快速确定飞线点位置
- 官方参考文档
dataV中的图表
官方:图表组件基于 Charts 封装,其也提供了许多常用的图表样式,用法和 echarts 差不多,但是在访问其js文件时,出现了404错误。。。所以还是使用 echarts 吧
官方链接
3. dataV结合Echarts的使用
echarts官网
echarts官方文档
echarts的js文件
3.1 vue项目中或者TS
环境下的使用
由于本次项目并没有在此环境下进行开发,所以不做介绍,官方文档 写的很清楚。
3.2 在原生js环境下的使用
需要注意的一点就是,echarts 的 js 需要在 vue 实例构建完成之后,也就是说,其要放在 vue 实例构建 之后,否则可能会导致渲染失败。
<!-- 这里的尺寸之所以采用百分比的形式来表示
是因为其在一个 flex 容器下设置的 echarts 图表
可以使用 px -->
<div id="main" style="width: 100%;height:100%;"></div>
<div id="main1" style="width: 50%;height:100%;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'), 'dark');
var myChart1 = echarts.init(document.getElementById('main1'), 'dark');
// 指定图表的配置项和数据
var option = {
backgroundColor: '',
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20],
}
]
};
var option1 = {
backgroundColor: '',
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'center'
},
series: [
{
name: 'Access From',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: 40,
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: [
{ value: 1048, name: 'Search Engine' },
{ value: 735, name: 'Direct' },
{ value: 580, name: 'Email' },
{ value: 484, name: 'Union Ads' },
{ value: 300, name: 'Video Ads' }
]
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
myChart1.setOption(option1);
</script>
效果如下图黄色圈起来的部分
3.3 使用vue非单页面组件的方式使用
<!-- 一般情况下 应该给组件一个盒子或者容器 -->
<div style="width: 25%;height:90%;">
<test></test>
</div>
<script>
const test = Vue.extend({
template: `
<div id="main3" style="width: 100%;height:100%;"></div>
`,
// data 应以函数的形式返回值
data() {
return {
option: {
backgroundColor: '',
title: {
text: 'Nightingale Chart',
subtext: 'Fake Data',
left: 'center'
},
series: [
{
name: 'Area Mode',
type: 'pie',
radius: [20, 140],
center: ['50%', '50%'],
roseType: 'area',
itemStyle: {
borderRadius: 5
},
data: [
{ value: 30, name: 'rose 1' },
{ value: 28, name: 'rose 2' },
{ value: 26, name: 'rose 3' },
{ value: 24, name: 'rose 4' },
{ value: 22, name: 'rose 5' },
{ value: 20, name: 'rose 6' },
{ value: 18, name: 'rose 7' },
{ value: 16, name: 'rose 8' }
]
}
]
}
}
},
mounted() {
// 在生命周期中挂载图表
var myChart = echarts.init(document.getElementById('main3'), 'dark');
myChart.setOption(this.option)
}
})
var vm = new Vue({
el: '#root',
// 注册组件
components: {
test,
}
})
</script>