真的好久沒(méi)有更新博客了,但是我最近并沒(méi)有偷懶哦,一直在學(xué)習(xí)vue這個(gè)框架,并且用它做了一個(gè)小項(xiàng)目,現(xiàn)在就給大家分享一下我的這個(gè)還比較有意思的小項(xiàng)目咯,本項(xiàng)目是基于vue2.0開(kāi)發(fā)的。
靈感來(lái)源
這是一個(gè)數(shù)據(jù)可視化相關(guān)的項(xiàng)目,作為一個(gè)學(xué)生班主任,需要對(duì)班上同學(xué)的各方面的情況都有所了解,于是我便做了一個(gè)問(wèn)卷調(diào)查來(lái)了解學(xué)生各方面的情況。然后我又想到可以分析我們班的群聊記錄呀,根據(jù)群聊記錄可以得到班上同學(xué)之間的親密度和班級(jí)群聊活躍度等信息。自然而然,我就想著可以搭建一個(gè)平臺(tái)來(lái)展示這些數(shù)據(jù),既然是數(shù)據(jù)當(dāng)然是以圖表的方式來(lái)展示更加直觀,然后折中選擇了echarts這個(gè)圖標(biāo)庫(kù)。至于為什么要選擇用vue這個(gè)插件,之前只是覺(jué)得學(xué)了vue可以練練手,做完之后發(fā)現(xiàn)vue真的很輕量也很好上手,結(jié)合vuex和vue-router基本能完成我項(xiàng)目中的所有需求。
在線展示:http://119.29.57.165:8080/family
源碼:https://github.com/hieeyh/tong2-family
本教程是基于你已經(jīng)有一定vue基礎(chǔ)之上的,如果你還不了解什么是vue建議先去學(xué)習(xí)一下
項(xiàng)目初始構(gòu)建
首先全局安裝vue-cli,vue-cli是vue自己的項(xiàng)目構(gòu)建工具,幾個(gè)簡(jiǎn)單的步驟就可以幫助你快速構(gòu)建一個(gè)vue項(xiàng)目。
npm install -g vue-cli
然后,利用vue-cli構(gòu)建一個(gè)vue項(xiàng)目
# 創(chuàng)建一個(gè)基于 "webpack" 模板的新項(xiàng)目
$ vue init webpack family
# 安裝依賴
$ cd family
$ npm install
項(xiàng)目文件解釋
- build中是webpack基本配置文件,開(kāi)發(fā)環(huán)境配置文件,生產(chǎn)環(huán)節(jié)配置文件
- node_modules是各種依賴模塊
- src中是vue組件及入口文件
- static中放置靜態(tài)文件
- index.html是頁(yè)面入口文件
基本頁(yè)面實(shí)現(xiàn)
項(xiàng)目創(chuàng)建好之后,就開(kāi)始實(shí)現(xiàn)自己想要的頁(yè)面了,修改src文件夾下的App.vue文件,如下:
<template>
<div id="#app">
<!-- 導(dǎo)航欄 -->
<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組件是頁(yè)面頭部,myNav組件是頁(yè)面左側(cè)導(dǎo)航欄,myFoot是頁(yè)面底部,router-view組件是vue-router中渲染路徑匹配到的視圖組件。每個(gè)組件的具體實(shí)現(xiàn)可以去github項(xiàng)目地址去看源碼。
創(chuàng)建配置路由
顯然,我要做的是一個(gè)單頁(yè)面應(yīng)用,要用到vue-router,先安裝vue-router,輸入如下命令:
npm install --save vue-router
然后,在src文件夾下面的main.js文件中添加路由相關(guān)的代碼,如下:
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
})
從路由映射的配置中可以看出,訪問(wèn)網(wǎng)站的根路由會(huì)直接跳轉(zhuǎn)到/wordcloud。路由映射的組件中用到了百度的echarts庫(kù),這是一個(gè)很好用的圖表庫(kù)。
怎么畫(huà)圖
怎么用echarts畫(huà)圖呢?其實(shí)官網(wǎng)上有很多實(shí)例,下面以bedroom.vue組件為例來(lái)簡(jiǎn)單說(shuō)明,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: ['學(xué)習(xí)氛圍差', '學(xué)習(xí)氛圍一般', '學(xué)習(xí)氛圍很好'],
opinionData: [
{value:26, name:'學(xué)習(xí)氛圍差'},
{value:31, name:'學(xué)習(xí)氛圍一般'},
{value:8, name:'學(xué)習(xí)氛圍很好'}
]
}
},
methods: {
drawPie (id) {
this.chart = echarts.init(document.getElementById(id))
this.chart.setOption({
title: {
text: '寢室學(xué)習(xí)氛圍情況調(diào)查',
left: 'center',
top: 10,
textStyle: {
fontSize: 24,
fontFamily: 'Helvetica',
fontWeight: 400
}
},
tooltip: {
trigger: 'item',
formatte: "{b}: {c} (blvhdc2%)"
},
toolbox: {
feature: {
saveAsImage: {},
dataView: {}
},
right: 15,
top: 10
},
legend: {
orient: 'vertical',
left: 5,
top: 10,
data: this.opinion,
},
series: [
{
name: '寢室學(xué)習(xí)氛圍',
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>
這是一個(gè)vue的單文件組件,script中,首先導(dǎo)入echarts庫(kù),前提是已經(jīng)安裝了echarts庫(kù),輸入以下命令安裝:
npm install --save echarts
data對(duì)象中是畫(huà)圖要用到的一些數(shù)據(jù),drawpie方法用來(lái)畫(huà)圖,接收一個(gè)DOM對(duì)象,然后在mounted構(gòu)子函數(shù)中調(diào)用drawpie即可。
兩點(diǎn)說(shuō)明
- drawpie方法接收的DOM對(duì)象需要有確定的寬高,否則圖像不顯示
- mounted中要包含vm.$nextTick才能保證該實(shí)例已經(jīng)插入文檔
實(shí)現(xiàn)登錄功能
登錄功能基于vuex(vue狀態(tài)管理)和瀏覽器的sessionStorage實(shí)現(xiàn)的。首先在src文件夾下新建store文件夾,存放vuex的store(倉(cāng)庫(kù)),新建三個(gè)文件store.js、login.js、user.js。login.js中存儲(chǔ)登錄狀態(tài),user.js中存儲(chǔ)用戶登錄信息,store.js加載login和user模塊。
注意:在store.js中要引入babel-polyfill(先安裝),否則會(huì)報(bào)錯(cuò),報(bào)錯(cuò)原因是Babel默認(rèn)只轉(zhuǎn)換新的JavaScript句法,而不轉(zhuǎn)換新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局對(duì)象,以及一些定義在全局對(duì)象上的方法都不會(huì)轉(zhuǎn)碼。所以必須使用babel-polyfill,為當(dāng)前環(huán)境提供一個(gè)墊片。
然后修改main.js文件,引入store:
import store from './store/store'
...
...
new Vue({
el: '#app',
template: '<App/>',
components: { App },
router,
store
})
修改App.vue文件,如下:
<template>
<div id="#app">
<!-- 導(dǎo)航欄 -->
<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預(yù)覽一下。
項(xiàng)目發(fā)布
項(xiàng)目可以在本地預(yù)覽了,但是要怎么發(fā)布到網(wǎng)上呢?首先,在命令行中輸入
npm run build
會(huì)生成一個(gè)dist文件夾,該文件夾中就是我們可以用來(lái)發(fā)布的代碼,直接將代碼上傳到你的服務(wù)器上就可以啦。