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>
复制