=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 。
`