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的实例对象)中的 thisdata函数、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 中使用 Bcomponents: {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>