基于vue、vuex、vue-router、echarts搭建的数据展示平台

16

真的好久没有更新博客了,但是我最近并没有偷懒哦,一直在学习vue这个框架,并且用它做了一个小项目,现在就给大家分享一下我的这个还比较有意思的小项目咯,本项目是基于vue2.0开发的。

灵感来源

这是一个数据可视化相关的项目,作为一个学生班主任,需要对班上同学的各方面的情况都有所了解,于是我便做了一个问卷调查来了解学生各方面的情况。然后我又想到可以分析我们班的群聊记录呀,根据群聊记录可以得到班上同学之间的亲密度和班级群聊活跃度等信息。自然而然,我就想着可以搭建一个平台来展示这些数据,既然是数据当然是以图表的方式来展示更加直观,然后折中选择了echarts这个图标库。至于为什么要选择用vue这个插件,之前只是觉得学了vue可以练练手,做完之后发现vue真的很轻量也很好上手,结合vuex和vue-router基本能完成我项目中的所有需求。

在线展示:http://119.29.57.165:8080/family
源码:https://github.com/hieeyh/tong2-family
本教程是基于你已经有一定vue基础之上的,如果你还不了解什么是vue建议先去学习一下

项目初始构建

首先全局安装vue-cli,vue-cli是vue自己的项目构建工具,几个简单的步骤就可以帮助你快速构建一个vue项目。

npm install -g vue-cli

然后,利用vue-cli构建一个vue项目

# 创建一个基于 "webpack" 模板的新项目
$ vue init webpack family
# 安装依赖
$ cd family
$ npm install

项目文件解释

  • build中是webpack基本配置文件,开发环境配置文件,生产环节配置文件

  • node_modules是各种依赖模块

  • src中是vue组件及入口文件

  • static中放置静态文件

  • index.html是页面入口文件

基本页面实现

项目创建好之后,就开始实现自己想要的页面了,修改src文件夹下的App.vue文件,如下:

<template>
<div id="#app">
<!-- 导航栏 -->
  <my-head></my-head>
  <my-nav></my-nav>
  <transition>
    <router-view></router-view>
  </transition>
  <my-foot></my-foot>
</div>
</template>

<script>
import myHead from './components/header'
import myNav from './components/nav'
import myFoot from './components/foot'

export default {
  name: 'app',
  components: {
    myHead,
    myNav,
    myFoot
  }
}
</script>

myHead组件是页面头部,myNav组件是页面左侧导航栏,myFoot是页面底部,router-view组件是vue-router中渲染路径匹配到的视图组件。每个组件的具体实现可以去github项目地址去看源码。

创建配置路由

显然,我要做的是一个单页面应用,要用到vue-router,先安装vue-router,输入如下命令:

npm install --save vue-router

然后,在src文件夹下面的main.js文件中添加路由相关的代码,如下:

import Vue from 'vue'
import App from './App'
import VueRouter from 'vue-router'

Vue.use(VueRouter) 
// 定义路由组件
const Worldcloud = require('./components/cloud.vue')
const Building = require('./components/building.vue')
const Canteen = require('./components/canteen.vue')
const Selfstudy = require('./components/selfstudy.vue')
const Difficult = require('./components/difficult.vue')
const Interest = require('./components/interest.vue')
const Bedroom = require('./components/bedroom.vue')
const Graduate = require('./components/graduate.vue')
const Getup = require('./components/getup.vue')
const Gotobed = require('./components/gotobed.vue')
const Eat = require('./components/eat.vue')
const Amuse = require('./components/amuse.vue')
const Single = require('./components/single.vue')
const Chat = require('./components/chat.vue')
const Onlyme = require('./components/onlyme.vue')

// 定义路由,配置路由映射
const routes = [
  { path: '/', redirect: '/wordcloud' },
  { path: '/wordcloud', component: Worldcloud },
  { path: '/building', component: Building },
  { path: '/canteen', component: Canteen },
  { path: '/selfstudy', component: Selfstudy },
  { path: '/difficult', component: Difficult },
  { path: '/interest', component: Interest },
  { path: '/bedroom', component: Bedroom },
  { path: '/graduate', component: Graduate },
  { path: '/getup', component: Getup },
  { path: '/gotobed', component: Gotobed },
  { path: '/eat', component: Eat },
  { path: '/amuse', component: Amuse },
  { path: '/single', component: Single },
  { path: '/chat', component: Chat },
  { path: '/onlyme', component: Onlyme }
]

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App },
  router
})

从路由映射的配置中可以看出,访问网站的根路由会直接跳转到/wordcloud。路由映射的组件中用到了百度的echarts库,这是一个很好用的图表库。

怎么画图

怎么用echarts画图呢?其实官网上有很多实例,下面以bedroom.vue组件为例来简单说明,bedroom.vue代码如下:

<template>
  <div class="main_content">
    <div id="bedroom"></div>
  </div>
</template>
<script>
  import echarts from 'echarts'
  export default {
    data() {
      return {
        chart: null,
        opinion: ['学习氛围差', '学习氛围一般', '学习氛围很好'],
        opinionData: [
          {value:26, name:'学习氛围差'},
          {value:31, name:'学习氛围一般'},
          {value:8, name:'学习氛围很好'}
        ]
      }
    },
    methods: {
      drawPie (id) {
        this.chart = echarts.init(document.getElementById(id))
        this.chart.setOption({
          title: {
            text: '寝室学习氛围情况调查',
            left: 'center',
            top: 10,
            textStyle: {
              fontSize: 24,
              fontFamily: 'Helvetica',
              fontWeight: 400
            }
          },
          tooltip: {
            trigger: 'item',
            formatte: "{b}: {c} ({d}%)"
          },
          toolbox: {
            feature: {
              saveAsImage: {},
              dataView: {}
            },
            right: 15,
            top: 10
          },
          legend: {
              orient: 'vertical',
              left: 5,
              top: 10,
              data: this.opinion,
          },
          series: [
            {
              name: '寝室学习氛围',
              type: 'pie',
              radius: ['50%', '70%'],
              center: ['50%', '60%'],
              avoidLabelOverlap: false,
              label: {
                emphasis: {
                  show: true,
                  textStyle: {
                    fontSize: '24',
                    fontWeight: 'bold'
                  }
                }
              },
              labelLine: {
                normal: {
                  show: false
                }
              },
              data: this.opinionData,
              itemStyle: {
                emphasis: {
                  shadowBlur: 10,
                  shadowOffset: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
              }
            }
          ]
        })
      }
    },
    mounted() {
      this.$nextTick(function() {
        this.drawPie('bedroom')
      })
    }
  }
</script>
<style scoped>
#bedroom {
  position: relative;
  left: 50%;
  margin-left: -400px;
  margin-bottom: 70px;
  width: 800px;
  height: 600px;
  border: solid #D01257 1px;
  box-shadow: 0 0 8px #FB90B7;
  border-radius: 10px;
}   
</style>

这是一个vue的单文件组件,script中,首先导入echarts库,前提是已经安装了echarts库,输入以下命令安装:

npm install --save echarts

data对象中是画图要用到的一些数据,drawpie方法用来画图,接收一个DOM对象,然后在mounted构子函数中调用drawpie即可。

两点说明

  1. drawpie方法接收的DOM对象需要有确定的宽高,否则图像不显示

  2. mounted中要包含vm.$nextTick才能保证该实例已经插入文档

实现登录功能

登录功能基于vuex(vue状态管理)和浏览器的sessionStorage实现的。首先在src文件夹下新建store文件夹,存放vuex的store(仓库),新建三个文件store.js、login.js、user.js。login.js中存储登录状态,user.js中存储用户登录信息,store.js加载login和user模块。

注意:在store.js中要引入babel-polyfill(先安装),否则会报错,报错原因是Babel默认只转换新的JavaScript句法,而不转换新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法都不会转码。所以必须使用babel-polyfill,为当前环境提供一个垫片。

然后修改main.js文件,引入store:

import store from './store/store'
...
...
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App },
  router,
  store
})

修改App.vue文件,如下:

<template>
<div id="#app">
<!-- 导航栏 -->
  <my-head></my-head>
  <my-nav></my-nav>
  <transition>
    <router-view></router-view>
  </transition>
  <my-mask v-if="canlogin"></my-mask>
  <my-login v-if="canlogin"></my-login>
  <my-foot></my-foot>
</div>
</template>
<script>
...
import myMask from './components/mask'
import myLogin from './components/login'

export default {
  ...
  data() {
    return {
      canlogin: false
    }
  },
  computed: {
    canlogin() {
      return this.$store.state.login.islogin
    }
  }
}
</script>

到此,就基本上大功告成了,在命令行中输入 npm run dev预览一下。

项目发布

项目可以在本地预览了,但是要怎么发布到网上呢?首先,在命令行中输入

npm run build

会生成一个dist文件夹,该文件夹中就是我们可以用来发布的代码,直接将代码上传到你的服务器上就可以啦。

你可能感兴趣的

25 条评论
andrew998 · 2016年11月21日

打开网站发现是母校地图,厉害了学妹!

回复

hieeyh 作者 · 2016年11月21日

嘻嘻,母校现在变化很大哦

回复

andrew998 · 2016年11月21日

从你的统计数据可以看出来,东园食堂火了,学二没落了,哈哈!

回复

hieeyh 作者 · 2016年11月21日

哈哈,我四年基本都在东园吃的,现在读研不住东边了好怀恋

回复

前端小白de窝 · 2016年12月08日

楼主,你的博客是怎么做的?和阮大神的好像,怎么弄的?

回复

hieeyh 作者 · 2016年12月12日

github+hexo 博客上有教程

回复

前端小白de窝 · 2016年12月15日

题主,看了你的代码,有个问题,我在写组件的时候该怎么调样式?或者说该怎么整合最后生成的整体页面的样式?第二个问题就是,在app.vue文件中的style内容,里面的类名是直接定义app.vue中的类名里的样式呢,还是怎么定义?

回复

前端小白de窝 · 2016年12月15日

还有就是,我怎么才能知道我的组件是不是正确加载了?或者说我开发的流程应该怎么弄?是一个组件写完,就run dev看一下呢,还是全部都写完,再来统一起来看效果?3Q~~~

回复

前端小白de窝 · 2016年12月15日

抱歉,还有一个问题就是,为什么你的项目里没有webpack.config.js文件?不是用cli工具生成的吗?

回复

前端小白de窝 · 2016年12月15日

去你的博客上留了个言,就是我在安装完依赖之后,run dev的时候报错了,错误是:
ERROR in ./~/.6.2.9@babel -loader/lib!./~/.9.9.5@vue-loader/lib/selector.js?type=script&index=0!./src/components/onlyme.vue
Module not found: Error: Cannot resolve 'file' or 'directory' D:download数据展示平台static/data/index2QQ_id.json in D:download数据展示平台srccomponents
@ ./~/.6.2.9@babel -loader/lib!./~/.9.9.5@vue-loader/lib/selector.js?type=script&index=0!./src/components/onlyme.vue 11:19-58

我不知道是什么原因,打开Localhost也是一片空白。console里也没有报错,一片空白。你知道怎么解决吗?3Q

回复

hieeyh 作者 · 2016年12月15日

因为缺少这个index2QQ_id.json文件,这个文件比较私密,我之后再上传一个吧。

回复

hieeyh 作者 · 2016年12月15日

webpack相关文件都在build文件夹里,都是自动生成的

回复

hieeyh 作者 · 2016年12月20日

文件已上传,还有错的话请贴出你报的错

回复

devincob · 2016年12月20日

@艰苦奋斗的侯小憨 我怎么给你贴图呢?这里好像不能传图片,从你的github上clone的代码,可是看你的github上并没有修改内容

回复

hieeyh 作者 · 2016年12月20日

复制粘贴吧,我github有传文件上去

回复

devincob · 2016年12月20日

@艰苦奋斗的侯小憨 我能加你QQ,贴图给你吗,Q:570322709

回复

Alexee · 2017年02月09日

实现登录功能那里,

data() {
    return {
      canlogin: false
    }
},
computed: {
    canlogin() {
      return this.$store.state.login.islogin
    }
}

既然要使用计算属性了,为啥 data 那里还需要 return { canlogin: false} 呢?

回复

0

默认是不登录的状态

KI_WI · 2017年09月27日
0

data里和计算属性里面不能重复定义吧

Alexee · 2017年09月28日
itfanr · 2017年03月21日

学习了 正需要呢

回复

assassin_cike · 2017年06月16日

你有没有发现不断切换左侧的他tab内存会不断的增长,居高不下,最后就爆了

回复

0

还真是

我叫罗小黑 · 2017年07月07日
yqx_cn · 2017年11月27日

想请教下为啥按照你项目写的方式引入百度地图会失败?

回复

载入中...