=Start=
缘由:
自己毕竟不是专门做前端/UI的,所以在页面布局以及样式上面没有那么专业,但爱美之心人皆有之,我也想做出一些好看的页面,用的时候感觉也会好些。这时,就需要借助一些UI框架以及图表工具了,对应的比较流行的就是ElementUI和Echarts了,这里简单介绍一下它们在Vue2的项目中该如何引入和使用,方便以后参考。
正文:
参考解答:
一、Vue2.0 项目中怎样添加 ElementUI 和 Echarts
方法一:直接在 package.json 文件里面的 dependencies 里配置
"echarts": "^4.1.0", "element-ui": "^2.0.0-rc.1",
然后再执行 npm install 命令。
方法二:直接执行命令
# -D选项的使用是为了将安装的依赖写入 package.json 文件,方便移植 npm install element-ui --save -D npm install echarts --save -D
二、Vue2.0 项目中如何使用 ElementUI 和 Echarts
2.1 elemnt-ui 只需在 main.js 里添加
// 引入 import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' // 使用 Vue.use(ElementUI)
2.2 对于用到 echarts 的页面,哪个页面用到就在哪个.vue文件中添加
var echarts = require('echarts');
补充:.vue 文件结构介绍
<template>
<div id="hello1">
<p>欢迎信息:{{ msg }}</p>
<el-button>默认按钮</el-button>
<el-button type="primary" @click="test">主要按钮(变换欢迎信息)</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</div>
</template>
<script type="text/javascript">
export default {
name: 'hello1',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
methods: {
test () {
this.msg = "hello world"
}
}
}
</script>
<style>
</style>
三、简单样例
ElementUI样例
<template>
<div id="matchlog">
<el-form :inline="true" :model="formInline" class="demo-form-inline" style="margin: 15px">
<el-form-item label="审批人">
<el-input v-model="formInline.user" placeholder="审批人"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="formInline.region" placeholder="活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
<el-table ref="multipleTable" :data="tableData" tooltip-effect="dark" style="width: 80%"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55">
</el-table-column>
<el-table-column label="日期" width="120" sortable>
<template slot-scope="scope">{{ scope.row.date }}</template>
</el-table-column>
<el-table-column prop="name" label="姓名" width="120" sortable>
</el-table-column>
<el-table-column prop="address" label="地址" show-overflow-tooltip sortable>
</el-table-column>
</el-table>
</div>
</template>
<script type="text/javascript">
export default {
data() {
return {
formInline: {
user: '',
region: ''
},
tableData: [{
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-08',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-06',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-07',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}],
multipleSelection: [],
}
},
methods: {
onSubmit() {
console.log('submit!');
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
}
}
</script>
<style>
</style>
Echarts样例
<template>
<div id="entry">
<div>
<div id="echart_etl_stat" style="height: 400px; width: 100%;"></div>
</div>
<div>
<div id="echart_storm_stat" style="height: 400px; width: 100%;"></div>
</div>
</div>
</template>
<script type="text/javascript">
var echarts = require('echarts');
function fetchData(cb) {
// 通过 setTimeout 模拟异步加载
setTimeout(function() {
cb({
categories: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"],
data: [5, 20, 36, 10, 10, 20]
});
}, 3000);
}
export default {
data () {
return {
message: "样例"
}
},
mounted: function() {
this.init_echarts();
},
methods: {
init_echarts () {
// 基于准备好的dom,初始化echarts实例
var echart_etl_stat = echarts.init(document.getElementById('echart_etl_stat'));
// 设置option
var echart_etl_stat_option = {
title: {
text: '已接入Topic日志量统计'
},
tooltip: {
trigger: 'axis'
},
legend: {
data:['category1', 'category2', 'category3', 'category4', ]
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: { // 右上角的小工具栏
// show : true,
// feature : {
// // mark : {show: true},
// dataView : {show: true, readOnly: true},
// magicType : {show: true, type: ['line', 'bar', 'stack', 'tiled']},
// restore : {show: true},
// saveAsImage : {show: true}
// }
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月']
},
yAxis: {
type: 'value'
},
series: [
{name: 'category1', type: 'line', data: [0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0]},
{name: 'category2', type: 'line', data: [0, 0, 3, 1, 0, 0, 0, 5, 0, 0, 0, 0]},
{name: 'category3', type: 'line', data: [0, 1, 2, 0, 3, 0, 2, 0, 0, 4, 0, 0]},
{name: 'category4', type: 'line', data: [0, 0, 5, 0, 0, 5, 0, 0, 6, 0, 4, 0]},
]
};
// 绘制图表
echart_etl_stat.setOption(echart_etl_stat_option);
var echart_storm_stat = echarts.init(document.getElementById('echart_storm_stat'));
var echart_storm_stat_option = {
title: {
text: 'Storm处理量统计'
},
tooltip: {},
legend: {
data:['销量']
},
xAxis: {
data: []
},
yAxis: {},
series: [{
name: '销量',
data: [],
type: 'bar',
}]
};
echart_storm_stat.setOption(echart_storm_stat_option); // 必不可少,否则会报错
echart_storm_stat.showLoading();
fetchData(function (data) {
echart_storm_stat.hideLoading();
echart_storm_stat.setOption({
xAxis: {
// data: data.categories,
data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"],
},
series: [{
// 根据名字对应到相应的系列
name: '销量',
// data: data.data,
data: [5, 20, 36, 10, 10, 20],
type: 'bar',
}]
});
});
}
},
}
</script>
<style>
</style>
四、一些注意事项
需要注意的是:Echarts对应的DOM容器必须要指定宽高,否则Echarts无法渲染dom !!!
错误:
Uncaught TypeError: Cannot read property ‘getAttribute’ of null
参考:
这个错误的发生是因为当方法被调用的时候这个HTML元素的对象还没有加载进去,所以你需要把这个报错的方法用在DOM对象加载之后。
或则你把js文件的调用放在body的最后,就是俗称的网页底部,在确定对应的HTML元素被加载之后再运行。
在 Vue2.0 里面一般就是放在 mounted 里面,然后整个网页就恢复正常了。
- 【Echarts】Uncaught TypeError: Cannot read property ‘getAttribute’ of null报错
- https://stackoverflow.com/questions/32542312/uncaught-typeerror-cannot-read-property-getattribute-of-null
- https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA
- https://cn.vuejs.org/v2/api/#mounted
错误:
Uncaught Error: series.type should be specified.
参考:
https://segmentfault.com/q/1010000012411869
错误:
Uncaught TypeError: Cannot read property ‘get’ of undefined
参考:
echart_obj.setOption(echart_obj_option);
即便是 空option 也需要先 setOption 之后再 setOption 其它的部分(当echarts的两个option存在不同的参数的时候),否则会报错。
参考链接:
- 如何在vue2.0项目中引用element-ui和echart.js
- vue2+elementUI HelloWorld
- Vue2+Echarts实现多种图表数据可视化Dashboard详解(附源码)
- 关于Vue实例的生命周期created和mounted的区别
- 实例生命周期钩子
=END=
《 “在Vue2项目中使用ElementUI和Echarts” 》 有 13 条评论
Vue 爬坑之路(三)—— 使用 vue-router 跳转页面
https://www.cnblogs.com/wisewrong/p/6277262.html
Vue + ElementUI 手撸后台管理网站基本框架(一)创建项目
https://blog.csdn.net/harsima/article/details/77949623
Vue + ElementUI 手撸后台管理网站基本框架(二)权限控制
https://blog.csdn.net/harsima/article/details/77949448
Vue核心思想:数据驱动、组件化
https://juejin.im/post/5b3a067c51882551c7026d5f
vue-router 按需加载
https://www.cnblogs.com/xiaochongchong/p/7772773.html
vue中的懒加载和按需加载 # 可以work
https://blog.csdn.net/qq_30227429/article/details/75246433
在vue-cli搭建的项目中使用mockjs
https://segmentfault.com/a/1190000010592626
http://mockjs.com/0.1/
vue+mockjs 模拟数据,实现前后端分离开发
https://www.cnblogs.com/jasonwang2y60/p/7302449.html
【Vue】5.vue mock数据(模拟后台)
https://blog.csdn.net/benben513624/article/details/78562529
vue-cli 本地开发mock数据使用方法
https://www.jianshu.com/p/ccd53488a61b
vue 的 DatePicker 和 Echarts 联动
https://segmentfault.com/q/1010000010504226
`
直接用watch监控数据的变化,变化了就执行你的method。
可以在 method 里面设置一个 get/post 请求,动态更新 Echarts 要展示的数据,即可实现联动。
`
关于ElementsUi 日期选择器 DatePicker 使用小心得 #测试也可以
https://blog.csdn.net/lyz571029230/article/details/77987835
`
logTimeChange(val) {
console.log(val)
}
`
开箱即用的 Vue Webpack 脚手架模版
https://jeffjade.com/2018/05/20/140-vue-webpack-boilerplate-template/
https://github.com/nicejade/vue-boilerplate-template
http://echarts.baidu.com/examples/#chart-type-bar
http://echarts.baidu.com/examples/editor.html?c=bar-label-rotation
http://echarts.baidu.com/echarts2/doc/example.html
http://echarts.baidu.com/echarts2/doc/example/bar1.html
5 分钟上手 ECharts
http://echarts.baidu.com/tutorial.html#5%20%E5%88%86%E9%92%9F%E4%B8%8A%E6%89%8B%20ECharts
前后端分离开发风险浅析
http://pirogue.org/2018/12/17/SPA/
`
3. 越权漏洞的发生
3.1 参数归属校验缺失
3.2 直接请求后端接口
3.3 前端框架引入的风险
4. 解决方案
4.1 前端后端一起鉴权,Node层校验登录态,后端校验登录态,同时后端校验数据归属;
4.2 Vue-router使用“mode: history”模式,前后端一起配合鉴权。
`
Vue-router 中hash模式和history模式的区别
https://www.jb51.net/article/144341.htm
Web 前后端分离的意义大吗?
https://www.zhihu.com/question/28207685
我们为什么要尝试前后端分离
https://segmentfault.com/a/1190000006240370
`
尝试与改变
现状与分歧
场景与要求
优势与意义
心得与体会
`
前后端分离的思考与实践(一)
http://taobaofed.org/blog/2014/04/05/practice-of-separation-of-front-end-from-back-end/
你不得不了解的前后端分离原理!
https://juejin.im/post/5b71302351882560ea4afbb8
实践中的前后端分离
https://juejin.im/post/59dad63ff265da065270d49e
网易前后端分离实践
https://github.com/genify/ita1024/blob/master/%E7%BD%91%E6%98%93%E5%89%8D%E5%90%8E%E7%AB%AF%E5%88%86%E7%A6%BB%E5%AE%9E%E8%B7%B5.md
保护你的API(上)
http://abruzzi.github.com/2016/05/about-session-and-security-api-1/
`
在大部分时候,我们讨论API的设计时,会从功能的角度出发定义出完善的,易用的API。而很多时候,非功能需求如安全需求则会在很晚才加入考虑。而往往这部分会涉及很多额外的工作量,比如与外部的SSO集成,Token机制等等。
这篇文章会以一个简单的例子,从应用程序和部署架构上分别讨论几种常见的模型。这篇文章是这个系列的第一篇,会讨论两个简单的主题:
基于Session的用户认证
基于Token的RESTful API(使用Spring Security)
==
前后端分离之后
前后端分离之后,在部署上通过一个反向代理就可以实现动静态分离,跨域问题的解决等。但是一旦引入鉴权,则又会产生新的问题。通常来说,鉴权是对于后台API/API背后的资源的保护,即未经授权的用户不能访问受保护资源。
要实现这个功能有很多种方式,在应用程序之外设置完善的安全拦截器是最常见的方式。不过有点不够优雅的是,一些不太纯粹的、非功能性的代码和业务代码混在同一个代码库中。
另一方面,各个业务系统都可能需要某种机制的鉴权,所以很多企业都会搭建SSO机制,即Single Sign-On。这样可以避免人们在多个系统创建不同账号,设置不同密码,不同的超时时间等等。如果SSO系统已经先于系统存在了很久,那么新开发的系统完全不需要自己再配置一套用户管理机制了(一般SSO只会完成鉴权中鉴别的部分,授权还是需要各个业务系统自行处理)。
本文中,我们使用基础设施(反向代理)的一些配置,来完成保护未授权资源的目的。
`
保护你的API(下)
http://abruzzi.github.com/2016/05/about-session-and-security-api-2/
Echarts 雷达图
https://echarts.baidu.com/echarts2/doc/example.html
https://echarts.baidu.com/echarts2/doc/example/radar2.html#blue
echarts之title-textAlign
https://blog.csdn.net/huanbia/article/details/50394515
Dialog 对话框 – 在保留当前页面状态的情况下,告知用户并承载相关操作。
https://element.eleme.cn/#/zh-CN/component/dialog
element-ui el-table表格排序sortable参数解析
https://www.cnblogs.com/steamed-twisted-roll/p/11069821.html
`
如果需要对表格的那一列进行排序,加一个sortable参数,可取的值有 true,false,custom 。
`