关键词
Vue Highcharts ElementUI
GitHub
思路
根据需求,一共需要三个页面,第一个页面是各种指标的列表,点击对应的指标转到第二个页面,展示相应指标的股票排行表格,点击表格的某一行跳转到第三个页面显示该股票的日K图。
在看了Element-ui的文档之后,看到el-dialog,觉得第三个页面可以直接从第二个页面弹出el-dialog实现,这样第二个页面就无需跳转可以一直展示。
创建project
用vue cli创建project
vue init webpack stockspec
PS D:\codes\vue\stockspec_vue> vue init webpack stockspec
? Project name stockspec
? Project description A Vue.js project
? Author mmdfish
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm
vue-cli · Generated "stockspec".
实现
- 引入Element-ui
// stockspec/src/main.js
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
- 引入Highcharts的highstock
// stockspec/src/main.js
import HighchartsVue from 'highcharts-vue'
import Highcharts from 'highcharts'
import stockInit from 'highcharts/modules/stock'
stockInit(Highcharts)
Vue.use(HighchartsVue)
- 页面设置
根据需求,创建两个页面,stockspec/src/component/stock.vue和stockspec/src/component/stockspec.vue。
加入路由,在stockspec/src/router/index.js中加入这两个页面的定义。
import stock from '@/components/stock'
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/stock',
name: 'Stock',
component: stock
},
{
path: '/stockspec',
name: 'StockSpec',
component: stockspec
},
]
})
- 指标列表入口
stockspec/src/component/stock.vue
用element-ui的layout 做最简单的布局,vue中一个template只能有一个组件,如果有多个组件会报错。解决方法是把这些el-row放在一个div中。stock里加入跳转stockspec的路由,用router-link做路由跳转,参数参考上一篇Django的request的参数。
这里一定要注意 router-link的用法,和path配对的是query,刷新页面数据不会丢失。和name配对的是params,刷新页面参数会丢失。具体看跳转时候现实的网址就能发现不同。
<template>
<div>
<el-row :gutter="10">
<el-col :span="4">贝塔系数(年)</el-col>
<el-col :span="4"><router-link :to="{ path: 'stockspec', query: {specname: 'beta_y', order:'asc', abs:true}}">最小</router-link></el-col>
<el-col :span="4"><router-link :to="{ path: 'stockspec', query: {specname: 'beta_y', order:'desc', abs:true}}">最大</router-link></el-col>
</el-row>
<el-row>
...
<el-row>
</div>
</template>
- 指标排行页面
stockspec/src/component/stockspec.vue
这个页面内容比较多,有些后续再写。
- 获取路由参数
getData() {
this.specname = this.$route.query.specname;
this.order = this.$route.query.order;
this.abs = false;
if(this.$route.query.abs) {
this.abs = this.$route.query.abs
}
}
- 从后端拿到数据
通过第一步拿到的路由参数,从Django后端获得json数据,就是response.data,这里用axios来从后端获取数据。第四篇里说到返回的json数据orient是table,那就用response.data.data获得其中的data部分。这里就不想细说了,多用console.log在chrome里debug就很容易看到。
import axios from "axios";
created() {
this.getData();
axios
.get("http://127.0.0.1:8000/stockserver/spec/", {
params: {
specname: this.specname,
order: this.order,
abs: this.abs
}
})
.then(response => {
this.stockSpecData = response.data.data;
});
}
- 用el-table展示数据
因为el-table里有很多细节的地方,后续会对el-table在本项目的用法详细介绍。el-table传入数据为 stockSpecData,就是从后端拿到的json数据。点击每一行调用row-click的displayDetails方法弹出dialog显示该股票的日K数据,点击每一行的name列打开新浪股票的对应股票页面可以看更多的数据。
<el-table :data="stockSpecData" :header-cell-style="{background:'#eef1f6',color:'#606266'}" :height="tableHeight" style="width: 100%" @row-click="displayDetails">
<el-table-column prop="code" label="代码" fixed :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="name" label="名字" fixed :show-overflow-tooltip="true">
<template slot-scope="scope">
<a :href="getLink(scope.row.code)" target="_blank" class="buttonText"><div style="font-size:16">{{scope.row.name}}</div></a>
</template>
</el-table-column>
<el-table-column
v-for="(item,key) in titleData"
:key="key"
:prop="item.value"
:label="item.name"
>
<template slot-scope="scope">
<span>{{getDisplayValueScope(scope)}}</span>
</template>
</el-table-column>
</el-table>
el-table的row-click调用的方法默认有row,column,event参数方便在方法里使用,具体内容可以用console.log打印出来看。displayDetails方法通过选择的股票代码去后端获取股票日K数据,然后把el-dialog的visible.sync设置为 true。
displayDetails(row, column, event) {
if(column.label == "名字") {
return
}
this.selectcode = row.code
this.selectname = row.name
axios
.get("http://127.0.0.1:8000/stockserver/dayk/", {
params: {
code: this.selectcode,
}
})
.then(response => {
this.dayk = response.data.data;
this.candleprops = {
'code':this.selectcode,
'name':this.selectname,
'kdata': this.dayk,
'reladay': this.selectreladayk,
};
this.dialogTableVisible = true
});
},
- 显示el-dialog
el-dialog 的visible.sync为true时,会弹出。在el-dialog里嵌入candlechart显示日K数据。candlechart调用的就是highcharts的highstock,后续再介绍。
customSize设置dialog相对于页面的比例大小。
另外两个el-dialog的style是给dialog加上滚动条。
<el-dialog :title="selectname + '(' + selectcode + ')'" :visible.sync="dialogTableVisible" custom-class="customSize">
<div v-if="dialogTableVisible"><candlechart :props1="candleprops"></candlechart></div>
</el-dialog>
<style>
.customSize{
width:70%;
height:70%;
}
//实现内部滚动条
.el-dialog {
display: flex;
flex-direction: column;
}
.el-dialog__body {
overflow: auto;
}
</style>
- 其他
stockspec/src/component/common.vue
一些通用的方法和常量,包括中英文的Dictionary spec_dict,显示数据的精度getDisplayValueScope和getDisplayValue,用export default导出
<script type="text/javascript">
const spec_dict = ...
function getDisplayValueScope(scope) {
var name = scope.column.property
var value = scope.row[scope.column.property]
return getDisplayValue(name,value)
}
function getDisplayValue(name,value) {
...
}
export default {
spec_dict,
getDisplayValueScope,
getDisplayValue
}
</script>
在其他vue中调用
import common from './common.vue'
common.getDisplayValue(name,value)
let specdict = common.spec_dict
关于el-table和highcharts在本项目的应用,后续会再写。
运行
如果前两个python项目都正常运行的话,从github clone之后应该是能直接看到运行效果的。
cd stockspec
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev